Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions .github/workflows/build-go-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ on:
type: string
required: true
version:
description: Version injected into the binary, i.e. the tag the release is cut from
description: >-
Version injected into the binary. Defaults, on a tag push, to the tag without its leading
"v" — the string GoReleaser injects, so an image never disagrees with the binary cut from
the same tag. Left empty on any other trigger, so the Dockerfile's own fallback stands.
type: string
required: true
required: false
version-build-arg:
description: >-
Name of the Dockerfile ARG the version is passed to, i.e. "SPECS_VERSION". The Dockerfile
Expand Down Expand Up @@ -69,7 +72,24 @@ on:

jobs:

version:
name: Version
runs-on: ${{ inputs.runs-on }}
outputs:
value: ${{ steps.resolve.outputs.value }}
steps:
- id: resolve
env:
GIVEN: ${{ inputs.version }}
run: |
value="$GIVEN"
if [ -z "$value" ] && [ "$GITHUB_REF_TYPE" = tag ]; then
value="${GITHUB_REF_NAME#v}"
fi
echo "value=$value" >> "$GITHUB_OUTPUT"

build:
needs: version
uses: ./.github/workflows/build.yml
with:
runs-on: ${{ inputs.runs-on }}
Expand All @@ -83,6 +103,8 @@ jobs:
secrets: ${{ inputs.secrets }}
push: ${{ inputs.push }}
disable-apparmor: ${{ inputs.disable-apparmor }}
# Omitted entirely when there is no version, rather than passed empty:
# an empty ARG would override the Dockerfile's fallback with nothing.
build-args: |
${{ inputs.version-build-arg }}=${{ inputs.version }}
${{ needs.version.outputs.value != '' && format('{0}={1}', inputs.version-build-arg, needs.version.outputs.value) || '' }}
${{ inputs.build-args }}
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
uses: docker/setup-buildx-action@v4

- name: Build and Push by digest
uses: specsnl/github-actions/build-image@2.3.0
uses: specsnl/github-actions/build-image@2.4.0
with:
dockerfile: ${{ inputs.dockerfile }}
context: ${{ inputs.context }}
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/merge-go-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ on:
type: string
required: false
version:
description: Value for org.opencontainers.image.version
description: >-
Overrides org.opencontainers.image.version. Rarely needed — metadata-action already sets
that label to the version it computed, i.e. "1.2.3" for a "v1.2.3" tag.
type: string
required: false
title:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
uses: docker/setup-buildx-action@v4

- name: Create Manifest
uses: specsnl/github-actions/create-manifest@2.3.0
uses: specsnl/github-actions/create-manifest@2.4.0
with:
image-name: ${{ steps.image_name.outputs.lowercase }}
target: ${{ inputs.target }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This repository contains the Specsnl organisation collection of GitHub Actions workflows and composite actions that can
be reused to automate various tasks in GitHub repositories.

Consumers pin by tag, i.e. `specsnl/github-actions/.github/workflows/build.yml@2.3.0`.
Consumers pin by tag, i.e. `specsnl/github-actions/.github/workflows/build.yml@2.4.0`.

## What is in here

Expand Down
4 changes: 2 additions & 2 deletions docs/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Both assume the job has already checked out, logged in to the registry and set u
## `build-image`

```yaml
- uses: specsnl/github-actions/build-image@2.3.0
- uses: specsnl/github-actions/build-image@2.4.0
```

| Input | Default | Description |
Expand Down Expand Up @@ -42,7 +42,7 @@ about conflicting outputs. With `load` on, the digest export and artifact upload
## `create-manifest`

```yaml
- uses: specsnl/github-actions/create-manifest@2.3.0
- uses: specsnl/github-actions/create-manifest@2.4.0
```

| Input | Default | Description |
Expand Down
37 changes: 23 additions & 14 deletions docs/go-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ permissions:
jobs:

build:
uses: specsnl/github-actions/.github/workflows/build-go-cli.yml@2.3.0
uses: specsnl/github-actions/.github/workflows/build-go-cli.yml@2.4.0
strategy:
fail-fast: false
matrix:
Expand All @@ -35,17 +35,15 @@ jobs:
platform: ${{ matrix.runner.platform }}
image-name: ghcr.io/specsnl/specs-cli
target: debian
version: ${{ github.ref_name }}
version-build-arg: SPECS_VERSION

merge:
needs: build
uses: specsnl/github-actions/.github/workflows/merge-go-cli.yml@2.3.0
uses: specsnl/github-actions/.github/workflows/merge-go-cli.yml@2.4.0
with:
runs-on: ubuntu-24.04
image-name: ghcr.io/specsnl/specs-cli
target: debian
version: ${{ github.ref_name }}
```

`target` is the Dockerfile stage to publish. The consuming repository owns its stages — see
Expand All @@ -54,8 +52,8 @@ jobs:
## Version injection

Go CLIs carry their version in an ldflag, so it has to be known at build time or the image reports its fallback
(`dev`). `build-go-cli.yml` passes `version` to the Dockerfile as the build arg named by `version-build-arg`; the
Dockerfile keeps ownership of the ldflag itself, which is how every Go repository in the org is already written:
(`dev`). `build-go-cli.yml` passes it to the Dockerfile as the build arg named by `version-build-arg`; the Dockerfile
keeps ownership of the ldflag itself, which is how every Go repository in the org is already written:

```dockerfile
ARG GO_MODULE=github.com/specsnl/specs-cli
Expand All @@ -65,13 +63,26 @@ RUN CGO_ENABLED=0 go build \
-ldflags "-s -w -X ${GO_MODULE}/internal/cmd.Version=${SPECS_VERSION}" -o ./specs
```

`version-build-arg` has no default on purpose. The arg is named after the binary and differs per repository
(`SPECS_VERSION`, `LABELSYNC_VERSION`, …), and a wrong value fails silently: buildx warns about an unused build arg,
the build succeeds, and the image reports `dev`. Assert the version in a
[pull-request guard](testing-images.md) so that stays impossible to ship.
On a tag push the version defaults to **the tag without its leading `v`** — `v1.2.3` becomes `1.2.3` — so the
examples above pass no `version` at all. That default is not cosmetic. Every Go repository in the org also releases
through GoReleaser, which strips the `v` when it injects the same ldflag; passing `${{ github.ref_name }}` straight
through would publish an image reporting `v1.2.3` while the binary from that very tag reports `1.2.3`.

Pass `version` explicitly to override it — to build a release from something other than its tag, or to stamp a version
on a branch build. On any trigger that is not a tag push the default is empty, and the build arg is then omitted
rather than passed empty, so the Dockerfile's own fallback stands.

`version-build-arg` has no default on purpose, and is the one input here that genuinely cannot have one. The arg is
named after the binary and differs per repository (`SPECS_VERSION`, `LABELSYNC_VERSION`, …), and a wrong value fails
silently: buildx warns about an unused build arg, the build succeeds, and the image reports `dev`. Assert the version
in a [pull-request guard](testing-images.md) so that stays impossible to ship.

Anything else the Dockerfile needs goes through `build-args`, which is appended to the version arg.

`merge-go-cli.yml` needs no `version` either: `metadata-action` already labels the image
`org.opencontainers.image.version` with the version it computed. The input is there to override that, which is rarely
what anyone wants.

## Tags

On top of what [`merge.yml` already emits](pipeline.md#tags):
Expand Down Expand Up @@ -107,7 +118,7 @@ Run the build and merge jobs once per variant, each with its own `target`:

```yaml
build-alpine:
uses: specsnl/github-actions/.github/workflows/build-go-cli.yml@2.3.0
uses: specsnl/github-actions/.github/workflows/build-go-cli.yml@2.4.0
strategy:
fail-fast: false
matrix:
Expand All @@ -121,18 +132,16 @@ Run the build and merge jobs once per variant, each with its own `target`:
platform: ${{ matrix.runner.platform }}
image-name: ghcr.io/specsnl/specs-cli
target: alpine
version: ${{ github.ref_name }}
version-build-arg: SPECS_VERSION

merge-alpine:
needs: build-alpine
uses: specsnl/github-actions/.github/workflows/merge-go-cli.yml@2.3.0
uses: specsnl/github-actions/.github/workflows/merge-go-cli.yml@2.4.0
with:
runs-on: ubuntu-24.04
image-name: ghcr.io/specsnl/specs-cli
target: alpine
variant: alpine
version: ${{ github.ref_name }}
```

`variant: alpine` yields `specs-cli:1.2.3-alpine` and a bare `specs-cli:alpine`, alongside the unsuffixed primary
Expand Down
4 changes: 2 additions & 2 deletions docs/php.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ what name.
jobs:

build:
uses: specsnl/github-actions/.github/workflows/build-php.yml@2.3.0
uses: specsnl/github-actions/.github/workflows/build-php.yml@2.4.0
strategy:
fail-fast: false
matrix:
Expand All @@ -24,7 +24,7 @@ jobs:

merge:
needs: build
uses: specsnl/github-actions/.github/workflows/merge-php.yml@2.3.0
uses: specsnl/github-actions/.github/workflows/merge-php.yml@2.4.0
with:
runs-on: ubuntu-24.04
image-name: ghcr.io/${{ github.repository }}
Expand Down
2 changes: 1 addition & 1 deletion docs/testing-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- uses: docker/setup-buildx-action@v4

- id: build
uses: specsnl/github-actions/build-image@2.3.0
uses: specsnl/github-actions/build-image@2.4.0
with:
platform: linux/amd64
image-name: ghcr.io/specsnl/specs-cli
Expand Down