V3 - #114
Open
janderssonse wants to merge 56 commits into
Open
Conversation
Adds the typed Go domain layer under internal/domain: artifacts.yml schema (config), release planning (pipeline, release), build / ecosystem types (build, projecttype), security report shapes (sbom, security, validate), provider/CI abstractions (provider, ci, errs, output). Also lands internal/platform for runtime detection and internal/testutil for the fakes the upper layers will use. Signed-off-by: Josef Andersson <josef.andersson@digg.se>
Adds internal/adapters: git/gpg/openpgp/cosign/docker for signing and container ops, syft/trivy/opengrep for SBOM + security tooling, maven/gradle/npm/cargo/xcode for ecosystem invocations, plus github/gitlab/local provider implementations and the GHA / GitLab / manifest / JSON output sinks. Built against the domain ports so the app layer (next commit) can be wired without further plumbing. Signed-off-by: Josef Andersson <josef.andersson@digg.se>
Lands internal/app: every workflow operation that used to live in the v2 bash scripts now exists as a typed Go use case (build, publish, release, container, sbom, security, summary, validate, report, plan, doctor, ci, version, archive, config). Each use case takes the domain types and adapter interfaces from the prior two commits and returns structured results — same observable behaviour as v2, with tests next to each. Removes the matching scripts/ subtrees the bash workflows used to source. Signed-off-by: Josef Andersson <josef.andersson@digg.se>
urfave/cli v3 command tree assembling every domain + app-layer use case behind one binary. Subgroups: build, config, container, doctor, plan, platform, publish, release, report, sbom, security, validate, version. Includes the `cmd/gen-cli-reference` generator and the generated docs/cli-reference.md so `TestDocsCLIReferenceInSync` is satisfied from this commit onward. Signed-off-by: Josef Andersson <josef.andersson@digg.se>
Drops tests/ (the Bats harness) entirely. Equivalent coverage now lives next to the Go code as table-driven _test.go files; the bootstrap installers gain a shellscripts_test.go to keep their shell-side behaviour covered. Signed-off-by: Josef Andersson <josef.andersson@digg.se>
Adapts the GitHub Actions workflows, runtime Containerfile, goreleaser config, .golangci.yml, .gitignore, and .mise.toml to the Go-based binary: install-reusable-ci.sh bootstrap, runtime images that bake reusable-ci, workflow inputs renamed from script paths to the Go CLI surface. Signed-off-by: Josef Andersson <josef.andersson@digg.se>
Rewrites docs/ around the Go binary: artifacts.yml reference, ecosystem-support matrix, runtime images, components, verification, workflows, threat model, GitLab plans. Updates examples/ to consume the v3 workflow contract. Adds the DEVELOPMENT guide for the Go codebase. Signed-off-by: Josef Andersson <josef.andersson@digg.se>
Combined post-port hygiene work. Themes:
- containers[].build-secrets: declare GHA secret names in artifacts.yml;
values flow through one REUSABLE_CI_BUILD_SECRETS_JSON envelope; the
new `container materialize-build-secrets` CLI unpacks them into
mode-0600 tmpfiles and emits `buildx-secrets` for
docker/build-push-action. Wired through publish-container.yml,
publish-dev-container.yml, both publish stages, and both
orchestrators. Schema + threat-model + docs updated.
- `validate event-context` guard: refuses to run privileged workflows
from pull_request* triggers. Domain + app + CLI + threat-model row +
a workflow-coherence test that pins the guard in place across every
privileged workflow.
- Doc cleanup: threat-model defended-property rows, components +
workflow-design-policy trigger-constraint notes, GitLab plan
consolidation, examples/README and publishing.md polish, README
de-Diggified to read for any adopter, SECURITY.md added pointing
at the diggsweden org policy.
- Lint config: .golangci.yml migrated to v2 schema; narrow exclusions
for test-file goconst/varnamelen/cyclop/dupl; the honest-but-noisy
test fixtures (PEM blocks, throwaway GPG keys) get scoped gosec
exemptions. Refactors for cyclop / nonamedreturns / govet shadow /
exhaustive / prealloc / revive / staticcheck / err113 / funcorder /
musttag findings; descriptive renames where varnamelen benefits
(m → manifest, s → sign, w → out, b → buf, r → chr). Two
`vulnerabilit%s` plural-suffix tricks rewritten as whole-word
selection.
- Dependency + Go bumps: Go 1.26.2 → 1.26.3 in go.mod + runtime
container; go-git 5.19.0 → 5.19.1; golang.org/x/{crypto,net,sys,text}
to close the OSV-reported CVE family. Renovate gains the gomod
manager so this drift is automated next time.
- JSON schema validator: gojsonschema → santhosh-tekuri/jsonschema/v6.
The project's schema declares draft 2020-12 but gojsonschema only
supports up to draft-07; the swap aligns validator and schema draft.
- SAST + lychee + gitleaks: real script-injection fix in
release-dev-build-stage.yml and release-dev-publish-stage.yml
(env-var indirection so the shell never interpolates JSON values).
nosemgrep directives placed on the actually-flagged lines for the
test-server fakes, safeexec, httpretry, install-reusable-ci_test.sh,
and the workflow_run checkout pattern in release-binary.yml. Lychee:
README LICENSE link → LICENSES/CC0-1.0.txt; OpenSSF Scorecard badge
→ resolved shields.io URL; CLI flag Usage strings rewritten so the
cli-reference.md regen no longer ends in a regex meta. .lycheeignore
for OIDC issuer + REUSE API + Google Cloud Console + currently-
private testsuite repo. .gitleaks.toml allowlists redact_test.go and
the GPG import stdin test fixtures.
Signed-off-by: Josef Andersson <josef.andersson@digg.se>
janderssonse
force-pushed
the
feat/refactor-go
branch
from
May 25, 2026 08:34
ba4820f to
0ef3e12
Compare
janderssonse
force-pushed
the
feat/refactor-go
branch
from
June 5, 2026 05:09
9557218 to
27520a5
Compare
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Enable Self Runtime Container to build/publish on pushes to feat/refactor-go (push events run the branch's own workflow), tag images :v3-pre and :sha-<sha>, and get the multi-arch build green: - hoist DEBIAN_VERSION to the global ARG scope - pin git-cliff, gh, and Temurin JDK to existing releases - fix the rust (cargo cyclonedx) and android (SIGPIPE) verify steps - build the android runtime amd64-only - bump trivy-action and cosign-installer for current release assets - build the reusable-ci binary in publish-arch before write-digest-marker Temporary branch wiring; remove the feat/refactor-go push entry at v3.0.0. Signed-off-by: Josef Andersson <janderssonse@proton.me>
Bump nanolinter 0.1.0 -> 0.7.0 (latest). Add uv to the toolset and set pipx.uvx=true so mise routes the pipx: backend tools (reuse) through uvx instead of pipx — uv becomes the only Python tool installer. mise has no separate uvx backend, so the pipx: prefix stays but never invokes pipx once uv is on PATH.
Add a linters.nanolinter PR route (default) that runs the consumer's just lint via mise-installed nanolinter and uploads its security findings (OpenGrep SAST, OSV deps, secrets, trivy-fs) to GitHub Code Scanning as SARIF via reusable-ci's enrich/upload-sarif commands. Threads a nanolinter target through the planner, quality stage, status gate, and PR summary. Signed-off-by: Josef Andersson <janderssonse@proton.me>
Make nanolinter the single lint/security route and remove the standalone ones: drop the OpenGrep and dependency-review jobs (security.sast-opengrep*, linters.dependencyreview), fold publiccode (linters.publiccodelint) and devbase-check (linters.devbasecheck) into nanolinter, and delete the four reusable workflows (security-opengrep, security-dependency-review, lint-publiccode, lint-devbase). Swift/iOS linting stays a separate macOS job. Updates planner, golden contract, summary, tests, docs, and examples. BREAKING CHANGE: consumers passing linters.devbasecheck, linters.publiccodelint, linters.dependencyreview, or security.sast-opengrep* must remove them; lint + SAST + dependency/secret scanning now come from the nanolinter route (pin nanolinter + check tools in .mise.toml). Signed-off-by: Josef Andersson <janderssonse@proton.me>
janderssonse
force-pushed
the
feat/refactor-go
branch
from
June 5, 2026 17:03
0c1a125 to
4fe6e36
Compare
Beyond :v3-pre and :sha-<short>, also tag each pre-release build with :v3-pre-<YYYYMMDD-HHMMSS> (immutable, derived from the commit timestamp) and the source branch via type=ref,event=branch (e.g. :feat-refactor-go, :main). Makes images identifiable at a glance on the GHCR package list. Signed-off-by: Josef Andersson <janderssonse@proton.me>
Set org.opencontainers.image.{title,source,url,revision,version,created}
on every per-arch build (publish-arch) so images self-identify via
docker inspect / GHCR independent of tags. Image-config labels are set at
build time, where the per-arch images are produced; source also links the
GHCR package to the repo.
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Update the tag-convention table with the per-branch tag (type=ref), the :v3-pre and :v3-pre-<stamp> pre-release tags, and add an OCI labels section covering the org.opencontainers.image.* labels now set on images. Signed-off-by: Josef Andersson <janderssonse@proton.me>
… images Container-based jobs check out the repository on the host runner and bind-mount it into the runtime image, so the workspace owner never matches the in-container UID and git aborts with 'detected dubious ownership'. This affects every container job that touches git (PR nanolinter base fetch and git checks, git-cliff changelog generation, release tag validation, gradle-android versionCode derivation, …). Set the exception once in the base image (git config --system) so all images inherit it, rather than patching each workflow. Signed-off-by: Josef Andersson <janderssonse@proton.me>
… official semver)
The metadata command could emit tags the registry rejects, which aborted
the runtime-image publish with 'invalid reference format' (a slashed branch
ref -> …:feat/refactor-go).
- type=ref (branch/tag) and the sha {{branch}} template now sanitize the ref
to the distribution tag grammar [A-Za-z0-9_][A-Za-z0-9_.-]{0,127}
(invalid-char runs -> '-', leading '.'/'-' trimmed, capped at 128).
- Every emitted tag is validated against that grammar as a final gate, so an
invalid operator-supplied raw value fails loudly instead of at push.
- type=semver now parses with the official SemVer 2.0.0 regex from semver.org
(named groups), replacing the homegrown major/minor regexes; non-semver
tags are skipped.
Table-driven tests cover slashes, leading separators, length cap, the branch
template, raw-value rejection, and strict-semver matching.
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Runtime-image tags were emitted un-prefixed ({{version}} -> 3.0.0), but
every consumer input defaults to the v-prefixed ghcr tag (…:v3.0.0). After
a v3.0.0 release the defaults would 404 against …:3.0.0.
semverTag now substitutes a pattern template ({{version}}/{{major}}/
{{minor}}/{{patch}} with surrounding literals preserved), so the publish
rules use v{{version}}/v{{major}}.{{minor}}/v{{major}} and a v3.0.0 tag
publishes :v3.0.0, :v3.0 and :v3 — matching the documented lockstep pin.
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Relicense the reusable-ci product source from CC0-1.0 to the dual licence EUPL-1.2 OR GPL-3.0-or-later (licensee's choice). Adds the SPDX licence texts and a root LICENSE notice; keeps the project REUSE-compliant. Scope (607 files): all Go, shell scripts, .github/workflows, the runtime Containerfile, and justfile. Left as CC0-1.0 (public domain): docs, config, test data/golden, go.mod/go.sum, and crucially examples/** — those are templates adopters copy into their own repos, where copyleft would impose obligations on every consumer. The generated cli-reference.md stays CC0; the SPDX literal emitted by internal/cli/render.go is preserved. Also fixes .goreleaser.yml archive glob (LICENSES/**/* -> LICENSES/*): the flat LICENSES/ dir matched nothing, so release tarballs never shipped the licence texts. GPL-3 requires conveying the licence with the binary. Copyright attribution (Digg - Agency for Digital Government) is unchanged. Signed-off-by: Josef Andersson <janderssonse@proton.me>
The CLI had three build paths (Containerfile gobuilder, goreleaser-on-tag, go install), so the binary in the runtime image was never guaranteed to match the released tarball. Collapse the publish path to a single build. - build-cli.yml (new, reusable): goreleaser builds linux/darwin × amd64/arm64 ONCE, cosign-signs + SBOMs + SLSA-attests, uploads dist/ as a run artifact. --skip=publish (callers publish); sign=false build-only mode for PRs (no cosign/OIDC). Edge version forced via GORELEASER_CURRENT_TAG. - Containerfile: remove the gobuilder stage and CLI_SOURCE shim entirely; bake cli-prebuilt/reusable-ci directly. No golang image pull, no in-image compile, one build path. (Standalone `docker build` is no longer self-contained — the image is a CI artifact built by the pipeline.) - self-runtime-container.yml: build-cli runs on every event; verify, publish-arch and publish-merge all consume the one binary (no on-runner Go compiles left). publish-arch adds a coherence-gate (image binary sha == published tarball binary). publish-cli publishes the rolling v3.0.0-edge prerelease via the GitHub REST API (curl, no gh). v*-edge is excluded from this workflow's and self-release.yml's tag triggers so it never re-enters the release path. - install-reusable-ci.sh (+ tests): ref-aware cosign identity — *-edge pins build-cli.yml@refs/heads/…, vN.N.N keeps the production release-binary.yml pin. Two trust domains, neither relaxed. - docs/runtime-images.md: CLI binary channels section. .gitignore: cli-prebuilt/. The tag/release path (release-binary.yml) is unchanged; Phase 2 unifies it. Signed-off-by: Josef Andersson <janderssonse@proton.me>
build-cli's first CI run failed at "Install cosign" (exit 22): cosign-installer v3.7.0 tries to download a detached cosign-linux-amd64.sig, but cosign v3.x releases ship a .sigstore.json bundle instead — so the .sig 404s. The v4.x installer handles the bundle. Same latent bug fixed in release-binary.yml, which would fail the next real release identically. Signed-off-by: Josef Andersson <janderssonse@proton.me>
build-cli failed at "Install syft": egress=block refused the GitHub release-asset S3 backend (github-production-release-asset-*.s3.amazonaws.com, an AWS host) that download-syft redirects to. Chasing shifting tool-download CDN/redirect hosts in an allow-list is brittle. Use egress-policy: audit, consistent with every other job in self-runtime-container.yml. The CLI's supply-chain trust is cosign keyless signing + SLSA build-provenance + the consumer-side identity pin, not egress; harden-runner still records all egress for review. Signed-off-by: Josef Andersson <janderssonse@proton.me>
Repo-wide, SHA-pinned with version comments (idiomatic + supply-chain safe):
- actions/setup-go v5.5.0 -> v6.4.0 (fixes the Node-20 runtime
deprecation the runner warned about)
- actions/checkout v6.0.2 -> v6.0.3
- step-security/harden-runner v2.16.0 -> v2.19.4
- anchore/sbom-action/download-syft v0.18.0 -> v0.24.0 (syft v1.37.0 -> v1.45.1)
- goreleaser/goreleaser-action v6.4.0 -> v7.2.2
- actions/attest-build-provenance v3.2.0 -> v4.1.0
cosign-installer (v4.1.2), upload-artifact (v7.0.1), download-artifact (v8.0.1)
and cosign (v3.0.6) are already current. The two majors (goreleaser-action v7,
attest-build-provenance v4) are exercised immediately by this push's build-cli
and publish-arch jobs.
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
…lobal The nanolinter flavour image is non-root with a read-only $HOME, so `git config --global --add safe.directory` failed: "could not lock config file /github/home/.gitconfig: Permission denied". Set safe.directory through GIT_CONFIG_COUNT/KEY_0/VALUE_0 at the job level instead — no config-file write, and it's inherited by every git invocation in the job (our checkout plus nanolinter's own git-based checks) so the workspace-mount ownership mismatch is covered everywhere. Signed-off-by: Josef Andersson <janderssonse@proton.me>
The nanolinter flavour image runs non-root, and a GitHub job's $GITHUB_WORKSPACE and RUNNER_TEMP are runner-owned mounts the user can't write (`git init` -> ".git: Permission denied"), with $HOME the read-only /github/home mount. Run the whole job in a fresh `mktemp -d` (the container's /tmp is user-writable) exported as WORKDIR: checkout, `nanolinter verify`, the SARIF, and the reusable-ci mise install all happen there — no root, no workspace writes. Because the SARIF now lives outside the workspace, hashFiles() (workspace-only) can't gate the steps — gate on a `sarif` step output instead — and the debug upload-artifact step is dropped (it resolves relative to the workspace). The Code-Scanning upload via reusable-ci (takes an absolute file path) is unaffected. Signed-off-by: Josef Andersson <janderssonse@proton.me>
The nanolinter flavour image bakes MISE_CONFIG_DIR=/opt/mise and pins MISE_OVERRIDE_CONFIG_FILENAMES=/opt/mise/config.toml (read-only). The reusable-ci install step only redirected HOME/XDG_*/MISE_*_DIR, so `mise use -g` tried to write the read-only /opt/mise/config.toml and failed for the non-root user (Permission denied). Also redirect MISE_CONFIG_DIR and MISE_OVERRIDE_CONFIG_FILENAMES to the writable mktemp dir (with an empty config.toml) so the github: install succeeds. Signed-off-by: Josef Andersson <janderssonse@proton.me>
…e them) $GITHUB_ENV/$GITHUB_OUTPUT/$GITHUB_PATH all live under RUNNER_TEMP (/__w/_temp), a runner-owned mount the non-root image user (uid 65532) cannot write — so `printf >> "$GITHUB_ENV"` failed with Permission denied and aborted the checkout step. Share state between steps without any file commands instead: a static $WORKDIR + $SARIF_FILE under the writable /tmp, a .lint-status file read by the gate, and an absolute $RC_BIN path (no $GITHUB_PATH append). Verified end-to-end in the nanolinter:java image with read-only HOME and read-only file-command files. Signed-off-by: Josef Andersson <janderssonse@proton.me>
…ound nanolinter 0.7.6 bakes curl + cosign into every flavour image, so the lint job can install reusable-ci via the canonical cosign-verified bootstrap installer (scripts/bootstrap/install-reusable-ci.sh, REUSABLE_CI_REQUIRE_COSIGN=1) — SHA-256 + cosign build-identity, fail-closed, same path as the rest of the suite. Removes the mise github: interim that only existed while the image lacked curl/cosign: the MISE_DATA/CACHE/STATE/CONFIG_DIR + MISE_OVERRIDE_CONFIG_FILENAMES redirects, the empty config.toml hack, mise use -g / mise which, and the "TLS-only, not cosign-pinned" caveat. The install step now curl-fetches the two bootstrap scripts at the ref and runs them with a writable HOME/XDG (for cosign's sigstore cache) and GITHUB_PATH="" (so the installer skips the PATH append the non-root user can't write); the binary lands at the static $RC_BIN. The non-root file-command avoidance (static /tmp paths + .lint-status file) stays — it's a runner-mount constraint, independent of curl/cosign. Stale "via mise" descriptions in the orchestrator + quality-stage updated too. Verified end-to-end in nanolinter:java 0.7.6 under read-only HOME and read-only file-command files: Sigstore verified, enrich OK, gate fires, zero file-command writes. actionlint clean. Signed-off-by: Josef Andersson <janderssonse@proton.me>
GitHub forces HOME=/github/home (a read-only mount) for container jobs, overriding the nanolinter image's own writable /home/nanolinter. opengrep hardcodes `mkdir $HOME/.opengrep` on startup (no SEMGREP_/OPENGREP_ env override exists), so the SAST check crashed with PermissionError on /github/home/.opengrep — surfacing as a "Tool/runtime failure", not a finding. Point HOME back at the image home (where the baked tool caches/config already live, and which the non-root user owns). Other tools use the baked XDG_CACHE_HOME and mvn already runs fine under a read-only HOME, so this only helps. Reproduced and fixed in nanolinter:java 0.7.6. Signed-off-by: Josef Andersson <janderssonse@proton.me>
…gate The lint step used to `exit 0` and a separate "Gate" step re-read a status file and failed — so the "Run nanolinter" step showed green while a later gate went red with "nanolinter verify failed (status 1)", which reads like a workflow glitch rather than "your code has lint issues". Make the nanolinter step fail directly on a blocking finding, with a clear message pointing at the per-check summary right above it. The SARIF install/enrich/upload steps already run via `if: always()`, so the report is still produced and uploaded after the failure — no status file or gate step needed. Signed-off-by: Josef Andersson <janderssonse@proton.me>
A GitHub-side 504 on a release asset failed the install on the first try (curl -sSfL doesn't retry), and in the nanolinter image the go-install fallback can't run, so it hard-failed. Add `--retry 5 --retry-delay 3 --retry-connrefused` to the installer's asset/checksums/bundle downloads and to the lint workflow's bootstrap-script fetch. `--retry` already covers HTTP 408/429/5xx + timeouts; the flags are old/portable so they're safe on every runner's curl. Verified: rode out a live 504 on the linux_amd64 tarball. Signed-off-by: Josef Andersson <janderssonse@proton.me>
nanolinter auto-writes a nice "Linting Results" panel to $GITHUB_STEP_SUMMARY, but the non-root flavour image can't write the real runner summary file (it lives under the runner-owned RUNNER_TEMP), so the panel vanished when lint moved into that image. Restore it: the nanolinter step redirects $GITHUB_STEP_SUMMARY to a writable /tmp file, uploads that markdown as an artifact, and the runtime-base "Summary" job (which can write the panel) downloads it and emits it to its own $GITHUB_STEP_SUMMARY. Both the upload and render are continue-on-error so a flaky artifact never fails the lint gate. Signed-off-by: Josef Andersson <janderssonse@proton.me>
… captured
The step-level `env: GITHUB_STEP_SUMMARY` was ignored — the runner re-injects
its own per-step value, so nanolinter still wrote to the real (unwritable)
summary file and nothing landed at /tmp ("No files were found … No artifacts
will be uploaded"). Export it inside the run script instead, where a shell
export wins for the nanolinter child process. Confirmed: nanolinter now writes
the panel markdown to /tmp even when an unwritable GITHUB_STEP_SUMMARY is
injected into the step env.
Signed-off-by: Josef Andersson <janderssonse@proton.me>
The runtime-container build failed when GitHub (mid "Partially Degraded Service" incident) returned a 504 on the yq release download — the bootstrap installers used curl with no retries, so the first blip killed the image build (go/java legs failed; node/rust passed only because they hit the GHA layer cache). The links are correct; it was purely transient. Add `--retry 5 --retry-delay 3 --retry-connrefused` to every release-download curl (yq, mise, opengrep, glab, publiccode-parser, git-cliff, gh, cosign, and the trivy/syft install.sh fetch), matching install-reusable-ci.sh. shellcheck clean, go tests pass. Signed-off-by: Josef Andersson <janderssonse@proton.me>
…T EACCES
The artifact upload itself succeeds (confirmed: "successfully uploaded! Final
size is 3303 bytes"); upload-artifact then fails only when writing its unused
step outputs to $GITHUB_OUTPUT — a runner file-command file the non-root user
can't write (EACCES). Mark that step continue-on-error so the cosmetic failure
doesn't red the job. The lint gate is the separate "Run nanolinter" step, so
this can't mask findings; a real upload failure still shows downstream as a
missing panel ("Artifact not found").
Signed-off-by: Josef Andersson <janderssonse@proton.me>
…ails When the reusable-ci download failed (transient release 504), the install step went red but enrich/upload showed green — their `[ -x "$RC_BIN" ]` guard silently exit-0'd, faking success. Gate enrich/upload on `steps.install.outcome == 'success'` so they skip honestly when the binary isn't there; the install step's own red still surfaces the failure. The lint gate itself stays the separate "Run nanolinter" step. Signed-off-by: Josef Andersson <janderssonse@proton.me>
The Dev Release Summary job is `if: always()` so it can report failures, but it
read fromJson(needs.setup-dev.outputs['dev-release-plan-json']) unguarded — when
setup-dev fails, that output is empty and fromJson('') template-crashes the
summary ("Error reading JToken... Path '', line 0, position 0") instead of
producing a failure summary. Add `|| '{}'`. (The full release-orchestrator's
summary already passes raw JSON strings, so it wasn't affected.)
Signed-off-by: Josef Andersson <janderssonse@proton.me>
actions/cache v4.2.3 and v4.3.0 both still run on Node 20, which GitHub is deprecating (forced to Node 24 on 2026-06-16, removed 2026-09-16). v5.0.5 is the Node 24 line. Standardize all eight cache pins on it to clear the deprecation warning. Inputs/behavior unchanged (key/path/restore-keys). Signed-off-by: Josef Andersson <janderssonse@proton.me>
The container-publish jobs run on the bare host runner (buildx needs the daemon), not in a runtime image, so the baked syft isn't present — and `reusable-ci sbom generate container` shells out to `syft`, failing with "executable file not found in $PATH". Add an "Install syft" step before the SBOM step in both publish-dev-container.yml and publish-container.yml (mirroring the existing "Install trivy"). Root cause that also made the install-then-use-next-step pattern unreliable: ci_prepend_path only did an in-process `export PATH` and never wrote $GITHUB_PATH, so a tool installed in one step wasn't on PATH in the next. Make ci_prepend_path also append to $GITHUB_PATH (guarded on non-empty, so the non-root nanolinter lint that sets GITHUB_PATH="" is unaffected); this fixes syft and the latent trivy-scan case alike. Drop the now-redundant manual $GITHUB_PATH write in install-reusable-ci.sh. go test + shellcheck + actionlint pass. Signed-off-by: Josef Andersson <janderssonse@proton.me>
Drop the previous ci_prepend_path/$GITHUB_PATH refactor — overkill. The SBOM step just needs syft locally, and install-syft.sh already installs to a writable /tmp dir. Source + install_syft + run reusable-ci in the SAME step so the in-process PATH covers the call; no shared-installer changes, no cross-step PATH persistence needed. Same minimal pattern in both publish-dev-container.yml and publish-container.yml. Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
The v4 artifact API needs ACTIONS_RESULTS_URL/ACTIONS_RUNTIME_TOKEN, which GitHub exposes only to actions, not to run: steps — so reusable-ci artifact upload/download fail there. Restore actions/upload-artifact + actions/download-artifact for the digest hand-off. Signed-off-by: Josef Andersson <janderssonse@proton.me>
GitHub injects the v4 artifact runtime token only into actions, never into
run: steps, so `reusable-ci artifact upload` can't authenticate from a run
step. Switch the 35 upload sites to actions/upload-artifact. Downloads use the
REST artifacts API (reachable from run steps) so they stay on the CLI, but
GITHUB_TOKEN isn't auto-present in run steps — add GH_TOKEN: ${{ github.token }}
to the 18 download steps.
Signed-off-by: Josef Andersson <janderssonse@proton.me>
Signed-off-by: Josef Andersson <janderssonse@proton.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Description
Please include a summary of the change and which issue is fixed or added.
Please also include relevant motivation and context.
List any dependencies that are required for this change.
Fixes #(issue)
Checklist