ci: add Dockerfile and GitHub Actions workflow to publish to ghcr.io - #3
Conversation
|
Warning Review limit reached
More reviews will be available in 37 minutes and 26 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR adds a multi-stage Dockerfile plus a GitHub Actions workflow that runs tests and linting, builds a multi-arch Docker image with Buildx and metadata-based tags, and conditionally pushes the image to ghcr.io for non-pull-request events. A ChangesDocker Image Build and Publish Pipeline
Sequence DiagramsequenceDiagram
participant Developer
participant GitHub as GitHub Events
participant Actions as GitHub Actions
participant Buildx as Docker Buildx
participant GHCR as ghcr.io
Developer->>GitHub: Push to main or create v* tag (or open PR)
GitHub->>Actions: Trigger workflow
Actions->>Actions: Run test and lint jobs
Actions->>Buildx: Checkout repo & initialize Buildx
Actions->>GHCR: Login to GHCR (if not PR)
Actions->>Buildx: Generate tags via docker/metadata-action
Buildx->>Buildx: Build multi-stage image (amd64, arm64) with cache
Buildx->>GHCR: Push image with tags (if not PR)
GHCR-->>Actions: Confirm image published
Actions-->>GitHub: Workflow complete
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a multi-stage Dockerfile for building the talos-meta-tool. The review identifies a critical issue where an invalid Go version (1.26) is specified, which will lead to build failures. Additionally, it is recommended to remove the hardcoded GOARCH=amd64 to support multiple architectures and to include the -trimpath flag for improved build reproducibility.
| @@ -0,0 +1,11 @@ | |||
| FROM golang:1.26-alpine AS builder | |||
There was a problem hiding this comment.
The Go version 1.26 does not exist (the current stable version is 1.23). This will cause the Docker build to fail as the base image cannot be pulled. Please use a valid version like 1.23-alpine. Note that the go.mod file also specifies 1.26.3, which should be corrected to a valid version to avoid build errors.
FROM golang:1.23-alpine AS builder
| RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ | ||
| go build -ldflags="-s -w" -o /talos-meta-tool . |
There was a problem hiding this comment.
Hardcoding GOARCH=amd64 prevents the image from being built for other architectures (e.g., arm64), which is a common requirement for Talos-related tools. Removing the hardcoded architecture allows the build to adapt to the target platform. Additionally, adding -trimpath is recommended for more reproducible builds.
RUN CGO_ENABLED=0 GOOS=linux \
go build -trimpath -ldflags="-s -w" -o /talos-meta-tool .
There was a problem hiding this comment.
🧹 Nitpick comments (2)
.github/workflows/docker.yaml (1)
36-43: ⚡ Quick winConsider enabling multi-arch publishing now that buildx is wired up.
Pairs with the Dockerfile comment about the hardcoded
GOARCH. If you adoptTARGETOS/TARGETARCHin the Dockerfile, you can publish a true multi-arch manifest by addingplatforms:here. QEMU is needed to emulate non-native targets onubuntu-latest.♻️ Proposed addition
- uses: docker/setup-buildx-action@v3 + + - uses: docker/setup-qemu-action@v3 @@ - uses: docker/build-push-action@v6 with: context: . + platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/docker.yaml around lines 36 - 43, Add multi-arch publishing to the docker/build-push-action@v6 step by specifying a platforms: list (e.g. linux/amd64,linux/arm64) and ensure buildx and QEMU are initialized beforehand (use docker/setup-buildx-action and docker/setup-qemu-action) so non-native targets can be emulated; also update the Dockerfile to use TARGETOS/TARGETARCH instead of hardcoded GOARCH so the published images in the manifest match each architecture.Dockerfile (1)
6-7: ⚡ Quick winHardcoded
GOARCH=amd64defeats multi-arch builds.With
docker/setup-buildx-actionalready configured in the workflow, this Dockerfile is ready to be driven for multiple platforms, but forcingGOARCH=amd64will silently cross-compile every build to amd64 regardless of the requested target platform (and ignorearm64runners orplatforms:inputs).Prefer letting BuildKit pass
TARGETOS/TARGETARCHvia the platform args:♻️ Proposed fix
-FROM golang:1.26-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS builder +ARG TARGETOS +ARG TARGETARCH WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ - go build -ldflags="-s -w" -o /talos-meta-tool . +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ + go build -ldflags="-s -w" -o /talos-meta-tool .If you also want the workflow to actually publish multi-arch manifests, add
platforms: linux/amd64,linux/arm64to thedocker/build-push-actionstep.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Dockerfile` around lines 6 - 7, The RUN line forces GOARCH=amd64 which breaks multi-arch builds; update the build invocation that sets CGO_ENABLED/GOOS/GOARCH and runs go build (the RUN ... go build -ldflags="-s -w" -o /talos-meta-tool .) to accept BuildKit platform args instead: remove the hardcoded GOARCH=amd64 (and avoid hardcoding GOOS if desired) and use the passed TARGETOS and TARGETARCH environment variables (or their BuildKit equivalents) so the image builds for the requested platform; keep CGO_ENABLED=0 if needed and ensure the go build step still outputs /talos-meta-tool.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In @.github/workflows/docker.yaml:
- Around line 36-43: Add multi-arch publishing to the
docker/build-push-action@v6 step by specifying a platforms: list (e.g.
linux/amd64,linux/arm64) and ensure buildx and QEMU are initialized beforehand
(use docker/setup-buildx-action and docker/setup-qemu-action) so non-native
targets can be emulated; also update the Dockerfile to use TARGETOS/TARGETARCH
instead of hardcoded GOARCH so the published images in the manifest match each
architecture.
In `@Dockerfile`:
- Around line 6-7: The RUN line forces GOARCH=amd64 which breaks multi-arch
builds; update the build invocation that sets CGO_ENABLED/GOOS/GOARCH and runs
go build (the RUN ... go build -ldflags="-s -w" -o /talos-meta-tool .) to accept
BuildKit platform args instead: remove the hardcoded GOARCH=amd64 (and avoid
hardcoding GOOS if desired) and use the passed TARGETOS and TARGETARCH
environment variables (or their BuildKit equivalents) so the image builds for
the requested platform; keep CGO_ENABLED=0 if needed and ensure the go build
step still outputs /talos-meta-tool.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d9f3dd93-e8ad-464b-bdba-53b2d10912c3
📒 Files selected for processing (2)
.github/workflows/docker.yamlDockerfile
There was a problem hiding this comment.
Pull request overview
Adds container packaging and CI automation to build and publish talos-meta-tool images to GitHub Container Registry (ghcr.io).
Changes:
- Introduces a multi-stage Dockerfile that builds a static Linux binary and ships it in a
scratchimage. - Adds a GitHub Actions workflow to build and (on main/tags) push the image to
ghcr.iowith metadata-driven tags and GHA caching.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| Dockerfile | Builds talos-meta-tool as a static binary in a builder stage and copies it into a minimal runtime image. |
| .github/workflows/docker.yaml | Builds and publishes the Docker image to GHCR on pushes/tags, using Docker metadata and build cache. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| WORKDIR /src | ||
| COPY go.mod go.sum ./ | ||
| RUN go mod download | ||
| COPY . . |
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - uses: docker/login-action@v3 | ||
| if: github.event_name != 'pull_request' | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - uses: docker/metadata-action@v5 | ||
| id: meta | ||
| with: | ||
| images: ghcr.io/${{ github.repository }} | ||
| tags: | | ||
| type=semver,pattern={{version}} | ||
| type=semver,pattern={{major}}.{{minor}} | ||
| type=raw,value=latest,enable={{is_default_branch}} | ||
|
|
||
| - uses: docker/build-push-action@v6 | ||
| with: | ||
| context: . | ||
| push: ${{ github.event_name != 'pull_request' }} | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| labels: ${{ steps.meta.outputs.labels }} |
| docker: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| steps: |
Andrei Kvapil (kvaps)
left a comment
There was a problem hiding this comment.
LGTM — clean multi-stage build on scratch, and the workflow is well-scoped (packages:write only, login/push gated on non-PR events, semver tags, gha cache).
Two notes:
- The DCO check is red — the commit needs a
Signed-off-byline.git commit --amend -s+ force-push will fix it. - Nice-to-have (not blocking):
GOARCH=amd64is hard-coded, so the image is amd64-only. Since bare-metal Talos/Tinkerbell also runs on arm64, consider building multi-arch via buildxTARGETARCH/TARGETOSand addingplatforms: linux/amd64,linux/arm64to the build-push step. Happy to take it as a follow-up.
7506caa to
e377a62
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
Dockerfile (2)
10-12: 💤 Low valueRun as a non-root user to satisfy the Trivy DS-0002 finding.
The container runs as root (uid 0) by default. Adding a numeric
USERclears the static-analysis finding and follows least-privilege; a numeric UID works without/etc/passwdonscratch.🔒 Proposed change
FROM scratch COPY --from=builder /talos-meta-tool /talos-meta-tool +USER 65534:65534 ENTRYPOINT ["/talos-meta-tool"]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Dockerfile` around lines 10 - 12, The image uses FROM scratch and currently runs as root via ENTRYPOINT ["/talos-meta-tool"]; fix the Trivy DS-0002 finding by adding a numeric non-root user (e.g., USER 65532) to the Dockerfile so the container runs with least privilege—update the Dockerfile after the COPY/ENTRYPOINT lines to include a USER <numeric-uid> instruction (referencing the existing ENTRYPOINT and COPY from the diff) so no /etc/passwd entries are required.
1-8: ⚡ Quick winPin the builder to
$BUILDPLATFORMto avoid emulation on multi-arch buildsThe workflow builds
linux/amd64andlinux/arm64viadocker/build-push-actionwithout specifying a--platform=$BUILDPLATFORMfor thebuilderstage, so thebuilderstage will run under emulation for non-native platforms. Pinning the stage to$BUILDPLATFORMavoids that slowdown while keeping cross-compilation viaGOARCH=${TARGETARCH}. (Base image taggolang:1.26-alpineexists.)♻️ Proposed change
-FROM golang:1.26-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS builder🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Dockerfile` around lines 1 - 8, Update the builder stage in the Dockerfile to pin it to the build platform so it doesn't run under emulation for non-native architectures: modify the builder stage FROM instruction to include the --platform=$BUILDPLATFORM flag (the stage named "builder" that uses golang:1.26-alpine and relies on ARG TARGETARCH / GOARCH) so the stage runs on the host build platform while continuing to cross-compile via CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} in the go build step.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/docker.yaml:
- Line 15: Three occurrences of the checkout step use "uses:
actions/checkout@v4" and are persisting GITHUB_TOKEN into the runner git config;
update each "uses: actions/checkout@v4" step to include a "with:
persist-credentials: false" block so the checkout action does not persist
credentials (apply this to every checkout step in the workflow).
- Around line 16-19: The workflow uses actions/setup-go@v5 with only
go-version-file: go.mod which enables module caching for untrusted PRs; update
the test job to disable setup-go caching for pull_request events by adding the
setup-go input cache: false (or conditionally run a step that sets cache: false
when github.event_name == 'pull_request'), so replace the current
actions/setup-go@v5 step to include with: go-version-file: go.mod and cache:
false (or gate the step with an if check) to prevent cache poisoning on PRs.
- Around line 15-16: This workflow uses tag-pinned GitHub Actions and insecure
defaults; replace every uses: <action>@<tag> (e.g., actions/checkout@v4,
actions/setup-go@v5, docker/build-push-action@v3, actions/cache@v6,
actions/upload-artifact@v3, etc.) with the corresponding full commit SHA to
prevent tag movement, add with: persist-credentials: false to each
actions/checkout step when authenticated git access is not required, and change
actions/setup-go@v5 usage to include with: cache: false (or otherwise constrain
caching) and go-version-file: go.mod for untrusted pull_request runs; ensure you
update all instances across the file consistently.
---
Nitpick comments:
In `@Dockerfile`:
- Around line 10-12: The image uses FROM scratch and currently runs as root via
ENTRYPOINT ["/talos-meta-tool"]; fix the Trivy DS-0002 finding by adding a
numeric non-root user (e.g., USER 65532) to the Dockerfile so the container runs
with least privilege—update the Dockerfile after the COPY/ENTRYPOINT lines to
include a USER <numeric-uid> instruction (referencing the existing ENTRYPOINT
and COPY from the diff) so no /etc/passwd entries are required.
- Around line 1-8: Update the builder stage in the Dockerfile to pin it to the
build platform so it doesn't run under emulation for non-native architectures:
modify the builder stage FROM instruction to include the
--platform=$BUILDPLATFORM flag (the stage named "builder" that uses
golang:1.26-alpine and relies on ARG TARGETARCH / GOARCH) so the stage runs on
the host build platform while continuing to cross-compile via CGO_ENABLED=0
GOOS=linux GOARCH=${TARGETARCH} in the go build step.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6db6e4ad-88c5-4e30-a1b1-e52d64433eaa
📒 Files selected for processing (3)
.dockerignore.github/workflows/docker.yamlDockerfile
| permissions: | ||
| contents: read | ||
| steps: | ||
| - uses: actions/checkout@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the workflow with line numbers around the referenced lines
nl -ba .github/workflows/docker.yaml | sed -n '1,200p'
# Check whether persist-credentials is already present anywhere in the workflow
rg -n "persist-credentials" .github/workflows/docker.yaml || true
# Show all checkout steps in the workflow for context
rg -n "uses:\s*actions/checkout@v" .github/workflows/docker.yaml -n
nl -ba .github/workflows/docker.yaml | rg -n "uses:\s*actions/checkout@v"Repository: cozystack/talos-meta-tool
Length of output: 112
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/docker.yaml")
txt = p.read_text().splitlines()
for i, line in enumerate(txt, start=1):
if i in {1,5,10,15,16,20,25,26,27,30,35,38,39,40,50} or "actions/checkout" in line or "persist-credentials" in line:
print(f"{i:4d}: {line}")
PY
echo "---- persist-credentials matches ----"
rg -n "persist-credentials" .github/workflows/docker.yaml || true
echo "---- checkout@v4 matches ----"
rg -n "uses:\s*actions/checkout@v4" .github/workflows/docker.yaml || true
echo "---- checkout@v matches ----"
rg -n "uses:\s*actions/checkout@" .github/workflows/docker.yaml || true
echo "---- show file (truncated) ----"
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/docker.yaml")
lines = p.read_text().splitlines()
for i in range(min(len(lines),120)):
print(f"{i+1:4d}: {lines[i]}")
PYRepository: cozystack/talos-meta-tool
Length of output: 2829
Disable checkout credential persistence in each job.
Add with: persist-credentials: false to all actions/checkout@v4 steps in .github/workflows/docker.yaml (lines 15, 26, and 38) to avoid persisting GITHUB_TOKEN credentials into the runner’s git config.
Suggested patch
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@v4 | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 15-15: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/docker.yaml at line 15, Three occurrences of the checkout
step use "uses: actions/checkout@v4" and are persisting GITHUB_TOKEN into the
runner git config; update each "uses: actions/checkout@v4" step to include a
"with: persist-credentials: false" block so the checkout action does not persist
credentials (apply this to every checkout step in the workflow).
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-go@v5 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/docker.yaml"
echo "== File head/tail for context =="
sed -n '1,120p' "$FILE" | nl -ba
echo
echo "== Exact uses: lines =="
nl -ba "$FILE" | rg -n "uses:\s*(actions/checkout@|actions/setup-go@)" -n || true
echo
echo "== persist-credentials occurrences =="
nl -ba "$FILE" | rg -n "persist-credentials" || true
echo
echo "== setup-go options block =="
# Print setup-go lines and nearby options
nl -ba "$FILE" | rg -n "uses:\s*actions/setup-go@v5" -n -C 6 || trueRepository: cozystack/talos-meta-tool
Length of output: 163
🌐 Web query:
actions/setup-go v5 default cache behavior cache option default value
💡 Result:
For actions/setup-go v5, the default cache behavior is that caching is enabled by default. 1) Cache option default value - The action input cache has a default value of true (so caching is on unless you set cache: false). [1] 2) “Default cache behavior” (what gets cached/restored) - The action includes built-in caching/restoration for Go modules and build outputs. [2] - It automatically computes the cache key from dependency files. [2] - For v5 specifically, the default dependency file used to form the Go modules cache key is go.sum in the repository root (you can change this via cache-dependency-path). [3] If you want to disable it explicitly: - uses: actions/setup-go@v5 with: cache: false Citations: default cache: true [1]; v5 caching enabled by default unless cache=false and uses go.sum in repo root for cache key [3].
Citations:
- 1: https://github.com/actions/setup-go/blob/main/action.yml
- 2: https://github.com/actions/setup-go
- 3: https://github.com/actions/setup-go/blob/d35c59ab/README.md
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/docker.yaml"
echo "== File =="
sed -n '1,120p' "$FILE"
echo
echo "== uses: (checkout/setup-go) with line numbers =="
awk '{print NR "\t" $0}' "$FILE" | rg -n "uses:\s*(actions/checkout@|actions/setup-go@)"
echo
echo "== persist-credentials occurrences =="
awk '{print NR "\t" $0}' "$FILE" | rg -n "persist-credentials"
echo
echo "== setup-go blocks (uses line + 8 lines after) =="
awk '{print NR "\t" $0}' "$FILE" | rg -n "uses:\s*actions/setup-go@" -n -C 8Repository: cozystack/talos-meta-tool
Length of output: 1930
🌐 Web query:
actions/checkout@v4 persist-credentials default value persist-credentials false security guidance
💡 Result:
For actions/checkout@v4, the persist-credentials input’s default behavior is effectively true: the action treats a missing persist-credentials input as false in code, but the published input schema and security guidance indicate credentials are persisted unless you explicitly set persist-credentials: false. Default value (when you don’t pass persist-credentials): true (credentials are persisted unless opted out) [1][2]. What persist-credentials does: actions/checkout persists the auth token in the local git config so later steps can run authenticated git commands, then removes it during post-job cleanup; to opt out, set persist-credentials: false [1]. Security guidance: GitHub/security guidance recommends setting persist-credentials: false unless you need authenticated git operations, to reduce risk of credential exposure if the workflow is compromised [3]. Practical recommendation: - If you don’t need later steps to run authenticated git commands (push/fetch with repo-scoped credentials), use: uses: actions/checkout@v4 with: persist-credentials: false [3][1]
Citations:
- 1: https://github.com/actions/checkout/tree/v4
- 2: Remove
persist-credentialsor change the default tofalseactions/checkout#485 - 3: https://cheatsheetseries.owasp.org/cheatsheets/GitHub_Actions_Security_Cheat_Sheet.html
🌐 Web query:
actions/setup-go v5 cache true what is cached go build cache go mod cache
💡 Result:
When cache is enabled (which is the default behavior) in actions/setup-go v5, it automatically manages both the Go module cache and the Go build cache [1][2]. Specifically, the action handles the following: - Go Module Cache: This is the directory where Go stores downloaded dependencies (typically retrieved via go mod download). The action identifies this path using the output of go env GOMODCACHE [3]. - Go Build Cache: This is the directory where Go stores build artifacts and test results to speed up subsequent builds and tests. The action identifies this path using the output of go env GOCACHE [3]. By setting cache: true, you do not need to manually configure the paths or cache keys for these directories [1][4]. The action automatically computes a cache key based on your dependency files (by default, it looks for go.mod in the repository root) [1][5]. You can customize which dependency files are used to generate the cache key by using the cache-dependency-path input [1][2].
Citations:
- 1: https://github.com/actions/setup-go
- 2: https://github.com/actions/setup-go/blob/main/README.md
- 3: https://danp.net/posts/github-actions-go-cache/
- 4: https://github.com/actions/setup-go/tree/v5.0.1
- 5: https://github.com/actions/setup-go/blob/d35c59ab/README.md
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/docker.yaml"
awk '{print NR "\t" $0}' "$FILE" | rg -n "^\s*-\s+uses:" -nRepository: cozystack/talos-meta-tool
Length of output: 51
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/docker.yaml"
echo "== All uses: lines (with line numbers) =="
awk '{print NR ":" $0}' "$FILE" | rg -n "uses:"
echo
echo "== Specific checkout/setup-go uses =="
awk '{print NR ":" $0}' "$FILE" | rg -n "uses: actions/(checkout|setup-go)@"
echo
echo "== persist-credentials =="
awk '{print NR ":" $0}' "$FILE" | rg -n "persist-credentials"Repository: cozystack/talos-meta-tool
Length of output: 737
Pin all GitHub Actions to full commit SHAs (and tighten checkout/setup-go security)
.github/workflows/docker.yamluses tag-pinned actions (@v4/@v5/@v7/@v3/@v6) at lines 15, 16, 26, 27, 38, 40, 42, 49, and 58; replace eachuses: <action>@<tag>withuses: <action>@<full-commit-sha>to prevent tag movement.actions/checkout@v4steps (lines 15/26/38) don’t setpersist-credentials: false; add it if authenticated git operations aren’t needed.actions/setup-go@v5(line 16) has defaultcache: true(module + build cache); disable (cache: false) for untrustedpull_requestruns or otherwise constrain caching.
Example changes
- uses: actions/checkout@v4
with:
persist-credentials: false- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: false🧰 Tools
🪛 zizmor (1.25.2)
[warning] 15-15: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 16-16: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 16-16: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/docker.yaml around lines 15 - 16, This workflow uses
tag-pinned GitHub Actions and insecure defaults; replace every uses:
<action>@<tag> (e.g., actions/checkout@v4, actions/setup-go@v5,
docker/build-push-action@v3, actions/cache@v6, actions/upload-artifact@v3, etc.)
with the corresponding full commit SHA to prevent tag movement, add with:
persist-credentials: false to each actions/checkout step when authenticated git
access is not required, and change actions/setup-go@v5 usage to include with:
cache: false (or otherwise constrain caching) and go-version-file: go.mod for
untrusted pull_request runs; ensure you update all instances across the file
consistently.
| - uses: actions/setup-go@v5 | ||
| with: | ||
| go-version-file: go.mod | ||
| - run: go test ./... |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the referenced workflow and surrounding lines
if [ -f .github/workflows/docker.yaml ]; then
nl -ba .github/workflows/docker.yaml | sed -n '1,120p'
else
echo "Missing: .github/workflows/docker.yaml"
fi
echo "----"
# Check for any other setup-go usages
rg -n "actions/setup-go@v" .github/workflows || true
echo "----"
# Check workflow triggers for docker.yaml
rg -n "^(on:|jobs:|name:)" .github/workflows/docker.yaml || trueRepository: cozystack/talos-meta-tool
Length of output: 112
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- docker.yaml (first 160 lines, with line numbers) ----"
if [ -f .github/workflows/docker.yaml ]; then
cat -n .github/workflows/docker.yaml | sed -n '1,160p'
else
echo "Missing: .github/workflows/docker.yaml"
fi
echo "---- setup-go usage in workflows ----"
rg -n "actions/setup-go@v" .github/workflows || true
echo "---- triggers in docker.yaml ----"
if [ -f .github/workflows/docker.yaml ]; then
rg -n "^(on:|jobs:|name:)" .github/workflows/docker.yaml || true
fiRepository: cozystack/talos-meta-tool
Length of output: 2423
🌐 Web query:
actions/setup-go v5 cache false cache key go.sum go.mod cache-dependency-path
💡 Result:
When using actions/setup-go v5, if you set the cache input to false, the action will disable its built-in caching mechanism [1][2]. Because the caching feature is disabled, the cache-dependency-path input becomes irrelevant and will not be used by the action, as there is no cache to populate or restore [2]. The cache-dependency-path input is only functional when caching is enabled (the default state, or when cache: true is set) [1][2]. In that scenario, it allows you to specify the path to your dependency files (such as go.sum or go.mod) so the action can use their hashes to generate the cache key [1][2]. If you have multiple dependency files or they are located in subdirectories, you can use glob patterns or specify multiple paths using the pipe | syntax within the cache-dependency-path input [1]. If you need to implement custom caching logic—for instance, if you require more granular control than the default behavior provides—you can set cache: false and then manually implement caching using the actions/cache action (e.g., actions/cache/restore and actions/cache/save) [3][4]. In such a manual implementation, you would then be responsible for defining the cache keys and paths, effectively bypassing the setup-go action's built-in caching configuration [3][4].
Citations:
- 1: https://github.com/actions/setup-go/blob/d35c59ab/README.md
- 2: https://github.com/actions/setup-go
- 3: https://github.com/actions/setup-go/tree/refs/heads/dependabot/npm_and_yarn/actions/cache-5.0.3
- 4: https://github.com/actions/setup-go/blob/main/docs/advanced-usage.md
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- .github/workflows/test.yaml (first 120 lines) ----"
if [ -f .github/workflows/test.yaml ]; then
cat -n .github/workflows/test.yaml | sed -n '1,160p'
else
echo "Missing test.yaml"
fiRepository: cozystack/talos-meta-tool
Length of output: 494
Disable Go caching for pull_request workflows to avoid cache poisoning risk
Both .github/workflows/docker.yaml (job test) and .github/workflows/test.yaml run on pull_request with actions/setup-go@v5 configured only with go-version-file: go.mod (no cache: false), so the action’s default module cache behavior is enabled for untrusted PRs. Consider disabling setup-go caching for pull_request (or isolating trusted/untrusted workflows).
Suggested patch
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
+ cache: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - run: go test ./... | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: false | |
| - run: go test ./... |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 16-16: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 16-16: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/docker.yaml around lines 16 - 19, The workflow uses
actions/setup-go@v5 with only go-version-file: go.mod which enables module
caching for untrusted PRs; update the test job to disable setup-go caching for
pull_request events by adding the setup-go input cache: false (or conditionally
run a step that sets cache: false when github.event_name == 'pull_request'), so
replace the current actions/setup-go@v5 step to include with: go-version-file:
go.mod and cache: false (or gate the step with an if check) to prevent cache
poisoning on PRs.
e377a62 to
a64986a
Compare
Signed-off-by: Mickaël Canévet <mickael.canevet@proton.ch>
a64986a to
f875556
Compare
Andrei Kvapil (kvaps)
left a comment
There was a problem hiding this comment.
Re-approving after the force-push. Nicely done — you addressed everything and more:
- Multi-arch via
TARGETARCH+platforms: linux/amd64,linux/arm64. - Workflows consolidated into a single
ci.yamlwithdockergated onneeds: [test, lint]+ main/tag refs. - Pinned
golang:1.26.3-alpine, added-trimpath, and a tight.dockerignore. - DCO sign-off in place.
LGTM.
Summary by CodeRabbit
New Features
Chores