Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
59 linesWorking out who changed each lineCodeBlameRaw
1import { test } from "node:test";
2import assert from "node:assert/strict";
3import { npmCi, retryable } from "./npm-ci.mjs";
4
5const quiet = () => {};
6const noSleep = async () => {};
7
8/** A fake npm that answers each try in turn. */
9function tries(...answers) {
10 const seen = [];
11 const run = async (args) => {
12 seen.push(args);
13 return { stalled: false, output: "", ...answers[seen.length - 1] };
14 };
15 return { seen, run };
16}
17
18test("a body that broke off is worth another try, a lockfile out of step is not", () => {
19 assert.equal(retryable("npm error code ECONNRESET\nnpm error network aborted"), true);
20 assert.equal(retryable("npm error request to https://registry.npmjs.org/x failed, reason: socket hang up"), true);
21 assert.equal(retryable("npm error code EAI_AGAIN"), true);
22 assert.equal(retryable("npm error `npm ci` can only install packages when your package.json and package-lock.json are in sync"), false);
23 assert.equal(retryable("npm error code E404"), false);
24});
25
26test("an install that ends without saying why, or stalls, is tried again", () => {
27 assert.equal(retryable(""), true);
28 assert.equal(retryable("added 12 packages"), true);
29 assert.equal(retryable("npm error code E404", { stalled: true }), true);
30});
31
32test("a dropped connection is tried again until the install passes", async () => {
33 const waits = [];
34 const { seen, run } = tries({ code: 1, output: "npm error code ECONNRESET" }, { code: 0 });
35 const code = await npmCi(["--prefer-offline", "--no-audit"], { run, sleep: async (ms) => waits.push(ms), waits: [5, 15], log: quiet });
36 assert.equal(code, 0);
37 assert.equal(seen.length, 2);
38 assert.deepEqual(seen[1], ["ci", "--prefer-offline", "--no-audit"]);
39 assert.deepEqual(waits, [5]);
40});
41
42test("a real error fails at once", async () => {
43 const { seen, run } = tries({ code: 1, output: "npm error code ERESOLVE" });
44 assert.equal(await npmCi([], { run, sleep: noSleep, log: quiet }), 1);
45 assert.equal(seen.length, 1);
46});
47
48test("it gives up after its tries, with npm's exit code", async () => {
49 const reset = { code: 7, output: "npm error network aborted" };
50 const { seen, run } = tries(reset, reset, reset, reset);
51 assert.equal(await npmCi([], { run, sleep: noSleep, attempts: 3, log: quiet }), 7);
52 assert.equal(seen.length, 3);
53});
54
55test("a stalled install is run again", async () => {
56 const { seen, run } = tries({ code: 1, stalled: true }, { code: 0 });
57 assert.equal(await npmCi([], { run, sleep: noSleep, log: quiet }), 0);
58 assert.equal(seen.length, 2);
59});