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
213 changes: 213 additions & 0 deletions .github/workflows/buildkit-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
name: Build & Push BuildKit Docker Image

on:
workflow_dispatch:
inputs:
version:
description: 'Version tag for the BuildKit image (e.g., v1.0.0)'
required: true
type: string
push_latest:
description: 'Also tag as latest'
required: false
type: boolean
default: false

jobs:
prepare-metadata:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.meta.outputs.version }}
major: ${{ steps.meta.outputs.major }}
major_minor: ${{ steps.meta.outputs.major_minor }}
tags_suffix: ${{ steps.tags.outputs.tags_suffix }}
steps:
- name: Validate inputs
run: |
VERSION="${{ github.event.inputs.version }}"

if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: version must be in format v1.2.3"
exit 1
fi

- name: Extract metadata
id: meta
run: |
VERSION="${{ github.event.inputs.version }}"
echo "version=$VERSION" >> $GITHUB_OUTPUT

if [[ "$VERSION" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
MAJOR="v${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
MAJOR_MINOR="v${BASH_REMATCH[1]}.${MINOR}"
echo "major=$MAJOR" >> $GITHUB_OUTPUT
echo "major_minor=$MAJOR_MINOR" >> $GITHUB_OUTPUT
fi

- name: Determine Docker tags
id: tags
run: |
TAGS_SUFFIX="${{ steps.meta.outputs.version }}"
TAGS_SUFFIX="$TAGS_SUFFIX,${{ steps.meta.outputs.major }}"
TAGS_SUFFIX="$TAGS_SUFFIX,${{ steps.meta.outputs.major_minor }}"

if [[ "${{ github.event.inputs.push_latest }}" == "true" ]]; then
TAGS_SUFFIX="$TAGS_SUFFIX,latest"
fi

echo "tags_suffix=$TAGS_SUFFIX" >> $GITHUB_OUTPUT

build-amd64:
runs-on: ubuntu-latest
needs: prepare-metadata
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
buildkitd-flags: --debug

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push AMD64 image
id: build
uses: docker/build-push-action@v6
with:
context: .
file: buildkit.Dockerfile
platforms: linux/amd64
outputs: type=image,name=lifecycleoss/buildkit,push-by-digest=true,name-canonical=true,push=true
cache-from: type=registry,ref=lifecycleoss/buildkit:buildcache-amd64
cache-to: type=registry,ref=lifecycleoss/buildkit:buildcache-amd64,mode=max

- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"

- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-amd64
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

build-arm64:
runs-on: ubuntu-latest
needs: prepare-metadata
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
buildkitd-flags: --debug

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push ARM64 image
id: build
uses: docker/build-push-action@v6
with:
context: .
file: buildkit.Dockerfile
platforms: linux/arm64
outputs: type=image,name=lifecycleoss/buildkit,push-by-digest=true,name-canonical=true,push=true
cache-from: type=registry,ref=lifecycleoss/buildkit:buildcache-arm64
cache-to: type=registry,ref=lifecycleoss/buildkit:buildcache-arm64,mode=max

- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"

- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-arm64
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge-and-push:
runs-on: ubuntu-latest
needs:
- prepare-metadata
- build-amd64
- build-arm64
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Create manifest list and push
env:
TAGS_SUFFIX: ${{ needs.prepare-metadata.outputs.tags_suffix }}
run: |
AMD64_DIGEST=$(find /tmp/digests/digests-amd64 -type f | head -1)
ARM64_DIGEST=$(find /tmp/digests/digests-arm64 -type f | head -1)

AMD64_SHA=$(basename "$AMD64_DIGEST")
ARM64_SHA=$(basename "$ARM64_DIGEST")

DIGESTS="lifecycleoss/buildkit@sha256:$AMD64_SHA lifecycleoss/buildkit@sha256:$ARM64_SHA"

IFS=',' read -ra TAG_ARRAY <<< "$TAGS_SUFFIX"

for TAG_SUFFIX in "${TAG_ARRAY[@]}"; do
TAG_SUFFIX=$(echo "$TAG_SUFFIX" | xargs)
FULL_TAG="lifecycleoss/buildkit:${TAG_SUFFIX}"
docker buildx imagetools create -t "$FULL_TAG" $DIGESTS
done

- name: Inspect final image
run: |
docker buildx imagetools inspect lifecycleoss/buildkit:${{ needs.prepare-metadata.outputs.version }}

- name: Create GitHub Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: buildkit-${{ needs.prepare-metadata.outputs.version }}
release_name: BuildKit Image ${{ needs.prepare-metadata.outputs.version }}
body: |
BuildKit image release for lifecycle.

Docker Hub: `lifecycleoss/buildkit:${{ needs.prepare-metadata.outputs.version }}`

Tags created:
- `lifecycleoss/buildkit:${{ needs.prepare-metadata.outputs.version }}`
- `lifecycleoss/buildkit:${{ needs.prepare-metadata.outputs.major }}`
- `lifecycleoss/buildkit:${{ needs.prepare-metadata.outputs.major_minor }}`
${{ github.event.inputs.push_latest == 'true' && '- `lifecycleoss/buildkit:latest`' || '' }}
draft: false
prerelease: false
23 changes: 23 additions & 0 deletions buildkit.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2025 GoodRx, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ARG BUILDKIT_VERSION=v0.28.1

FROM golang:1.24-alpine AS builder
RUN go install github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login@v0.12.0

FROM moby/buildkit:${BUILDKIT_VERSION}
COPY --from=builder /go/bin/docker-credential-ecr-login /usr/bin/
RUN mkdir -p /root/.docker && \
echo '{"credsStore":"ecr-login"}' > /root/.docker/config.json
Loading