MCPcopy Index your code
hub / github.com/ether/etherpad / performCheck

Function performCheck

src/node/updater/index.ts:113–219  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

111};
112
113const performCheck = async (): Promise<void> => {
114 if (settings.updates.tier === 'off') return;
115 // Coalesce overlapping ticks. performCheck mutates shared in-memory state and writes
116 // it to disk; concurrent runs would race on saveState() and could double-send emails.
117 if (checkInFlight) return;
118 checkInFlight = true;
119 try {
120 // getCurrentState() can throw on a non-ENOENT fs error from loadState();
121 // it must run inside the try/finally so checkInFlight is always cleared,
122 // otherwise a one-time permission error permanently disables polling.
123 const state = await getCurrentState();
124 const result = await checkLatestRelease({
125 fetcher: realFetcher,
126 prevEtag: state.lastEtag,
127 repo: settings.updates.githubRepo,
128 });
129 const now = new Date();
130 state.lastCheckAt = now.toISOString();
131
132 if (result.kind === 'updated') {
133 state.latest = result.release;
134 state.lastEtag = result.etag;
135 } else if (result.kind === 'skipped-prerelease') {
136 // Preserve ETag so we don't re-fetch an unchanged prerelease body next tick.
137 state.lastEtag = result.etag;
138 } else if (result.kind === 'notmodified') {
139 // 304 — no state change.
140 } else if (result.kind === 'ratelimited') {
141 logger.warn('GitHub rate-limited; will retry at next interval');
142 } else if (result.kind === 'error') {
143 logger.warn(`GitHub fetch error status=${result.status}`);
144 }
145
146 // Notifier pass: only when we have a known latest, an admin email, and the policy allows notify.
147 if (state.latest && settings.adminEmail) {
148 const current = getEpVersion();
149 const policy = evaluatePolicy({
150 installMethod: detectedMethod,
151 tier: settings.updates.tier,
152 current,
153 latest: state.latest.version,
154 maintenanceWindow: settings.updates.maintenanceWindow,
155 });
156 if (policy.canNotify) {
157 const decision = decideEmails({
158 adminEmail: settings.adminEmail,
159 current,
160 latest: state.latest.version,
161 latestTag: state.latest.tag,
162 isSevere: isMinorOrMoreBehind(current, state.latest.version),
163 state: state.email,
164 now,
165 });
166 for (const email of decision.toSend) {
167 await sendEmailViaSmtp(settings.adminEmail, email.subject, email.body);
168 }
169 state.email = decision.newState;
170 }

Callers 1

startPollingFunction · 0.70

Calls 11

checkLatestReleaseFunction · 0.90
getEpVersionFunction · 0.90
evaluatePolicyFunction · 0.90
decideEmailsFunction · 0.90
isMinorOrMoreBehindFunction · 0.90
decideScheduleFunction · 0.90
parseWindowFunction · 0.90
saveStateFunction · 0.90
getCurrentStateFunction · 0.85
sendEmailViaSmtpFunction · 0.85
stateFilePathFunction · 0.85

Tested by

no test coverage detected