const assert = require("node:assert/strict"); const { chmodSync, mkdtempSync, readFileSync, rmSync, writeFileSync, } = require("node:fs"); const { tmpdir } = require("node:os"); const nodePath = require("node:path"); const { test } = require("node:test"); const EXECUTABLE_MODE = 0o755; const { spawnSync } = require("node:child_process"); test("immutable publication resumes exact digest checks after post-push failure", () => { const directory = mkdtempSync(nodePath.join(tmpdir(), "wl-image-retry-")); const workflow = readFileSync( nodePath.resolve(__dirname, "../.gitea/workflows/image.yml"), "utf8", ); const block = workflow .split(" - name: Publish immutable release tag\n run: |\n", 2)[1] .split(" - name:", 1)[0] .replaceAll(/^ {10}/gm, ""); const double = String.raw`#!${process.execPath} const fs = require('node:fs'); const args = process.argv.slice(2).join(' '); fs.appendFileSync('calls', args + '\n'); if (args.startsWith('manifest inspect')) { if (!fs.existsSync('published')) { console.error('manifest unknown'); process.exit(1); } } else if (args.startsWith('buildx imagetools inspect')) { console.log('sha256:exact'); } else if (args.startsWith('buildx build')) { fs.writeFileSync('published', 'yes'); fs.writeFileSync('image-metadata.json', JSON.stringify({'containerimage.digest': 'sha256:exact'})); } else if (args.startsWith('pull')) { if (!fs.existsSync('pull-failed')) { fs.writeFileSync('pull-failed', 'yes'); process.exit(1); } } else if (args.startsWith('image inspect')) { console.log(args.includes('image.version') ? '1.2.3' : process.env.BAD_REVISION ? 'other' : 'commit'); } else if (args.startsWith('run') && process.env.BAD_SMOKE) process.exit(1); `; try { for (const name of ["docker", "npm"]) { // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames. writeFileSync(nodePath.join(directory, name), double); // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames. chmodSync(nodePath.join(directory, name), EXECUTABLE_MODE); } const run = (extra = {}) => spawnSync("/bin/sh", ["-ec", block], { cwd: directory, encoding: "utf8", env: { ...process.env, IMAGE: "synthetic/image", PATH: `${directory}:${process.env.PATH}`, RELEASE_TAG: "v1.2.3", REVISION: "commit", ...extra, }, }); assert.notEqual(run().status, 0); const retry = run(); assert.equal(retry.status, 0, retry.stdout + retry.stderr); assert.notEqual(run({ BAD_REVISION: "1" }).status, 0); assert.notEqual(run({ BAD_SMOKE: "1" }).status, 0); // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames. const calls = readFileSync(nodePath.join(directory, "calls"), "utf8"); assert.equal( calls.split("\n").filter(line => line.startsWith("buildx build")) .length, 1, ); assert.ok(calls.includes("synthetic/image@sha256:exact")); } finally { rmSync(directory, { force: true, recursive: true }); } });