fix(ci): gate images behind verified Testcontainers
Verify / verify (push) Successful in 8m52s

This commit is contained in:
sechmachine
2026-08-15 23:21:23 +07:00
parent 7a6139017f
commit d13443e338
7 changed files with 233 additions and 30 deletions
+31 -1
View File
@@ -6,6 +6,14 @@ import test from "node:test";
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
const read = (path) => readFileSync(resolve(root, path), "utf8");
const expectedActionPins = new Map([
["actions/checkout", "3d3c42e5aac5ba805825da76410c181273ba90b1"],
["actions/setup-java", "b6effb05e454b25005698d916606bdc6ffcbf961"],
["actions/setup-node", "820762786026740c76f36085b0efc47a31fe5020"],
["docker/setup-buildx-action", "bb05f3f5519dd87d3ba754cc423b652a5edd6d2c"],
["docker/login-action", "dbcb813823bdd20940b903addbd779551569679f"],
["docker/build-push-action", "53b7df96c91f9c12dcc8a07bcb9ccacbed38856a"],
]);
test("production image and Compose keep one image usable with bundled or external PostgreSQL", () => {
const dockerfile = read("Dockerfile");
@@ -37,12 +45,19 @@ test("verification workflow checks every pull request and pushed branch without
assert.match(workflow, /npm run test:ui/);
assert.match(workflow, /npm run build/);
assert.match(workflow, /\.\/mvnw -B test/);
assert.match(workflow, /TESTCONTAINERS_HOST_OVERRIDE: host\.docker\.internal/);
assert.doesNotMatch(workflow, /permissions:\s*write-all/);
});
test("container workflow publishes only main and makes native ARM64 explicitly optional", () => {
test("container workflow runs only manually or on main and verifies before either image build", () => {
const workflow = read(".gitea/workflows/container.yml");
assert.match(workflow, /'on':\n workflow_dispatch:\n push:\n branches:\n - main/);
assert.doesNotMatch(workflow, /^ pull_request:/m);
assert.match(workflow, /jobs:\n verify:/);
assert.match(workflow, /amd64:\n needs: verify/);
assert.match(workflow, /arm64:[\s\S]*?needs: verify/);
assert.match(workflow, /TESTCONTAINERS_HOST_OVERRIDE: host\.docker\.internal/);
assert.match(workflow, /runs-on: ubuntu-latest-arm/);
assert.match(workflow, /vars\.ARM64_RUNNER_AVAILABLE == 'true'/);
assert.match(workflow, /gitea\.ref == 'refs\/heads\/main'/);
@@ -51,3 +66,18 @@ test("container workflow publishes only main and makes native ARM64 explicitly o
assert.match(workflow, /imagetools create/);
assert.doesNotMatch(workflow, /ssh|DEPLOY_HOST|DEPLOY_KEY/i);
});
test("workflows pin every action to the latest reviewed immutable release", () => {
const workflows = [
read(".gitea/workflows/verify.yml"),
read(".gitea/workflows/container.yml"),
].join("\n");
const uses = [...workflows.matchAll(/uses:\s+([^@\s]+)@([0-9a-f]{40})/g)];
assert.ok(uses.length > 0);
for (const [, action, pin] of uses) {
assert.equal(pin, expectedActionPins.get(action), `unexpected pin for ${action}`);
}
assert.deepEqual(new Set(uses.map(([, action]) => action)), new Set(expectedActionPins.keys()));
assert.doesNotMatch(workflows, /uses:\s+[^\s]+@v\d/);
});