File size: 2,871 Bytes
31b3c47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..");
// Normalize line endings: a Windows checkout with core.autocrlf=true has CRLF,
// and the line-anchored patterns below must mean the same thing everywhere.
const WORKFLOW = readFileSync(join(ROOT, ".github/workflows/hf-deploy.yml"), "utf8").replace(
  /\r\n/g,
  "\n",
);

function eventBlock(name) {
  const match = WORKFLOW.match(
    new RegExp(String.raw`\n  ${name}:\n([\s\S]*?)(?=\n  [A-Za-z_][A-Za-z0-9_-]*:|\npermissions:)`),
  );
  assert.ok(match, `missing ${name} event block`);
  return match[1];
}

// Since 617fb49 ("delegate Nexus publication and bind live source") provider
// writes for SZLHOLDINGS/nexus belong to szl-holdings/.github
// publish-nexus-space.yml. This workflow is a no-secret ownership guard, so it
// must never regain a publisher. The Docker closure includes source directories,
// so every main/PR/merge-group source change must validate the same boundary.

test("the guard never publishes: provider writes stay with the central publisher", () => {
  assert.match(WORKFLOW, /publish-nexus-space\.yml/);
  for (const fragment of [
    "secrets.HF_",
    "reusable-hf-deploy.yml",
    "upload_file(",
    "create_repo(",
    "restart_space(",
  ]) {
    // The guard's own forbidden-list spells these split ('secrets.' + 'HF_').
    assert.ok(!WORKFLOW.includes(fragment), `local provider writer reintroduced: ${fragment}`);
  }
  assert.match(WORKFLOW, /^permissions:\n {2}contents: read$/m);
  assert.doesNotMatch(WORKFLOW, /:\s*write\b/);
});

test("main pushes and pull requests validate every source change", () => {
  const push = eventBlock("push");
  const pullRequest = eventBlock("pull_request");
  assert.match(push, /^ {4}branches: \[main\]$/m);
  assert.match(pullRequest, /^ {4}branches: \[main\]$/m);
  assert.doesNotMatch(push, /^ {4}paths:/m);
  assert.doesNotMatch(pullRequest, /^ {4}paths:/m);
  assert.match(WORKFLOW, /^ {2}merge_group: \{\}$/m);
});

test("the guard checks out and proves the exact event source", () => {
  assert.ok(
    WORKFLOW.includes(
      "env:\n  SOURCE_REVISION: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }}",
    ),
  );
  assert.match(WORKFLOW, /ref: \$\{\{ env\.SOURCE_REVISION \}\}/);
  assert.match(WORKFLOW, /test "\$\(git rev-parse HEAD\)" = "\$SOURCE_REVISION"/);
});

test("every action is pinned to a full commit SHA", () => {
  const uses = [...WORKFLOW.matchAll(/^\s*uses:\s*(\S+)/gm)].map((match) => match[1]);
  assert.ok(uses.length > 0);
  for (const value of uses) {
    assert.match(value, /^[^@\s]+@[0-9a-f]{40}$/, `unpinned action: ${value}`);
  }
});