-
Notifications
You must be signed in to change notification settings - Fork 3
feat: publish multi-arch Docker image on release #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # Publish a release Docker image to GHCR. | ||
| # | ||
| # Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a publish job | ||
| # within `cargo-dist`. Runs after `host`, so the GitHub Release and its binary artifacts exist; | ||
| # the Dockerfile fetches the prebuilt musl binary from the release at image-build time. | ||
|
|
||
| name: "[tower] Publish Docker image" | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| plan: | ||
| required: true | ||
| type: string | ||
|
|
||
| jobs: | ||
| docker-publish: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - uses: docker/setup-buildx-action@v3 | ||
| - uses: docker/login-action@v3 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Build and push | ||
| env: | ||
| TAG: ${{ fromJson(inputs.plan).announcement_tag }} | ||
| PRERELEASE: ${{ fromJson(inputs.plan).announcement_is_prerelease }} | ||
| run: | | ||
| VERSION="${TAG#v}" | ||
| TAGS=(--tag "ghcr.io/tower/tower-cli:$VERSION") | ||
| if [ "$PRERELEASE" != "true" ]; then | ||
| TAGS+=(--tag "ghcr.io/tower/tower-cli:latest") | ||
| fi | ||
| docker buildx build \ | ||
| --platform linux/amd64,linux/arm64 \ | ||
| --build-arg VERSION="$VERSION" \ | ||
| "${TAGS[@]}" \ | ||
| --push . | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,18 @@ | ||||||||||||||||
| FROM --platform=$BUILDPLATFORM alpine:3 AS fetch | ||||||||||||||||
| ARG TARGETARCH | ||||||||||||||||
| ARG VERSION | ||||||||||||||||
| RUN apk add --no-cache curl tar xz \ | ||||||||||||||||
| && case "$TARGETARCH" in \ | ||||||||||||||||
| amd64) ARCH=x86_64 ;; \ | ||||||||||||||||
| arm64) ARCH=aarch64 ;; \ | ||||||||||||||||
| *) echo "unsupported TARGETARCH: $TARGETARCH" >&2; exit 1 ;; \ | ||||||||||||||||
| esac \ | ||||||||||||||||
| && curl -fsSL -o /tmp/tower.tar.xz \ | ||||||||||||||||
| "https://github.com/tower/tower-cli/releases/download/v${VERSION}/tower-${ARCH}-unknown-linux-musl.tar.xz" \ | ||||||||||||||||
| && mkdir -p /out \ | ||||||||||||||||
| && tar -xJf /tmp/tower.tar.xz -C /out --strip-components=1 \ | ||||||||||||||||
| && chmod +x /out/tower | ||||||||||||||||
|
|
||||||||||||||||
| FROM gcr.io/distroless/static-debian12 | ||||||||||||||||
| COPY --from=fetch /out/tower /usr/local/bin/tower | ||||||||||||||||
| ENTRYPOINT ["/usr/local/bin/tower"] | ||||||||||||||||
|
Comment on lines
+16
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Yes, gcr.io/distroless/static-debian12 (the latest tag) runs as root (UID 0) by default. The image has variants including :nonroot, which sets the default user to the nonroot user with UID/GID 65532. The recommended non-root UID/GID for distroless static images is 65532:65532, corresponding to the built-in nonroot user. This is the standard unprivileged user provided in all distroless images for running containers securely without root privileges. Users can also use nobody (UID/GID 65534), but nonroot is the specifically recommended one via the :nonroot tag. To use it, either pull gcr.io/distroless/static-debian12:nonroot or add USER nonroot (or USER 65532:65532) in your Dockerfile when basing on the root variant. Citations:
Run the container as non-root. Line 16 uses Suggested fix FROM gcr.io/distroless/static-debian12
COPY --from=fetch /out/tower /usr/local/bin/tower
+USER 65532:65532
ENTRYPOINT ["/usr/local/bin/tower"]📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
In cargo-dist release manifests, isannouncement_tagguaranteed to include avprefix, or can it be plain semver like1.2.3?💡 Result:
In cargo-dist release manifests, announcement_tag is not guaranteed to include a v prefix and can be plain semver like 1.2.3. The field announcement_tag in DistManifest is an Option described as "The (git) tag associated with this announcement". Cargo-dist's tag parsing is permissive: it matches git tags using the regex ^[0-9]+.[0-9]+.[0-9]+*, which captures plain semver versions like 1.2.3 without a v prefix. Official docs and examples emphasize conventional formats like v1.0.0 or my-app-v1.0.0, but a key PR (
#346) explicitly made parsing more flexible: "The 'v' prefix on a version is now optional". Supported formats include: - v1.0.0 - 1.0.0 - package-name-v1.0.0 - package-name-1.0.0 - package-name/v1.0.0 - package-name/1.0.0 Thus, plain semver like 1.2.3 is valid, and announcement_tag will reflect whatever git tag triggered the release or was passed via --tag.Citations:
🏁 Script executed:
Repository: tower/tower-cli
Length of output: 69
🏁 Script executed:
Repository: tower/tower-cli
Length of output: 41
🏁 Script executed:
Repository: tower/tower-cli
Length of output: 851
🏁 Script executed:
Repository: tower/tower-cli
Length of output: 739
🏁 Script executed:
git tag --list | tail -20Repository: tower/tower-cli
Length of output: 41
Avoid
vstripping/reconstruction mismatch for release asset lookup.Line 35 strips
vfromTAG(the announcement_tag from cargo-dist), while the Dockerfile hardcodesv${VERSION}in the release download URL (Dockerfile line 11). Since cargo-dist allows plain semver tags like1.2.3(withoutvprefix), a release created with a non-prefixed tag would cause the Docker build to fail—it would request/download/v1.2.3/when assets are actually at/download/1.2.3/.Pass the original tag value to the Dockerfile so it uses the exact release tag format:
Suggested fix
In Dockerfile:
🤖 Prompt for AI Agents