diff --git a/cmd/ingestor/stats_file_test.go b/cmd/ingestor/stats_file_test.go index e96d56bd..59d59f0b 100644 --- a/cmd/ingestor/stats_file_test.go +++ b/cmd/ingestor/stats_file_test.go @@ -2,8 +2,11 @@ package main import ( "encoding/json" + "errors" "os" "path/filepath" + "runtime" + "syscall" "testing" "time" ) @@ -129,6 +132,9 @@ func TestWriteStatsAtomic_SymlinkAtDestIsReplaced(t *testing.T) { // Pre-plant a symlink at the destination path. path := filepath.Join(dir, "stats.json") if err := os.Symlink(target, path); err != nil { + if runtime.GOOS == "windows" && errors.Is(err, syscall.Errno(1314)) { + t.Skip("Windows account cannot create symlinks; this security fixture must run on Linux CI") + } t.Fatalf("symlink: %v", err) } diff --git a/cmd/server/config_mode_test.go b/cmd/server/config_mode_test.go index 601ef765..0abb6bfc 100644 --- a/cmd/server/config_mode_test.go +++ b/cmd/server/config_mode_test.go @@ -3,6 +3,7 @@ package main import ( "os" "path/filepath" + "runtime" "testing" ) @@ -10,6 +11,9 @@ import ( // API key and broker passwords, so the rewrite must keep whatever mode the // operator set rather than resetting it to 0644. func TestSaveGeoFilterPreservesFileMode(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Windows does not support POSIX file permission bits") + } dir := t.TempDir() path := filepath.Join(dir, "config.json") if err := os.WriteFile(path, []byte(`{"apiKey":"secret-key-that-is-long-enough"}`+"\n"), 0600); err != nil { diff --git a/tests/unit/test-issue-1956-release-routing.js b/tests/unit/test-issue-1956-release-routing.js index 89ee1738..bb520ee6 100644 --- a/tests/unit/test-issue-1956-release-routing.js +++ b/tests/unit/test-issue-1956-release-routing.js @@ -57,6 +57,8 @@ function runSteps(source, context, edge, mutateFails = false) { const log = path.join(dir, 'commands'); fs.writeFileSync(log, ''); fs.mkdirSync(path.join(dir, 'cmd/decrypt'), { recursive: true }); + fs.mkdirSync(path.join(dir, 'docs/release-notes'), { recursive: true }); + fs.writeFileSync(path.join(dir, 'docs/release-notes/v9.8.7.md'), 'Fixture release notes\n'); // go() only logs, so nothing real is produced; the release job's own // static/runnable verification step still needs these to exist. for (const arch of ['amd64', 'arm64']) { @@ -131,6 +133,7 @@ function runSteps(source, context, edge, mutateFails = false) { input: stubs + '\n' + expand(script, context), cwd: dir, encoding: 'utf8', timeout: 15000, env: { ...process.env, GITHUB_REF: context.github.ref, GITHUB_SHA: context.github.sha, + GITHUB_REF_NAME: context.github.ref_name, GITHUB_OUTPUT: bashPath(output), COMMAND_LOG: bashPath(log), TMPDIR: bashPath(dir), EDGE_CONFIG: edge === null ? 'missing' : JSON.stringify({ config: { Labels: { 'org.opencontainers.image.revision': edge } } }), // :edge is a two-platform index plus the two buildx attestation @@ -285,6 +288,22 @@ assert.equal(value(dispatchInput, 'type', 8), 'boolean', 'dispatch flag must ret assert.equal(value(dispatchInput, 'default', 8), 'false', 'manual and fallback dispatches must build images by default'); const release = block(deploy, 'release-artifacts', 2); +const notesStep = steps(release).find(step => value(step, 'id', 8) === 'notes'); +const inheritedRefName = process.env.GITHUB_REF_NAME; +try { + for (const hostRef of [undefined, 'unrelated-runner-branch']) { + if (hostRef === undefined) delete process.env.GITHUB_REF_NAME; + else process.env.GITHUB_REF_NAME = hostRef; + for (const [tag, expectedPath] of [['v9.8.7', 'docs/release-notes/v9.8.7.md'], ['v9.8.8', '']]) { + const ctx = context(`refs/tags/${tag}`); + runSteps(`steps:\n${notesStep}`, ctx, null); + assert.equal(ctx.steps.notes.outputs.path, expectedPath, 'release notes must use the simulated tag, independent of the host environment'); + } + } +} finally { + if (inheritedRefName === undefined) delete process.env.GITHUB_REF_NAME; + else process.env.GITHUB_REF_NAME = inheritedRefName; +} const builds = runSteps(release, context(), null).commands.filter(command => command[0] === 'go'); // CGO_ENABLED=1 since the SQLite driver became github.com/mattn/go-sqlite3, and // CC must be zig targeting musl — that is what makes the artifact static and