Docker Images #15
Workflow file for this run
This file contains 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
# Workflows pertaining to the jsii/superchain Docker image | |
name: Docker Images | |
on: | |
workflow_dispatch: {} | |
merge_group: {} | |
pull_request: {} | |
push: | |
tags: | |
- v*-*-* | |
env: | |
DOCKER_BUILDKIT: 1 | |
jobs: | |
superchain: | |
name: jsii/superchain | |
permissions: | |
contents: read | |
id-token: write # Necessary for OIDC federation | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
debian: | |
- "bullseye" # 11 | |
- "bookworm" # 12 | |
node: ["18", "20", "22"] # STOP! Before adding anything here, check our maintenance policy in the README | |
exclude: | |
# We publish bullseye only with Node >= 20 | |
- debian: "bullseye" | |
node: "18" | |
env: | |
# Node version whose images will be aliased without the -nodeXX segment | |
DEFAULT_NODE_MAJOR_VERSION: 18 | |
steps: | |
- name: Check out | |
uses: actions/checkout@v4 | |
# Check if federation into AWS is configured. This is necessary because | |
# GitHub does not interpret ${{ secret.FOO }} within `if:` conditions... | |
# See: https://github.com/actions/runner/issues/520 | |
- name: Check AWS federation configuration | |
id: federate_to_aws | |
run: |- | |
if [[ "${{ secrets.AWS_ROLE_TO_ASSUME }}" != "" ]]; then | |
echo "🔑 Federation into AWS is possible (AWS_ROLE_TO_ASSUME is available)" | |
echo "enabled=true" >> $GITHUB_OUTPUT | |
else | |
echo "❌ Federation into AWS is disabled (no AWS_ROLE_TO_ASSUME secret found)" | |
echo "enabled=false" >> $GITHUB_OUTPUT | |
fi | |
# Federate into the PR Validation AWS Account | |
- name: Federate into AWS | |
if: steps.federate_to_aws.outputs.enabled == 'true' | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-region: us-east-1 | |
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | |
role-session-name: GHA_aws-jsii_docker-images | |
# Login to ECR Public registry, so we don't get throttled at 1 TPS | |
- name: Login to ECR Public | |
if: steps.federate_to_aws.outputs.enabled == 'true' | |
run: |- | |
aws ecr-public get-login-password --region=us-east-1 \ | |
| docker login --username AWS --password-stdin public.ecr.aws | |
- name: Slice DockerHub credentials | |
id: credentials | |
run: |- | |
echo "username=$(cut -d: -f1 <<< '${{ secrets.DOCKER_CREDENTIALS }}')" >> "$GITHUB_OUTPUT" | |
echo "password=$(cut -d: -f2 <<< '${{ secrets.DOCKER_CREDENTIALS }}')" >> "$GITHUB_OUTPUT" | |
echo "::add-mask::$(cut -d: -f2 <<< '${{ secrets.DOCKER_CREDENTIALS }}')" | |
# We only authenticate to Docker on the 'aws/jsii' repo, as forks will not have the secret | |
- name: Login to Docker Hub | |
if: github.repository == 'aws/jsii-superchain' | |
# The DOCKER_CREDENTIALS secret is expected to contain a username:token pair | |
run: |- | |
docker login \ | |
--username=${{ steps.credentials.outputs.username }} \ | |
--password=${{ steps.credentials.outputs.password }} | |
# Ensure we run with bash, because that's the syntax we're using here... | |
shell: bash | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
with: | |
platforms: arm64 | |
- name: Set up docker buildx | |
id: buildx | |
uses: docker/setup-buildx-action@v3 | |
with: | |
# Disable parallelism because IO contention makes it too slow on GitHub | |
# workers... | |
buildkitd-config-inline: |- | |
[worker.oci] | |
max-parallelism = 1 | |
# 1 pull per second from ECR Public | |
- name: Jitter the start time to avoid ECR Public throttling | |
id: sleep-start | |
if: steps.federate_to_aws.outputs.enabled != 'true' | |
run: |- | |
sleep $((RANDOM % 60)) | |
- name: Determine build time | |
id: build-time | |
run: |- | |
echo "value=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT | |
- name: Show Available Disk Space | |
run: df -h && du -h | |
- name: Free Disk Space | |
uses: jlumbroso/[email protected] | |
- name: Build Image | |
working-directory: superchain | |
run: |- | |
docker buildx build \ | |
--quiet \ | |
--builder ${{ steps.buildx.outputs.name }} \ | |
--platform linux/amd64,linux/arm64 \ | |
--target superchain \ | |
--pull \ | |
--build-arg BUILD_TIMESTAMP="${{ steps.build-time.outputs.value }}" \ | |
--build-arg COMMIT_ID='${{ github.sha }}' \ | |
--build-arg DEBIAN_VERSION=${{ matrix.debian }} \ | |
--build-arg NODE_MAJOR_VERSION=${{ matrix.node }} \ | |
-f Dockerfile \ | |
. | |
- name: Test Image | |
working-directory: superchain | |
run: |- | |
docker buildx build \ | |
--builder ${{ steps.buildx.outputs.name }} \ | |
--platform linux/amd64,linux/arm64 \ | |
--target superchain \ | |
--build-arg BUILD_TIMESTAMP="${{ steps.build-time.outputs.value }}" \ | |
--build-arg COMMIT_ID='${{ github.sha }}' \ | |
--build-arg DEBIAN_VERSION=${{ matrix.debian }} \ | |
--build-arg NODE_MAJOR_VERSION=${{ matrix.node }} \ | |
-f Dockerfile \ | |
. | |
# Re-authenticate to ECR Public, this time with image-push permissions | |
- name: Federate with AWS role for ECR Public push | |
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-region: us-east-1 | |
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME_FOR_ECR_PUBLIC_PUSH }} | |
role-session-name: GHA_aws-jsii_docker-images-PUSH | |
- name: Authenticate with ECR Public for Push | |
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') | |
uses: aws-actions/amazon-ecr-login@v2 | |
with: | |
registry-type: public | |
# Only when pushing to new preview tag | |
- name: Publish (preview build) | |
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-preview') | |
working-directory: superchain | |
# NOTE BELOW: The `--tag` flags can be provided multiple times... we use that capability... | |
run: |- | |
# If the current version is the default version, also tag this with the unqualified ':nightly' label | |
if [[ "${{ matrix.node }}" == "$DEFAULT_NODE_MAJOR_VERSION" ]]; then | |
docker buildx build \ | |
--builder ${{ steps.buildx.outputs.name }} \ | |
--platform linux/amd64,linux/arm64 \ | |
--target superchain \ | |
--push \ | |
--build-arg BUILD_TIMESTAMP="${{ steps.build-time.outputs.value }}" \ | |
--build-arg COMMIT_ID='${{ github.sha }}' \ | |
--build-arg DEBIAN_VERSION=${{ matrix.debian }} \ | |
--build-arg NODE_MAJOR_VERSION=${{ matrix.node }} \ | |
--tag "${{ vars.ECR_PUBLIC_REGISTRY }}:1-${{ matrix.debian }}-slim-nightly" \ | |
--tag "${{ vars.ECR_PUBLIC_REGISTRY }}:1-${{ matrix.debian }}-slim-node${{ matrix.node }}-nightly" \ | |
--tag "jsii/superchain:1-${{ matrix.debian }}-slim-nightly" \ | |
--tag "jsii/superchain:1-${{ matrix.debian }}-slim-node${{ matrix.node }}-nightly" \ | |
-f Dockerfile \ | |
. | |
else | |
docker buildx build \ | |
--builder ${{ steps.buildx.outputs.name }} \ | |
--platform linux/amd64,linux/arm64 \ | |
--target superchain \ | |
--push \ | |
--build-arg BUILD_TIMESTAMP="${{ steps.build-time.outputs.value }}" \ | |
--build-arg COMMIT_ID='${{ github.sha }}' \ | |
--build-arg DEBIAN_VERSION=${{ matrix.debian }} \ | |
--build-arg NODE_MAJOR_VERSION=${{ matrix.node }} \ | |
--tag "${{ vars.ECR_PUBLIC_REGISTRY }}:1-${{ matrix.debian }}-slim-node${{ matrix.node }}-nightly" \ | |
--tag "jsii/superchain:1-${{ matrix.debian }}-slim-node${{ matrix.node }}-nightly" \ | |
-f Dockerfile \ | |
. | |
fi | |
- name: Update README (any tag) | |
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') | |
uses: peter-evans/dockerhub-description@v4 | |
with: | |
username: ${{ steps.credentials.outputs.username }} | |
password: ${{ steps.credentials.outputs.password }} | |
repository: jsii/superchain | |
readme-filepath: ./README.md | |
- name: Publish (latest) | |
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-preview') | |
working-directory: superchain | |
# NOTE BELOW: The `--tag` flags can be provided multiple times... we use that capability... | |
run: |- | |
# If the current version is the default version, also tag this with the unqualified ':1-*' label | |
if [[ "${{ matrix.node }}" == "$DEFAULT_NODE_MAJOR_VERSION" ]]; then | |
docker buildx build \ | |
--builder ${{ steps.buildx.outputs.name }} \ | |
--platform linux/amd64,linux/arm64 \ | |
--target superchain \ | |
--push \ | |
--build-arg BUILD_TIMESTAMP="${{ steps.build-time.outputs.value }}" \ | |
--build-arg COMMIT_ID='${{ github.sha }}' \ | |
--build-arg DEBIAN_VERSION=${{ matrix.debian }} \ | |
--build-arg NODE_MAJOR_VERSION=${{ matrix.node }} \ | |
--tag "${{ vars.ECR_PUBLIC_REGISTRY }}:1-${{ matrix.debian }}-slim" \ | |
--tag "${{ vars.ECR_PUBLIC_REGISTRY }}:1-${{ matrix.debian }}-slim-node${{ matrix.node }}" \ | |
--tag "jsii/superchain:1-${{ matrix.debian }}-slim" \ | |
--tag "jsii/superchain:1-${{ matrix.debian }}-slim-node${{ matrix.node }}" \ | |
-f Dockerfile \ | |
. | |
else | |
docker buildx build \ | |
--builder ${{ steps.buildx.outputs.name }} \ | |
--platform linux/amd64,linux/arm64 \ | |
--target superchain \ | |
--push \ | |
--build-arg BUILD_TIMESTAMP="${{ steps.build-time.outputs.value }}" \ | |
--build-arg COMMIT_ID='${{ github.sha }}' \ | |
--build-arg DEBIAN_VERSION=${{ matrix.debian }} \ | |
--build-arg NODE_MAJOR_VERSION=${{ matrix.node }} \ | |
--tag "${{ vars.ECR_PUBLIC_REGISTRY }}:1-${{ matrix.debian }}-slim-node${{ matrix.node }}" \ | |
--tag "jsii/superchain:1-${{ matrix.debian }}-slim-node${{ matrix.node }}" \ | |
-f Dockerfile \ | |
. | |
fi | |
build: | |
name: "build" | |
runs-on: ubuntu-latest | |
needs: | |
- superchain | |
if: always() | |
steps: | |
- name: Build result | |
run: echo ${{ needs.superchain.result }} | |
- if: ${{ needs.superchain.result != 'success' }} | |
name: Set status based on matrix build | |
run: exit 1 |