start-command 0.39.1 → 0.40.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/CHANGELOG.md +20 -0
- package/README.md +2 -1
- package/eslint.config.mjs +1 -0
- package/package.json +9 -9
- package/src/bin/cli.js +7 -5
- package/src/lib/command-stream.js +19 -5
- package/src/lib/execution-chain.js +2 -2
- package/src/lib/execution-store.js +62 -44
- package/src/lib/failure-handler.js +12 -6
- package/src/lib/log-sanitizer.js +191 -229
- package/src/lib/log-uploader.js +6 -3
- package/test/ci-workflow-invariants.js +18 -0
- package/test/command-stream-log.js +85 -0
- package/test/dependency-freshness.mjs +552 -0
- package/test/execution-store-clink.js +152 -0
- package/test/execution-store.js +49 -5
- package/test/fixtures/executions-lino-objects-codec-0.4.0.lino +1 -0
- package/test/fixtures/executions-lino-objects-codec-0.9.3.lino +26 -0
- package/test/javascript-first-ci.js +29 -0
- package/test/log-sanitizer.js +387 -151
- package/test/regression-187.js +4 -0
- package/test/regression-224.js +4 -2
- package/test/regression-231.js +20 -0
- package/test/release-git.mjs +2 -1
package/test/regression-187.js
CHANGED
|
@@ -78,6 +78,8 @@ function fixture() {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
const stopped = () => ({ alive: false, state: SessionState.STOPPED });
|
|
81
|
+
// The snapshot preflight must not depend on the free disk of the test host.
|
|
82
|
+
const plentyOfDisk = { freeBytes: () => 100 * 1024 ** 3 };
|
|
81
83
|
const accepted = (_bin, args = []) => ({
|
|
82
84
|
success: true,
|
|
83
85
|
stdout: args.includes('--size')
|
|
@@ -102,6 +104,7 @@ describe('issue #187: explicit resume attempts', () => {
|
|
|
102
104
|
? () => ({ alive: false, state: SessionState.MISSING })
|
|
103
105
|
: stopped,
|
|
104
106
|
runner: accepted,
|
|
107
|
+
snapshotOptions: plentyOfDisk,
|
|
105
108
|
runIsolated: () => ({ success: true, containerId: 'new-container' }),
|
|
106
109
|
startWatcher: (_name, _policy, _log, _uuid, options) => {
|
|
107
110
|
expect(options.recoverOnKill).toBe(mode !== 'docker-snapshot');
|
|
@@ -357,6 +360,7 @@ esac
|
|
|
357
360
|
command: 'replacement',
|
|
358
361
|
probe: stopped,
|
|
359
362
|
runner: accepted,
|
|
363
|
+
snapshotOptions: plentyOfDisk,
|
|
360
364
|
startWatcher: () => {},
|
|
361
365
|
});
|
|
362
366
|
expect(result.success).toBe(true);
|
package/test/regression-224.js
CHANGED
|
@@ -59,6 +59,8 @@ afterEach(() => {
|
|
|
59
59
|
const SAFETY = require.resolve('../src/lib/docker-snapshot-safety');
|
|
60
60
|
|
|
61
61
|
/** Hold the snapshot lock in another process for `holdMs`. */
|
|
62
|
+
// A waiter polls for 1 s before it reads the holder's name, so tests that
|
|
63
|
+
// expect the name hold the lock well past that, even on a slow runner.
|
|
62
64
|
async function holdLockElsewhere(lockPath, holder, holdMs) {
|
|
63
65
|
const ready = `${lockPath}.ready`;
|
|
64
66
|
const child = spawn(
|
|
@@ -264,7 +266,7 @@ describe('issue #224 item 1: waiting for the snapshot lock', () => {
|
|
|
264
266
|
|
|
265
267
|
it('waits for the holder with --snapshot-wait and says so once', async () => {
|
|
266
268
|
const lockPath = path.join(makeTempDir('lock-224-'), 'snapshot.lock');
|
|
267
|
-
await holdLockElsewhere(lockPath, 'task-a',
|
|
269
|
+
await holdLockElsewhere(lockPath, 'task-a', 3000);
|
|
268
270
|
const lines = [];
|
|
269
271
|
const started = Date.now();
|
|
270
272
|
const lock = acquireSnapshotLock({
|
|
@@ -307,7 +309,7 @@ describe('issue #224 item 1: waiting for the snapshot lock', () => {
|
|
|
307
309
|
|
|
308
310
|
it('serializes two concurrent CLI resumes instead of failing the second', async () => {
|
|
309
311
|
const lockPath = path.join(makeTempDir('lock-224-'), 'snapshot.lock');
|
|
310
|
-
await holdLockElsewhere(lockPath, 'task-a',
|
|
312
|
+
await holdLockElsewhere(lockPath, 'task-a', 3000);
|
|
311
313
|
const { store } = snapshotRecord();
|
|
312
314
|
const calls = [];
|
|
313
315
|
const lines = [];
|
package/test/regression-231.js
CHANGED
|
@@ -12,6 +12,7 @@ const { parseArgs } = require('../src/lib/args-parser');
|
|
|
12
12
|
const {
|
|
13
13
|
ExecutionStore,
|
|
14
14
|
ExecutionRecord,
|
|
15
|
+
isClinkInstalled,
|
|
15
16
|
} = require('../src/lib/execution-store');
|
|
16
17
|
const {
|
|
17
18
|
executionAliases,
|
|
@@ -126,6 +127,25 @@ describe('issue #231: execution names', () => {
|
|
|
126
127
|
]);
|
|
127
128
|
});
|
|
128
129
|
|
|
130
|
+
// Issue #253: the rename used to reach only the lino store; clink 4.x
|
|
131
|
+
// rejected every links query the store built.
|
|
132
|
+
it.skipIf(!isClinkInstalled())(
|
|
133
|
+
'--rename reaches the links database',
|
|
134
|
+
() => {
|
|
135
|
+
const { store } = sandbox();
|
|
136
|
+
store.save(record(A, { sessionName: 'screen-a' }));
|
|
137
|
+
nameExecution(store, A, 'first', { rename: true });
|
|
138
|
+
const links = store.execClink('((($id: $s $t)) (($id: $s $t)))', [
|
|
139
|
+
'--changes',
|
|
140
|
+
]).output;
|
|
141
|
+
expect(links).toContain(
|
|
142
|
+
`${A}.options: ${A} 'options={"sessionName":"screen-a","name":"first"}'`
|
|
143
|
+
);
|
|
144
|
+
expect(store.verifyConsistency().errors).toEqual([]);
|
|
145
|
+
},
|
|
146
|
+
30000
|
|
147
|
+
);
|
|
148
|
+
|
|
129
149
|
it('a UUID-shaped alias resolves like any other name', () => {
|
|
130
150
|
const { store } = sandbox();
|
|
131
151
|
store.save(record(A));
|
package/test/release-git.mjs
CHANGED
|
@@ -87,7 +87,8 @@ describe('release-git (#211)', () => {
|
|
|
87
87
|
await withRepo({ reject: true }, async () => {
|
|
88
88
|
const result = await $`git push origin main`.run(quiet);
|
|
89
89
|
expect(result.code).not.toBe(0);
|
|
90
|
-
|
|
90
|
+
// command-stream 2.x returns stderr as a readable snapshot (#253).
|
|
91
|
+
expect(String(result.stderr)).toContain('GH013');
|
|
91
92
|
});
|
|
92
93
|
});
|
|
93
94
|
|