Skip to content

Commit

Permalink
Use AWS creds via OIDC; merge job now reusable
Browse files Browse the repository at this point in the history
  • Loading branch information
erhhung committed Aug 21, 2024
1 parent d18abe0 commit b575d08
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 86 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# https://docs.docker.com/build/ci/github-actions/multi-platform/
name: Build
name: Build Docker Image

on:
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_call
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
uses: docker/metadata-action@v5
with:
images: |-
${{ github.repository }}
docker.io/${{ github.repository }}
ghcr.io/${{ github.repository }}
labels: ${{ inputs.image-labels }}

Expand All @@ -76,8 +76,7 @@ jobs:
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: us-east-1
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
role-to-assume: ${{ vars.RUNNER_OIDC_ROLE_ARN }}

# https://github.com/aws-actions/amazon-ecr-login
- name: Log in to ECR Public
Expand All @@ -91,6 +90,7 @@ jobs:
id: docker-hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

Expand Down
116 changes: 34 additions & 82 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# https://docs.docker.com/build/ci/github-actions/multi-platform/
name: CI
name: CI Pipeline

on:
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#push
Expand All @@ -13,17 +13,14 @@ env:
IMAGE_LABELS: |-
org.opencontainers.image.authors=Erhhung Yuan <[email protected]>
jobs:
# because env cannot be passed to reusable workflows:
# https://github.com/orgs/community/discussions/26671
env-vars:
runs-on: ubuntu-latest
steps:
- name: Set env Variables as Outputs
run: '#'
outputs:
image-labels: ${{ env.IMAGE_LABELS }}
# https://docs.github.com/en/rest/authentication/permissions-required-for-github-apps
permissions:
id-token: write # obtain JWT via OIDC
contents: read # repository checkout
packages: write # push image to GHCR
actions: write # caches & artifacts

jobs:
launch-runner:
runs-on: ubuntu-latest
steps:
Expand All @@ -33,8 +30,7 @@ jobs:
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ vars.RUNNER_AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
role-to-assume: ${{ vars.RUNNER_OIDC_ROLE_ARN }}

# https://github.com/erhhung/ec2-github-runner
- name: Launch Temporary EC2 Runner
Expand All @@ -44,6 +40,8 @@ jobs:
RUN_INFO: ${{ github.run_id }}-${{ github.run_attempt }}
with:
mode: start
# cannot use github.token as it does not support
# required metadata & administration permissions
github-token: ${{ secrets.RUNNER_GITHUB_REPOS_PAT }}
labels: Linux,ARM64,AL2023
image-id: ${{ vars.RUNNER_ARM64_AMI_ID }}
Expand Down Expand Up @@ -81,91 +79,44 @@ jobs:
labels-json: '${{ steps.output.outputs.labels-json }}'
labels-csv: '${{ steps.output.outputs.labels-csv }}'

# because env cannot be passed to reusable workflows:
# https://github.com/orgs/community/discussions/26671
prepare-inputs:
runs-on: ubuntu-latest
steps:
- name: Set env Variables as Outputs
run: '#'
outputs:
image-labels: ${{ env.IMAGE_LABELS }}

build-amd64:
needs: env-vars
needs: prepare-inputs
uses: ./.github/workflows/build.yml
with:
platform: linux/amd64
image-labels: ${{ needs.env-vars.outputs.image-labels }}
image-labels: ${{ needs.prepare-inputs.outputs.image-labels }}
secrets: inherit

build-arm64:
needs:
- launch-runner
- env-vars
- prepare-inputs
uses: ./.github/workflows/build.yml
with:
platform: linux/arm64
runs-on: ${{ needs.launch-runner.outputs.labels-json }}
image-labels: ${{ needs.env-vars.outputs.image-labels }}
image-labels: ${{ needs.prepare-inputs.outputs.image-labels }}
secrets: inherit

merge:
merge-manifests:
needs:
- build-amd64
- build-arm64
runs-on: ubuntu-latest
steps:
# https://github.com/actions/download-artifact
- name: Download Digests
id: download
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

# https://github.com/crazy-max/ghaction-setup-docker
- name: Set up Docker Daemon
id: docker
uses: crazy-max/ghaction-setup-docker@v3

# https://github.com/docker/setup-buildx-action
- name: Set up Docker BuildX
id: buildx
uses: docker/setup-buildx-action@v3

# https://github.com/docker/metadata-action
- name: Extract Metadata for Docker
id: metadata
uses: docker/metadata-action@v5
with:
images: |-
${{ github.repository }}
ghcr.io/${{ github.repository }}
labels: ${{ env.IMAGE_LABELS }}

# https://github.com/docker/login-action
- name: Log in to Docker Hub
id: docker-hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

# https://github.com/docker/login-action
- name: Log in to GitHub GHCR
id: ghcr
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Create Manifests and Push
id: manifests
working-directory: /tmp/digests
run: |-
tags=($(jq -cr '[.tags[] | "-t \(.)"] | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON"))
images=($(printf '${{ github.repository }}@sha256:%s ' *))
docker buildx imagetools create "${tags[@]}" "${images[@]}"
# confirm merged image manifests
- name: Inspect Image
id: inspect
run: |-
tag="${{ github.repository }}:$DOCKER_METADATA_OUTPUT_VERSION"
docker buildx imagetools inspect $tag
- prepare-inputs
uses: ./.github/workflows/merge.yml
with:
image-labels: ${{ needs.prepare-inputs.outputs.image-labels }}
secrets: inherit

terminate-runner:
if: always()
Expand All @@ -180,15 +131,16 @@ jobs:
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ vars.RUNNER_AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
role-to-assume: ${{ vars.RUNNER_OIDC_ROLE_ARN }}

# https://github.com/erhhung/ec2-github-runner
- name: Terminate Temporary EC2 Runner
id: runner
uses: erhhung/ec2-github-runner@v3
with:
mode: stop
# cannot use github.token as it does not support
# required metadata & administration permissions
github-token: ${{ secrets.RUNNER_GITHUB_REPOS_PAT }}
labels: ${{ needs.launch-runner.outputs.labels-csv }}
instance-id: ${{ needs.launch-runner.outputs.instance-id }}
78 changes: 78 additions & 0 deletions .github/workflows/merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# https://docs.docker.com/build/ci/github-actions/multi-platform/
name: Merge Image Manifests

on:
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_call
workflow_call:
inputs:
image-labels:
type: string
description: Labels for the image (K=V per line)
required: false
default: ''

jobs:
merge:
runs-on: ubuntu-latest
steps:
# https://github.com/actions/download-artifact
- name: Download Digests
id: download
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

# https://github.com/crazy-max/ghaction-setup-docker
- name: Set up Docker Daemon
id: docker
uses: crazy-max/ghaction-setup-docker@v3

# https://github.com/docker/setup-buildx-action
- name: Set up Docker BuildX
id: buildx
uses: docker/setup-buildx-action@v3

# https://github.com/docker/metadata-action
- name: Extract Metadata for Docker
id: metadata
uses: docker/metadata-action@v5
with:
images: |-
docker.io/${{ github.repository }}
ghcr.io/${{ github.repository }}
labels: ${{ inputs.image-labels }}

# https://github.com/docker/login-action
- name: Log in to Docker Hub
id: docker-hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

# https://github.com/docker/login-action
- name: Log in to GitHub GHCR
id: ghcr
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Create Manifests and Push
id: manifests
working-directory: /tmp/digests
run: |-
tags=($(jq -cr '[.tags[] | "-t \(.)"] | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON"))
images=($(printf '${{ github.repository }}@sha256:%s ' *))
docker buildx imagetools create "${tags[@]}" "${images[@]}"
# confirm merged image manifests
- name: Inspect Image
id: inspect
run: |-
tag="${{ github.repository }}:$DOCKER_METADATA_OUTPUT_VERSION"
docker buildx imagetools inspect $tag

0 comments on commit b575d08

Please sign in to comment.