@steve31415/baselib 3.30.0 → 3.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/deploy/rollback.js +26 -1
- package/dist/deploy/types.d.ts +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,7 +29,9 @@ ERROR log (`~/plasticine-way/docs/SECURITY.md`, "Resend API key").
|
|
|
29
29
|
|
|
30
30
|
Bins: `check-test-owners` — the fleet's structural test-coverage gate; every
|
|
31
31
|
app runs it from `npm run verify`. `pw-deploy` / `pw-rollback` — the fleet
|
|
32
|
-
deploy (`~/plasticine-way/docs/OPERATIONS.md`, "Deployment safety")
|
|
32
|
+
deploy (`~/plasticine-way/docs/OPERATIONS.md`, "Deployment safety"); an
|
|
33
|
+
app's hooks module (`DeployHooks` in `src/deploy/types.ts`) extends both,
|
|
34
|
+
`postRollback` being the one hook `pw-rollback` runs.
|
|
33
35
|
`pw-sql` / `pw-logs` — read-only production queries (database, Axiom), the
|
|
34
36
|
first step of any production investigation (same doc, "Investigating
|
|
35
37
|
production state").
|
package/dist/deploy/rollback.js
CHANGED
|
@@ -7,7 +7,7 @@ import { hostname } from 'node:os';
|
|
|
7
7
|
import { must, mustJson } from './exec.js';
|
|
8
8
|
import { openEvidence, PhaseTimer } from './evidence.js';
|
|
9
9
|
import { acquireLock, listReleaseRecords, placeHold, releaseLock } from './gcs.js';
|
|
10
|
-
import { DEFAULT_ACCOUNT, loadConfig } from './config.js';
|
|
10
|
+
import { DEFAULT_ACCOUNT, loadConfig, loadHooks } from './config.js';
|
|
11
11
|
import { pickRevisionForSha, releaseEntriesFrom, selectRollbackTarget, readServingState, SHA40, } from './plan.js';
|
|
12
12
|
export async function runRollback(options) {
|
|
13
13
|
const log = options.log ?? ((m) => console.error(`[pw-rollback] ${m}`));
|
|
@@ -19,6 +19,7 @@ export async function runRollback(options) {
|
|
|
19
19
|
const requested = argv.find((a) => SHA40.test(a));
|
|
20
20
|
const timer = new PhaseTimer(log);
|
|
21
21
|
let evidenceDir = '';
|
|
22
|
+
let rolledBackTo = '';
|
|
22
23
|
let lock = null;
|
|
23
24
|
try {
|
|
24
25
|
const config = await loadConfig(options.repoRoot);
|
|
@@ -151,6 +152,26 @@ export async function runRollback(options) {
|
|
|
151
152
|
throw new Error(`${service.name}: post-rollback smoke failed (${lastDetail})`);
|
|
152
153
|
log(`${service.name}: smoke passed`);
|
|
153
154
|
}
|
|
155
|
+
// The hooks module is loaded only now: a broken one must not stand
|
|
156
|
+
// between an incident and the traffic move.
|
|
157
|
+
timer.enter('hooks');
|
|
158
|
+
rolledBackTo = target;
|
|
159
|
+
const hooks = await loadHooks(options.repoRoot, config);
|
|
160
|
+
if (hooks.postRollback) {
|
|
161
|
+
const ctx = {
|
|
162
|
+
sha: target,
|
|
163
|
+
baseSha: servingShas.length === 1 ? servingShas[0] : null,
|
|
164
|
+
config,
|
|
165
|
+
repoRoot: options.repoRoot,
|
|
166
|
+
contextDir: '',
|
|
167
|
+
evidenceDir,
|
|
168
|
+
imageDigest: targets[0].imageDigest,
|
|
169
|
+
serving,
|
|
170
|
+
exec: runner,
|
|
171
|
+
log,
|
|
172
|
+
};
|
|
173
|
+
await hooks.postRollback(ctx);
|
|
174
|
+
}
|
|
154
175
|
timer.close();
|
|
155
176
|
log(`rolled back to ${target.slice(0, 12)}`);
|
|
156
177
|
log(`hold placed on ${servingShas.map((sha) => sha.slice(0, 12)).join(', ')} — ` +
|
|
@@ -162,6 +183,10 @@ export async function runRollback(options) {
|
|
|
162
183
|
const message = error instanceof Error ? error.message : String(error);
|
|
163
184
|
console.error(message);
|
|
164
185
|
console.error(`rollback failed in phase: ${timer.current}`);
|
|
186
|
+
if (rolledBackTo) {
|
|
187
|
+
console.error(`traffic IS on ${rolledBackTo.slice(0, 12)} and the hold is placed; only the app's ` +
|
|
188
|
+
'postRollback hook failed — finish what it does by hand');
|
|
189
|
+
}
|
|
165
190
|
if (evidenceDir)
|
|
166
191
|
console.error(`evidence: ${evidenceDir}`);
|
|
167
192
|
return 1;
|
package/dist/deploy/types.d.ts
CHANGED
|
@@ -120,4 +120,11 @@ export interface DeployHooks {
|
|
|
120
120
|
smoke?: (ctx: HookContext) => Promise<void>;
|
|
121
121
|
/** Runs after everything else succeeded (e.g. notes's release state). */
|
|
122
122
|
postSuccess?: (ctx: HookContext) => Promise<void>;
|
|
123
|
+
/** pw-rollback only: runs after traffic is back on the target build, the
|
|
124
|
+
* hold is placed and the smoke passed — for what a traffic move does not
|
|
125
|
+
* carry (e.g. podcasts' render Job image). `sha` and `imageDigest` are the
|
|
126
|
+
* rollback target's, `serving` is the state rolled back from, and
|
|
127
|
+
* `contextDir` is empty (nothing is built). A throw fails the command but
|
|
128
|
+
* undoes nothing. */
|
|
129
|
+
postRollback?: (ctx: HookContext) => Promise<void>;
|
|
123
130
|
}
|
package/package.json
CHANGED