Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2fcfb68
feat
mlajkim Jan 6, 2026
4c8b12e
fix
mlajkim Jan 6, 2026
f91edf5
feat
mlajkim Jan 6, 2026
ab7a9c6
feat
mlajkim Jan 7, 2026
df7b601
feat
mlajkim Jan 7, 2026
e3f4f41
feat
mlajkim Jan 7, 2026
b79bf6a
fix: regex
mlajkim Jan 7, 2026
4d4f1c5
fix
mlajkim Jan 7, 2026
09faec8
feat
mlajkim Jan 7, 2026
89b976e
feat
mlajkim Jan 7, 2026
b4b0abb
feat
mlajkim Jan 7, 2026
39eb0f8
feat
mlajkim Jan 7, 2026
f3af9a4
feat
mlajkim Jan 7, 2026
4328e89
feat
mlajkim Jan 7, 2026
d62bd99
fix: back
mlajkim Jan 7, 2026
a856477
chore: explicitly define Docker registry URL and image, removing dyna…
mlajkim Jan 7, 2026
0e934df
Merge branch 'master' into feat/add-arm64-supported
mlajkim Jan 7, 2026
cc0666c
feat
mlajkim Jan 7, 2026
714331d
docs: Clarify `BUILD_MATRIX` and musl library copying with comments, …
mlajkim Jan 7, 2026
fbd41c1
feat: Extract Docker build matrix and platform suffixes into a dedica…
mlajkim Jan 7, 2026
fee59f5
feat
mlajkim Jan 7, 2026
cb625d2
feat
mlajkim Jan 7, 2026
a2c9663
fix
mlajkim Jan 7, 2026
8f867bc
build: Switch Docker build-push-action to load images local only
mlajkim Jan 7, 2026
94f0018
feat: Conditionally push Docker images and run merge job based on Git…
mlajkim Jan 7, 2026
e584167
Apply suggestion from @mlajkim
mlajkim Jan 7, 2026
1235343
feat: Build and push Docker images to GitHub Container Registry as an…
mlajkim Jan 8, 2026
74226be
comment
mlajkim Jan 8, 2026
1558b4a
feat: name for step
mlajkim Jan 8, 2026
a608f94
feat
mlajkim Jan 8, 2026
cac68c5
feat
mlajkim Jan 8, 2026
d73e18b
feat: cleaner
mlajkim Jan 8, 2026
6170e00
feat
mlajkim Jan 8, 2026
7f605f0
comment
mlajkim Jan 8, 2026
f91de38
feat
mlajkim Jan 8, 2026
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
253 changes: 177 additions & 76 deletions .github/workflows/docker-build-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,70 @@ on:
branches: [ master ]

env:
DOCKER_BUILDX_PLATFORM: linux/amd64
# https://hub.docker.com/r/athenz/authorization-proxy/tags
DOCKER_REGISTRY_URL: docker.io
DOCKER_REGISTRY_ORG: athenz
DOCKER_REGISTRY_IMAGE: authorization-proxy
# DOCKER_REGISTRY_USER: values for docker login is stored in repository variables
# DOCKER_REGISTRY_TOKEN_NAME: values for docker login is stored in repository variables
TAGS_CONFIG: |
# If branch is master, main or default branch, push the latest tag image:
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}

# If the event is a tag release following the semver regex, push the latest tag image:
# Semver official regex: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
type=match,value=latest,group=0,pattern=^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$

# If it is PR version, push the pr-<pr-number> tag image:
type=ref,event=pr

type=semver,pattern=v{{version}}

# Any cron builds (scheduled workflows) push the nightly tag image:
type=schedule,pattern=nightly


jobs:
build:
set_matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set.outputs.matrix }}
suffixes: ${{ steps.set.outputs.suffixes }}
steps:
- id: set
run: |
# We define BUILD_MATRIX so that we have multiple platform supported,
# maybe Windows as well in the future:

MATRIX_JSON='{
"include": [
{ "platform": "linux/amd64", "runner": "ubuntu-latest", "suffix": "-amd64" },
{ "platform": "linux/arm64", "runner": "ubuntu-24.04-arm", "suffix": "-arm64" }
]
}'

# Store JSON data:
echo "matrix=$(echo "$MATRIX_JSON" | jq -c .)" >> $GITHUB_OUTPUT

# Store Suffix list:
echo "suffixes=$(echo "$MATRIX_JSON" | jq -r '.include[].suffix' | xargs)" >> $GITHUB_OUTPUT

build:
needs: set_matrix
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.set_matrix.outputs.matrix) }}
permissions:
actions: none
checks: none
contents: read
deployments: none
issues: none
discussions: none
packages: none
packages: write # for ghcr read permission
pull-requests: none
repository-projects: none
security-events: none
Expand All @@ -54,16 +102,6 @@ jobs:
# uses: https://github.com/FranzDiebold/github-env-vars-action/tags
uses: FranzDiebold/github-env-vars-action@v2

# A GitHub Action to prepare default environment variables.
-
name: Set Default Environment Variables
id: default_env
run: |
# Use docker.io for Docker Hub if empty
[[ "${{ env.DOCKER_REGISTRY_URL}}" = "" ]] && echo "DOCKER_REGISTRY_URL=docker.io" >> $GITHUB_ENV
[[ "${{ env.DOCKER_REGISTRY_ORG }}" = "" ]] && echo "DOCKER_REGISTRY_ORG=${{ env.CI_REPOSITORY_OWNER }}" >> $GITHUB_ENV
[[ "${{ env.DOCKER_REGISTRY_IMAGE }}" = "" ]] && echo "DOCKER_REGISTRY_IMAGE=${{ env.CI_REPOSITORY_NAME }}" >> $GITHUB_ENV

# This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
# https://github.com/actions/checkout
-
Expand All @@ -84,8 +122,9 @@ jobs:
# uses: https://github.com/actions/setup-go/tags
uses: actions/setup-go@v4
with:
# Fix the following warning: Both go-version and go-version-file inputs are specified, only go-version will be used
go-version: "stable"
go-version-file: './go.mod'
# go-version-file: './go.mod'
cache: true

# A GitHub Action for golang tests
Expand All @@ -101,6 +140,7 @@ jobs:
# https://github.com/apache/skywalking-eyes
# issue: go version hard-coded: https://github.com/apache/skywalking-eyes/blob/5dfa68f93380a5e57259faaf95088b7f133b5778/header/action.yml#L47-L51
- name: Check License Header
if: matrix.platform == 'linux/amd64' # Only required once for any platform, and will do the most general amd64
uses: apache/skywalking-eyes/header@main
with:
log: "info" # optional: set the log level. The default value is `info`.
Expand All @@ -113,6 +153,7 @@ jobs:
-
name: Sysdig Benchmark Dockerfile
id: sysdig
if: matrix.platform == 'linux/amd64' # Only required once for any platform, and will do the most general amd64
# You may pin to the exact commit or the version.
# uses: https://github.com/sysdiglabs/benchmark-dockerfile/tags
uses: sysdiglabs/benchmark-dockerfile@v1.0.0
Expand All @@ -130,6 +171,7 @@ jobs:
-
name: Post Sysdig Benchmark Dockerfile
id: postsysdig
if: matrix.platform == 'linux/amd64' # Only required once for any platform, and will do the most general amd64
run: |
echo ${{ toJSON(steps.sysdig.outputs.violation_report) }} | \
jq -r .
Expand All @@ -138,50 +180,6 @@ jobs:
wc -l | \
xargs -I% test 0 -eq %

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
-
name: Extract Docker metadata
id: meta
# You may pin to the exact commit or the version.
# uses: https://github.com/docker/metadata-action/tags
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_REGISTRY_URL }}/${{ env.DOCKER_REGISTRY_ORG }}/${{ env.DOCKER_REGISTRY_IMAGE }}
# for latest tag
# latest=auto for tagging latest only for "master" branch
flavor: |
latest=true
# eg. refs/heads/master
# eg. refs/pull/318/merge
# shorthand for {{major}}.{{minor}}.{{patch}} (can include pre-release)
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=ref,event=pr
type=semver,pattern=v{{version}}
type=schedule,pattern=nightly

# GitHub Action to login against a Docker registry.
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
-
name: Docker Login to registry ${{ env.DOCKER_REGISTRY_URL }}
id: login
# You may pin to the exact commit or the version.
# uses: https://github.com/docker/login-action/tags
uses: docker/login-action@v3
with:
# Server address of Docker registry. If not set then will default to Docker Hub
registry: ${{ env.DOCKER_REGISTRY_URL }} # optional
# Username used to log against the Docker registry
username: ${{ vars.DOCKER_REGISTRY_USER }} # optional
# Password or personal access token used to log against the Docker registry
password: ${{ secrets[vars.DOCKER_REGISTRY_TOKEN_NAME] }} # optional
# Log out from the Docker registry at the end of a job
logout: true # optional, default is true

# GitHub Action to install QEMU static binaries.
# https://github.com/docker/setup-qemu-action
-
Expand All @@ -200,30 +198,133 @@ jobs:
# uses: https://github.com/docker/setup-buildx-action/tags
uses: docker/setup-buildx-action@v3

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
-
name: Build and push Docker image
id: build_and_push
# You may pin to the exact commit or the version.
# uses: https://github.com/docker/build-push-action/tags
- name: Login to Temporary Registry (GitHub Container Registry)
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Lowercase image id name to follow the docker name rule
run: |
IMAGE_ID=ghcr.io/${{ github.repository }}
echo "GHCR_IMAGE_ID=$(echo $IMAGE_ID | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV

- name: Build and Push to GHCR (Staging)
uses: docker/build-push-action@v4
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
load: ${{ github.event_name == 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
# push: true
# load: false
# tags: ${{ env.DOCKER_REGISTRY_URL }}/${{ env.DOCKER_REGISTRY_ORG }}/${{ env.DOCKER_REGISTRY_IMAGE }}:nightly
labels: ${{ steps.meta.outputs.labels }}
platforms: ${{ env.DOCKER_BUILDX_PLATFORM }}
build-args: |
APP_VERSION=${{ steps.meta.outputs.version }}
push: true
# tag i.e) ghcr.io/athenz/authorization-proxy:sha-ck29d1-amd64
tags: ${{ env.GHCR_IMAGE_ID }}:${{ github.sha }}${{ matrix.suffix }}
platforms: ${{ matrix.platform }}
cache-from: type=gha
cache-to: type=gha,mode=max

# Test Docker image
-
name: Test Docker image
id: test_docker
run: |
docker run --rm ${{ fromJSON(steps.meta.outputs.json).tags[0] }} --version
docker run --rm ${{ env.GHCR_IMAGE_ID }}:${{ github.sha }}${{ matrix.suffix }} --version
merge:
if: github.event_name != 'pull_request' # We do not need to push pr images to official registry (Docker.io)
needs:
- set_matrix
- build # Make sure each build of every platform defined in matrix is completed
runs-on: ubuntu-latest
permissions:
packages: write # Give read permission WITHOUT making the registry_visibility=Public
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker registry
uses: docker/login-action@v3
with:
# Server address of Docker registry. If not set then will default to Docker Hub
registry: ${{ env.DOCKER_REGISTRY_URL }} # optional
# Username used to log against the Docker registry
username: ${{ vars.DOCKER_REGISTRY_USER }} # optional
# Password or personal access token used to log against the Docker registry
password: ${{ secrets[vars.DOCKER_REGISTRY_TOKEN_NAME] }} # optional
# Log out from the Docker registry at the end of a job
logout: true # optional, default is true
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_REGISTRY_URL }}/${{ env.DOCKER_REGISTRY_ORG }}/${{ env.DOCKER_REGISTRY_IMAGE }}
flavor: |
latest=false
# No suffix defined as this will be the merged one!
tags: ${{ env.TAGS_CONFIG }}
- name: Set GHCR Image Name (Lowercase)
run: |
IMAGE_ID=ghcr.io/${{ github.repository }}
echo "GHCR_IMAGE_ID=$(echo $IMAGE_ID | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
- name: Create Manifest and Push to Docker Hub
env:
PLATFORM_SUFFIXES: ${{ needs.set_matrix.outputs.suffixes }}
SHA_TAG: ${{ github.sha }}
run: |
echo "${{ steps.meta.outputs.tags }}" | while read -r docker_registry_tag; do
echo "Merging sources into final tag: $docker_registry_tag"

sources=""
for suffix in $PLATFORM_SUFFIXES; do
# i.e) ghcr.io/athenz/authorization-proxy:sha-xxx-amd64
sources="$sources ${{ env.GHCR_IMAGE_ID }}:${SHA_TAG}${suffix}"
done

docker buildx imagetools create -t "$docker_registry_tag" $sources
done
cleanup:
name: Cleanup Temporary Images from GitHub Container Registry
needs: [set_matrix, build, merge]
if: always()
runs-on: ubuntu-latest
permissions:
packages: write # Permission to delete images from GitHub Container Registry
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Delete Temporary Images using GitHub API
env:
OWNER: ${{ github.repository_owner }}
PACKAGE_NAME: authorization-proxy
SHA_TAG: ${{ github.sha }}
PLATFORM_SUFFIXES: ${{ needs.set_matrix.outputs.suffixes }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "🧹 Cleanup using GitHub API..."

for suffix in $PLATFORM_SUFFIXES; do
TAG_NAME="${SHA_TAG}${suffix}"
echo "🔍 Finding version ID for tag: $TAG_NAME"

VERSION_ID=$(gh api "/orgs/$OWNER/packages/container/$PACKAGE_NAME/versions" \
-H "Accept: application/vnd.github+json" \
--jq ".[] | select(.metadata.container.tags[]? == \"$TAG_NAME\") | .id")

if [ -z "$VERSION_ID" ]; then
echo "⚠️ Tag $TAG_NAME not found (already deleted?)"
continue
fi

echo "🗑️ Deleting Version ID: $VERSION_ID (Tag: $TAG_NAME)"

# Delete based on ID:
gh api -X DELETE "/orgs/$OWNER/packages/container/$PACKAGE_NAME/versions/$VERSION_ID" \
-H "Accept: application/vnd.github+json" || true
done

echo "✨ Cleanup finished!"
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /etc/passwd /etc/passwd
# Copy our dynamic-linked executable and library
COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME}
COPY --from=builder /lib/ld-musl-x86_64.so* /lib/

# Copy dynamic-linked libraries for musl, like /lib/ld-musl-x86_64.so* or /lib/ld-musl-arm64.so* etc:
COPY --from=builder /lib/ld-musl-*.so* /lib/
# Copy user
COPY --from=builder /etc/passwd /etc/passwd

Expand Down
Loading