Files
windmill/cli/test/item_digest_unit.test.ts
4beb1f9420 feat: add trigger, tag, run-as and digest claims to job OIDC tokens (#11481)
* feat: add trigger, tag, run-as and digest claims to job OIDC tokens

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: parse digest floats exactly and derive the codebase digest like push

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: give flows that reference flow nodes no digest and keep --json clean

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: list flow step digests from module positions only

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: skip the pulled module-script digest check on windows

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: update ee-repo-ref to 71b8c1042fd8188c2d2882476f12b671cb5ba421

This commit updates the EE repository reference after PR #840 was merged in windmill-ee-private.

Previous ee-repo-ref: ba1870536789a43c5b6ec18522a93edb9cb07f3d

New ee-repo-ref: 71b8c1042fd8188c2d2882476f12b671cb5ba421

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-10-02 19:02:17 +02:00

89 lines
2.7 KiB
TypeScript

import { afterAll, beforeAll, expect, test } from "bun:test";
import JSZip from "jszip";
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import {
readDirRecursiveWithIgnore,
ZipFSElement,
} from "../src/commands/sync/sync.ts";
import { itemDigest } from "../src/commands/digest/digest.ts";
import vectors from "./fixtures/item_digest_vectors.json";
// The server hashes the same vectors in backend/tests/job_provenance.rs, so a checkout
// `wmill sync pull` writes for them must digest to the values the job OIDC claims carry.
const originalCwd = process.cwd();
beforeAll(() => {
process.chdir(mkdtempSync(join(tmpdir(), "wmill-digest-")));
});
afterAll(() => {
process.chdir(originalCwd);
});
/** The workspace export of the vectors, as `GET .../workspaces/tarball` writes it. */
function exportZip(): JSZip {
const zip = new JSZip();
const file = (path: string, content: string) =>
zip.file(path, content, { createFolders: false });
const { script, flow } = vectors;
file(`${script.path}.ts`, script.content);
file(
`${script.path}.script.json`,
JSON.stringify({
summary: "",
description: "",
schema: {},
lock: script.lock,
kind: "script",
modules: script.modules,
})
);
file(
`${flow.path}.flow.json`,
JSON.stringify({ summary: "", description: "", value: flow.value, schema: {} })
);
return zip;
}
async function writeTree(el: any) {
for await (const e of readDirRecursiveWithIgnore(() => false, el)) {
if (!e.isDirectory) {
mkdirSync(dirname(e.path), { recursive: true });
writeFileSync(e.path, await e.getContentText());
}
}
}
beforeAll(async () => {
await writeTree(ZipFSElement(exportZip(), true, "bun", {}, {}, false, true));
});
// On Windows the pull leaves a multi-file script's entry point outside its `__mod/` folder
// (`ZipFSElement` matches module bases against `/`-separated zip names), a layout neither
// push nor this command reads back.
test.skipIf(process.platform === "win32")(
"a pulled script digests to the server's digest",
async () => {
const script = await itemDigest("f/digest/script__mod/script.ts", "bun");
expect(script).toEqual({
path: vectors.script.path,
kind: "script",
digest: vectors.script.digest,
});
expect(
(await itemDigest("f/digest/script__mod/script.yaml", "bun")).digest
).toBe(vectors.script.digest);
}
);
test("a pulled flow digests to the server's digests", async () => {
const flow = await itemDigest(join("f", "digest", "flow.flow"), "bun");
expect(flow).toEqual({
path: vectors.flow.path,
kind: "flow",
digest: vectors.flow.digest,
steps: vectors.flow.steps,
});
});