-
-
Notifications
You must be signed in to change notification settings - Fork 71
Add reusable actions for native BuildKit build in GHA #273
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
Merged
+485
−1
Merged
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
24bbd9f
Add reusable workflow for native BuildKit build in GHA
sairon 75583a2
Use dashes instead of underscores in inputs
sairon 677f4d3
Move actions to actions folder
sairon 7a7fab5
Improve (multi-)arch validation, fix cache-from tag
sairon f1b88d0
Address review comments - remove platform, adjust output argument
sairon 89b3247
Make gha cache configurable
sairon 2335ceb
Add 'load' input and default to false
sairon 28a77db
Don't set any output if image is not pushed nor loaded
sairon 433b20d
Change builder workflow name
sairon 78b43ea
Specify required and defaults in cosign-verify
sairon e93d246
Docker registry -> container registry, context description update
sairon 88a0820
Sort inputs alphabetically, rename to keep semantic clustering
sairon ea75d5e
Merge image tags into a single argument
sairon 8d2380f
Fix container-(username|password) -> container-registry-(username|pas…
sairon a5d42ec
Drop builder workflow, create prepare-multi-arch-matrix and publish-m…
sairon 52b5620
Set default registry-prefix
sairon e5d272b
Print matrix at the end of prepare-multi-arch-matrix
sairon c711632
Set dynamic arch/repo/version labels in build-image action, add label…
sairon 48c5edc
Reintroduce BUILD_VERSION
sairon 4a7d1db
Bump to docker/login-action v4.0.0 (as in #274)
sairon 69243fc
Use imagetools metadata-file as source for digest when signing manifest
sairon eee43c8
Adjust build-image description
sairon 2426beb
Set same params for output type=image and type=docker
sairon 832e03b
Default context in build-image
sairon 65f3e36
Drop prepare-multi-arch-matrix multi-arch boolean, simplify logic
sairon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,248 @@ | ||
| name: Home Assistant multi-arch image builder | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| architectures: | ||
| description: Architectures to build (JSON array, e.g., '["amd64", "aarch64"]') | ||
| required: true | ||
| type: string | ||
| multi-arch: | ||
| description: Prefix per-arch image names with architecture (required for multiple architectures) | ||
| required: false | ||
| default: true | ||
| type: boolean | ||
| registry-prefix: | ||
| description: Registry and namespace prefix (e.g., "ghcr.io/owner") | ||
| required: true | ||
| type: string | ||
| image-name: | ||
| description: Image name without a tag (e.g., "base-python") | ||
| required: true | ||
| type: string | ||
| image-tag: | ||
| description: Base image tag (e.g., "3.23") | ||
| required: true | ||
| type: string | ||
| image-extra-tags: | ||
| description: Additional tags, one per line | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| context: | ||
| description: Build context (usually the directory with Dockerfile) | ||
| required: true | ||
| type: string | ||
| file: | ||
| description: Dockerfile path (defaults to "Dockerfile" in the context directory) | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| version: | ||
| description: Image version label | ||
| required: true | ||
| type: string | ||
| build-args: | ||
| description: Additional build arguments (key=value format, one per line) | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| push: | ||
| description: Whether to push images to registry | ||
| required: false | ||
| default: false | ||
| type: boolean | ||
| cache-gha: | ||
| description: Whether to use GitHub Actions cache for build caching | ||
| required: false | ||
| default: true | ||
| type: boolean | ||
| cache-scope: | ||
| description: Scope for build cache sharing (defaults to architecture, set if building multiple images from a single repo) | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| cache-image-tag: | ||
| description: Tag of the image containing BuildKit inline cache metadata | ||
| required: false | ||
| default: "latest" | ||
| type: string | ||
| cosign: | ||
| description: Whether to sign images with Cosign | ||
| required: false | ||
| default: true | ||
| type: boolean | ||
| cosign-identity: | ||
| description: Certificate identity regexp for verifying cache images (defaults to current repo pattern) | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| cosign-issuer: | ||
| description: Certificate OIDC issuer regexp for all cosign verification | ||
| required: false | ||
| default: "https://token.actions.githubusercontent.com" | ||
| type: string | ||
| verify-base: | ||
| description: Base image reference to verify with cosign before building | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| cosign-base-identity: | ||
| description: Certificate identity regexp for verifying the base (FROM) image | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| cosign-base-issuer: | ||
| description: Certificate OIDC issuer regexp for base image verification (defaults to cosign-issuer) | ||
| required: false | ||
| default: "" | ||
| type: string | ||
|
|
||
| jobs: | ||
| prepare: | ||
| name: Prepare build matrix | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| matrix: ${{ steps.set-matrix.outputs.matrix }} | ||
| steps: | ||
| - name: Build matrix from architectures | ||
| id: set-matrix | ||
| shell: bash | ||
| env: | ||
| ARCHITECTURES: ${{ inputs.architectures }} | ||
| MULTI_ARCH: ${{ inputs.multi-arch }} | ||
| run: | | ||
| arch_count=$(jq 'length' <<< "${ARCHITECTURES}") | ||
| if [[ "${MULTI_ARCH}" != "true" ]] && (( arch_count > 1 )); then | ||
| echo "::error::multi-arch is false but ${arch_count} architectures were specified; use multi-arch: true or pass a single architecture" | ||
| exit 1 | ||
| fi | ||
|
|
||
| invalid_arches=$(jq -r '[.[] | select(. != "amd64" and . != "aarch64")] | unique | join(", ")' <<< "${ARCHITECTURES}") | ||
| if [[ -n "${invalid_arches}" ]]; then | ||
| echo "::error::Unsupported architecture(s): ${invalid_arches}. Supported values: amd64, aarch64" | ||
| exit 1 | ||
| fi | ||
|
|
||
| matrix=$(jq -c '{include: [.[] | | ||
| if . == "amd64" then {arch: "amd64", os: "ubuntu-24.04"} | ||
| elif . == "aarch64" then {arch: "aarch64", os: "ubuntu-24.04-arm"} | ||
| end | ||
| ]}' <<< "${ARCHITECTURES}") | ||
| echo "matrix=${matrix}" >> "$GITHUB_OUTPUT" | ||
|
|
||
| build: | ||
| name: Build ${{ matrix.arch }} image | ||
| needs: prepare | ||
| runs-on: ${{ matrix.os }} | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| packages: write | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJSON(needs.prepare.outputs.matrix) }} | ||
| steps: | ||
| - name: Checkout the repository | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Compute image name | ||
| id: image | ||
| shell: bash | ||
| env: | ||
| REGISTRY_PREFIX: ${{ inputs.registry-prefix }} | ||
| IMAGE_NAME: ${{ inputs.image-name }} | ||
| ARCH: ${{ matrix.arch }} | ||
| MULTI_ARCH: ${{ inputs.multi-arch }} | ||
| run: | | ||
| if [[ "${MULTI_ARCH}" == "true" ]]; then | ||
| image="${REGISTRY_PREFIX}/${ARCH}-${IMAGE_NAME}" | ||
| else | ||
| image="${REGISTRY_PREFIX}/${IMAGE_NAME}" | ||
| fi | ||
| echo "name=${image}" >> "$GITHUB_OUTPUT" | ||
agners marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| - name: Build image | ||
| id: build | ||
| uses: home-assistant/builder/actions/build-image@gha-builder | ||
sairon marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| with: | ||
| image: ${{ steps.image.outputs.name }} | ||
| image-tag: ${{ inputs.image-tag }} | ||
| image-extra-tags: ${{ inputs.image-extra-tags }} | ||
| arch: ${{ matrix.arch }} | ||
| push: ${{ inputs.push }} | ||
| cache-gha: ${{ inputs.cache-gha }} | ||
| cache-scope: ${{ inputs.cache-scope }} | ||
| cache-image-tag: ${{ inputs.cache-image-tag }} | ||
| docker-password: ${{ secrets.GITHUB_TOKEN }} | ||
| context: ${{ inputs.context }} | ||
| file: ${{ inputs.file }} | ||
| version: ${{ inputs.version }} | ||
| build-args: ${{ inputs.build-args }} | ||
| cosign: ${{ inputs.cosign }} | ||
| cosign-identity: ${{ inputs.cosign-identity }} | ||
| cosign-base-identity: ${{ inputs.cosign-base-identity }} | ||
| cosign-issuer: ${{ inputs.cosign-issuer }} | ||
| cosign-base-issuer: ${{ inputs.cosign-base-issuer }} | ||
| verify-base: ${{ inputs.verify-base }} | ||
agners marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| manifest: | ||
| name: Publish multi-arch manifest | ||
| if: inputs.push && inputs.multi-arch | ||
| needs: [prepare, build] | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| packages: write | ||
| steps: | ||
| - name: Login to GitHub Container Registry | ||
| uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.repository_owner }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 | ||
|
|
||
| - name: Install Cosign | ||
| uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 | ||
| if: inputs.cosign | ||
| with: | ||
| cosign-release: "v2.5.3" | ||
|
|
||
| - name: Create multi-arch manifest and sign it | ||
| shell: bash | ||
| env: | ||
| ARCHITECTURES: ${{ inputs.architectures }} | ||
| REGISTRY_PREFIX: ${{ inputs.registry-prefix }} | ||
| IMAGE_NAME: ${{ inputs.image-name }} | ||
| IMAGE_TAG: ${{ inputs.image-tag }} | ||
| IMAGE_EXTRA_TAGS: ${{ inputs.image-extra-tags }} | ||
| COSIGN: ${{ inputs.cosign }} | ||
| run: | | ||
| source_images=() | ||
| for arch in $(jq -r '.[]' <<< "${ARCHITECTURES}"); do | ||
| source_images+=("${REGISTRY_PREFIX}/${arch}-${IMAGE_NAME}:${IMAGE_TAG}") | ||
| done | ||
|
|
||
| tags=("${REGISTRY_PREFIX}/${IMAGE_NAME}:${IMAGE_TAG}") | ||
| while IFS= read -r tag; do | ||
| [[ -n "$tag" ]] && tags+=("${REGISTRY_PREFIX}/${IMAGE_NAME}:${tag}") | ||
| done <<< "${IMAGE_EXTRA_TAGS}" | ||
|
|
||
| tag_args=() | ||
| for tag in "${tags[@]}"; do | ||
| tag_args+=("--tag" "${tag}") | ||
| done | ||
|
|
||
| docker buildx imagetools create "${tag_args[@]}" "${source_images[@]}" | ||
|
|
||
| if [[ "${COSIGN}" == "true" ]]; then | ||
| # All tags for the manifest point to the same digest, get digest from the first tag | ||
| digest=$(skopeo inspect --raw --no-tags "docker://${tags[0]}" | skopeo manifest-digest /dev/stdin) | ||
| cosign sign --yes "${REGISTRY_PREFIX}/${IMAGE_NAME}@${digest}" | ||
| fi | ||
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.