From a59a230b91219181cf2c5b788eff52ae6b7d5715 Mon Sep 17 00:00:00 2001 From: Allison Thackston <6098197+athackst@users.noreply.github.com> Date: Fri, 27 Mar 2026 00:39:44 -0700 Subject: [PATCH 1/2] Try to fix docker bake again --- .github/actions/docker-bake/action.yml | 29 +++++-------------- .github/actions/docker-bake/get_variables.py | 18 ++++++++---- .../docker-bake/tests/test_get_variables.py | 2 +- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/.github/actions/docker-bake/action.yml b/.github/actions/docker-bake/action.yml index 5cfb8b6f..2f14ba43 100644 --- a/.github/actions/docker-bake/action.yml +++ b/.github/actions/docker-bake/action.yml @@ -60,25 +60,11 @@ runs: shell: bash run: | set -euo pipefail - ghcr_login_user="${{ inputs.ghcr-username }}" - if [[ -z "$ghcr_login_user" ]]; then - ghcr_login_user="${{ github.actor }}" - fi - ghcr_owner="${{ inputs.ghcr-username }}" - # Dependabot usernames include brackets (e.g. dependabot[bot]) which are - # invalid in image/cache references; fall back to repo owner namespace. - if [[ -z "$ghcr_owner" || "$ghcr_owner" == *"["* || "$ghcr_owner" == *"]"* ]]; then - ghcr_owner="${{ github.repository_owner }}" - fi - ghcr_owner="$(printf '%s' "$ghcr_owner" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9._-]+/-/g; s/^-+//; s/-+$//')" - if [[ -z "$ghcr_owner" ]]; then - ghcr_owner="$(printf '%s' "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9._-]+/-/g; s/^-+//; s/-+$//')" - fi + ghcr_owner="${{ github.repository_owner }}" family="${{ inputs.family }}" distro="${{ inputs.distro }}" - echo "ghcr_login_user=$ghcr_login_user" >> "$GITHUB_OUTPUT" echo "ghcr_owner=$ghcr_owner" >> "$GITHUB_OUTPUT" echo "family=${family,,}" >> "$GITHUB_OUTPUT" echo "distro=${distro,,}" >> "$GITHUB_OUTPUT" @@ -91,11 +77,11 @@ runs: password: ${{ inputs.docker-password }} - name: Log in to GHCR - if: ${{ inputs.ghcr-password && steps.refs.outputs.ghcr_login_user }} + if: ${{ inputs.ghcr-username && inputs.ghcr-password }} uses: docker/login-action@v3 with: registry: ghcr.io - username: ${{ steps.refs.outputs.ghcr_login_user }} + username: ${{ inputs.ghcr-username }} password: ${{ inputs.ghcr-password }} - name: Set up Python @@ -131,7 +117,7 @@ runs: --family "${{ inputs.family }}" --distro "${{ inputs.distro }}" --platform "${{ steps.detect.outputs.platform }}" - ${{ inputs.ghcr-password && format('--ghcr-username "{0}"', steps.refs.outputs.ghcr_owner) || '' }} + ${{ inputs.ghcr-password && format('--ghcr-owner "{0}"', steps.refs.outputs.ghcr_owner) || '' }} ${{ inputs.docker-password && format('--docker-username "{0}"', inputs.docker-username) || '' }} ${{ inputs.push == 'true' && '--digest' || '' }} ) @@ -147,7 +133,7 @@ runs: push: ${{ inputs.push }} set: | ${{ steps.gen.outputs.release }}-*.platform=${{ steps.detect.outputs.platform }} - *.cache-to=type=gha,mode=max,scope=${{ steps.gen.outputs.group }} + ${{ inputs.push == 'true' && format('*.cache-to=type=gha,mode=max,scope={0},ignore-error=true', steps.gen.outputs.group) || format('*.cache-to=type=gha,mode=min,scope={0},ignore-error=true', steps.gen.outputs.group) }} *.cache-from=type=gha,scope=${{ steps.gen.outputs.group }} ${{ (inputs.push == 'true' && inputs.ghcr-password && steps.refs.outputs.ghcr_owner) && format('*.cache-to=type=registry,ref=ghcr.io/{0}/{1}:{2}-{3}-buildcache,mode=max', steps.refs.outputs.ghcr_owner, steps.refs.outputs.family, steps.refs.outputs.distro, steps.detect.outputs.platform_key) || '' }} ${{ (inputs.ghcr-password && steps.refs.outputs.ghcr_owner) && format('*.cache-from=type=registry,ref=ghcr.io/{0}/{1}:{2}-{3}-buildcache', steps.refs.outputs.ghcr_owner, steps.refs.outputs.family, steps.refs.outputs.distro, steps.detect.outputs.platform_key) || '' }} @@ -161,8 +147,9 @@ runs: meta_dir="${{ github.workspace }}/.tmp" mkdir -p "$meta_dir" meta_file="bake-metadata-${{ inputs.family }}-${{ inputs.distro }}-${{ steps.detect.outputs.platform_key }}.json" - metadata='${{ steps.bake.outputs.metadata }}' - printf '%s' "$metadata" > "$meta_dir/$meta_file" + cat > "$meta_dir/$meta_file" <<'__DOCKER_BAKE_METADATA__' + ${{ steps.bake.outputs.metadata }} + __DOCKER_BAKE_METADATA__ echo "metadata_path=$meta_dir/$meta_file" >> "$GITHUB_OUTPUT" echo "Saved $meta_file ($(wc -c < "$meta_dir/$meta_file") bytes)" diff --git a/.github/actions/docker-bake/get_variables.py b/.github/actions/docker-bake/get_variables.py index 0eb27ee9..bcc566e3 100755 --- a/.github/actions/docker-bake/get_variables.py +++ b/.github/actions/docker-bake/get_variables.py @@ -11,7 +11,7 @@ --family ros2 \ --distro rolling \ --platform linux/amd64 \ - --ghcr-username \ + --ghcr-owner \ --docker-username \ --digest @@ -142,7 +142,15 @@ def main() -> int: help="Docker platform os/arch[/variant] (e.g., linux/amd64).", ) parser.add_argument( - "--ghcr-username", default="", help="GHCR owner/org for final tags." + "--ghcr-owner", + dest="ghcr_owner", + default="", + help="GHCR owner/org for final tags.", + ) + parser.add_argument( + "--ghcr-username", + dest="ghcr_owner", + help=argparse.SUPPRESS, ) parser.add_argument( "--docker-username", @@ -187,7 +195,7 @@ def main() -> int: stage_targets: list[str] = [] set_lines: list[str] = [] normalized_family = args.family.strip().lower() - normalized_ghcr_user = args.ghcr_username.strip().lower() + normalized_ghcr_owner = args.ghcr_owner.strip().lower() normalized_docker_user = args.docker_username.strip().lower() for tgt in entry.get("targets", []): if not platforms_support(tgt.get("platforms", ""), platform): @@ -198,9 +206,9 @@ def main() -> int: stage_targets.append(tname) destinations: list[str] = [] - if normalized_ghcr_user: + if normalized_ghcr_owner: destinations.append( - f"ghcr.io/{normalized_ghcr_user}/{normalized_family}" + f"ghcr.io/{normalized_ghcr_owner}/{normalized_family}" ) if normalized_docker_user: destinations.append( diff --git a/.github/actions/docker-bake/tests/test_get_variables.py b/.github/actions/docker-bake/tests/test_get_variables.py index 28228cab..4e4115a2 100644 --- a/.github/actions/docker-bake/tests/test_get_variables.py +++ b/.github/actions/docker-bake/tests/test_get_variables.py @@ -75,7 +75,7 @@ def test_main_emits_expected_outputs(self): "rolling", "--platform", "linux/amd64", - "--ghcr-username", + "--ghcr-owner", "GhUser", "--docker-username", "DockerUSER", From 03eeba352b0d65239a8293f0f75b4de4c266ec2b Mon Sep 17 00:00:00 2001 From: Allison Thackston <6098197+athackst@users.noreply.github.com> Date: Fri, 27 Mar 2026 09:45:06 -0700 Subject: [PATCH 2/2] Add optional caching --- .github/actions/docker-bake/README.md | 6 ++++++ .github/actions/docker-bake/action.yml | 8 ++++++-- .github/workflows/test.yml | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/actions/docker-bake/README.md b/.github/actions/docker-bake/README.md index d9185c6d..fc6008e2 100644 --- a/.github/actions/docker-bake/README.md +++ b/.github/actions/docker-bake/README.md @@ -8,6 +8,10 @@ Builds per-platform images from `templates.yml` using `docker buildx bake`, uplo - Runs `docker/bake-action@v6` to build or push the image targets. - Reuses BuildKit cache from GHCR when credentials are provided (while still priming the GitHub Actions cache as a fallback). - Registry cache export is enabled only when `push=true`. + - GHA cache behavior is configurable via `gha-cache`: + - `all`: enable GHA cache import and export + - `from`: enable only GHA cache import + - `none`: disable GHA cache import and export - GHCR cache/image namespace parts are normalized for valid registry references. - Persists the bake metadata as an artifact so the merge job can create multi-arch manifests. @@ -19,6 +23,7 @@ Builds per-platform images from `templates.yml` using `docker buildx bake`, uplo | `platform` | | Override build platform (`os/arch[/variant]`). Defaults to daemon platform. | | `docker-username` / `docker-password` | | Docker Hub credentials used for `docker login`. | | `ghcr-username` / `ghcr-password` | | GHCR credentials used for `docker login`. | +| `gha-cache` | | `all` (default), `from`, or `none` for GHA cache mode. | | `push` | | Set to `false` to skip pushing digests (defaults to `true`). | ## Outputs @@ -40,6 +45,7 @@ Builds per-platform images from `templates.yml` using `docker buildx bake`, uplo platform: linux/amd64 ghcr-username: ${{ github.repository_owner }} ghcr-password: ${{ secrets.GITHUB_TOKEN }} + gha-cache: all push: ${{ github.ref == 'refs/heads/main' }} ``` diff --git a/.github/actions/docker-bake/action.yml b/.github/actions/docker-bake/action.yml index 2f14ba43..cec6671b 100644 --- a/.github/actions/docker-bake/action.yml +++ b/.github/actions/docker-bake/action.yml @@ -31,6 +31,10 @@ inputs: description: "Push digests to registry" default: "true" required: false + gha-cache: + description: "GitHub Actions cache mode: all|none|from" + default: "all" + required: false outputs: platform: @@ -133,8 +137,8 @@ runs: push: ${{ inputs.push }} set: | ${{ steps.gen.outputs.release }}-*.platform=${{ steps.detect.outputs.platform }} - ${{ inputs.push == 'true' && format('*.cache-to=type=gha,mode=max,scope={0},ignore-error=true', steps.gen.outputs.group) || format('*.cache-to=type=gha,mode=min,scope={0},ignore-error=true', steps.gen.outputs.group) }} - *.cache-from=type=gha,scope=${{ steps.gen.outputs.group }} + ${{ inputs.gha-cache == 'all' && (inputs.push == 'true' && format('*.cache-to=type=gha,mode=max,scope={0},ignore-error=true', steps.gen.outputs.group) || format('*.cache-to=type=gha,mode=min,scope={0},ignore-error=true', steps.gen.outputs.group)) || '' }} + ${{ (inputs.gha-cache == 'all' || inputs.gha-cache == 'from') && format('*.cache-from=type=gha,scope={0}', steps.gen.outputs.group) || '' }} ${{ (inputs.push == 'true' && inputs.ghcr-password && steps.refs.outputs.ghcr_owner) && format('*.cache-to=type=registry,ref=ghcr.io/{0}/{1}:{2}-{3}-buildcache,mode=max', steps.refs.outputs.ghcr_owner, steps.refs.outputs.family, steps.refs.outputs.distro, steps.detect.outputs.platform_key) || '' }} ${{ (inputs.ghcr-password && steps.refs.outputs.ghcr_owner) && format('*.cache-from=type=registry,ref=ghcr.io/{0}/{1}:{2}-{3}-buildcache', steps.refs.outputs.ghcr_owner, steps.refs.outputs.family, steps.refs.outputs.distro, steps.detect.outputs.platform_key) || '' }} ${{ steps.gen.outputs.set_lines }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1dbd7414..3537d863 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -127,6 +127,7 @@ jobs: distro: ${{ matrix.distro }} # e.g. rolling ghcr-username: ${{ github.actor }} # optional ghcr-password: ${{ secrets.GITHUB_TOKEN }} # optional + gha-cache: ${{ contains(matrix.distro, 'cuda') && 'from' || 'all' }} push: "false" bake-build-arm64: @@ -149,6 +150,7 @@ jobs: distro: ${{ matrix.distro }} # e.g. rolling ghcr-username: ${{ github.actor }} # optional ghcr-password: ${{ secrets.GITHUB_TOKEN }} # optional + gha-cache: ${{ contains(matrix.distro, 'cuda') && 'from' || 'all' }} push: "false" merge-manifests: