Skip to content

release-build

release-build #225

Workflow file for this run

name: Release Build
on:
# Allow the workflow to be triggered manually, e.g. for testing, or after
# changing the Dockerfiles:
workflow_dispatch:
inputs:
pulumi_version:
description: The version of Pulumi to use to build the Docker images. Full semver, e.g. "3.18.1".
type: string
required: true
force_release:
description: Whether to force a release to occur. By default, only repository dispatch creates releases.
type: boolean
required: true
default: false
tag_latest:
description: Whether to also tag this version as "latest".
type: boolean
required: true
default: true
# Trigger the release workflow for Docker containers when a new version of
# Pulumi is released. This dispatch event is fired in pulumi/pulumi's release
# workflow:
repository_dispatch:
types:
- docker-build # Legacy event name, will delete once no longer used.
- release-build # Current event name.
env:
GITHUB_TOKEN: ${{ secrets.PULUMI_BOT_TOKEN }}
# Used to run the container tests:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
# The organization in the Pulumi SaaS service against which the integration
# tests will run:
PULUMI_ORG: "pulumi-test"
# We parameterize the Docker Hub username to allow forks to easily test
# changes on a separate repo without having to change the username in multiple
# places:
DOCKER_USERNAME: pulumibot
DOCKER_ORG: pulumi
PULUMI_VERSION: ${{ github.event.inputs.pulumi_version || github.event.client_payload.ref }}
# Do not depend on C library for the tests.
CGO_ENABLED: "0"
# Azure credentials for the tests
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
AWS_REGION: "us-west-2"
# GCP
GCP_SERVICE_ACCOUNT_EMAIL: "[email protected]"
GCP_PROJECT_NAME: "pulumi-ci-gcp-provider"
GCP_PROJECT_NUMBER: "895284651812"
GCP_WORKLOAD_IDENTITY_POOL: "pulumi-ci"
GCP_WORKLOAD_IDENTITY_PROVIDER: "pulumi-ci"
GCP_REGION: "us-central1"
GCP_ZONE: "us-central1-a"
jobs:
kitchen-sink:
name: All SDKs image
strategy:
matrix:
go-version: [1.21.x]
# Disabling arm64 for now as it takes too long to build Python when running Docker with QEMU.
# Once arm64 runners are availble to OSS projects, we can re-enable this.
# TODO: https://github.com/pulumi/pulumi-docker-containers/issues/297
arch: ["amd64"] # "arm64"
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@master
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Build
run: |
docker build \
-f docker/pulumi/Dockerfile \
--platform linux/${{ matrix.arch }} \
-t ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-${{ matrix.arch }} \
--target base \
--build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \
--load \
docker/pulumi
- name: Build nonroot variant
run: |
docker build \
-f docker/pulumi/Dockerfile \
--platform linux/${{ matrix.arch }} \
-t ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-nonroot-${{ matrix.arch }} \
--target nonroot \
--build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \
--load \
docker/pulumi
- name: Install go
uses: actions/setup-go@v5
with:
go-version: "1.22"
cache-dependency-path: tests/go.sum
- name: Compile tests
working-directory: tests
run: |
GOOS=linux GOARCH=amd64 go test -c -o /tmp/pulumi-test-containers ./...
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
role-duration-seconds: 14400 # 4 hours
role-session-name: pulumi-docker-containers@githubActions
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
- name: Authenticate with Google Cloud
uses: google-github-actions/auth@v2
with:
service_account: ${{ env.GCP_SERVICE_ACCOUNT_EMAIL }}
workload_identity_provider: projects/${{ env.GCP_PROJECT_NUMBER
}}/locations/global/workloadIdentityPools/${{ env.GCP_WORKLOAD_IDENTITY_POOL
}}/providers/${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }}
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v2'
- name: Select Tests for AMD64
if: ${{ matrix.arch == 'amd64' }}
# Run all tests on AMD64
run: echo "CONTAINER_TESTS_TO_RUN=''" >> $GITHUB_ENV
- name: Select Tests for ARM64
if: ${{ matrix.arch == 'arm64' }}
# We use QEMU to run ARM64 images on AMD64, but .NET Core isn't supported by QEMU,
# for now we only run the basic TestEnvironment tests on ARM64.
# https://gitlab.com/qemu-project/qemu/-/issues/249
# TODO: enable more tests https://github.com/pulumi/pulumi-docker-containers/issues/289
run: echo "CONTAINER_TESTS_TO_RUN='-test.run TestEnvironment'" >> $GITHUB_ENV
- name: Tests
run: |
docker run \
-e RUN_CONTAINER_TESTS=true \
-e IMAGE_VARIANT=pulumi \
-e PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
-e PULUMI_ORG=${PULUMI_ORG} \
-e ARM_CLIENT_ID=${ARM_CLIENT_ID} \
-e ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET} \
-e ARM_TENANT_ID=${ARM_TENANT_ID} \
-e ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID} \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
-e AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN} \
-e AWS_REGION=${AWS_REGION} \
-e GCP_PROJECT_NAME=${GCP_PROJECT_NAME} \
-e GCP_PROJECT_NUMBER=${GCP_PROJECT_NUMBER} \
-e GOOGLE_APPLICATION_CREDENTIALS=/src/creds.json \
--mount type=bind,source=$GOOGLE_APPLICATION_CREDENTIALS,target=/src/creds.json \
--volume /tmp:/src \
--entrypoint /src/pulumi-test-containers \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-${{ matrix.arch }} \
-test.timeout=1h -test.v ${{ env.CONTAINER_TESTS_TO_RUN }}
- name: Tests for nonroot variant
run: |
chmod o+r $GOOGLE_APPLICATION_CREDENTIALS
docker run \
-e RUN_CONTAINER_TESTS=true \
-e IMAGE_VARIANT=pulumi-nonroot \
-e PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
-e PULUMI_ORG=${PULUMI_ORG} \
-e ARM_CLIENT_ID=${ARM_CLIENT_ID} \
-e ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET} \
-e ARM_TENANT_ID=${ARM_TENANT_ID} \
-e ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID} \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
-e AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN} \
-e AWS_REGION=${AWS_REGION} \
-e GCP_PROJECT_NAME=${GCP_PROJECT_NAME} \
-e GCP_PROJECT_NUMBER=${GCP_PROJECT_NUMBER} \
-e GOOGLE_APPLICATION_CREDENTIALS=/src/creds.json \
--mount type=bind,source=$GOOGLE_APPLICATION_CREDENTIALS,target=/src/creds.json \
--volume /tmp:/src \
--entrypoint /src/pulumi-test-containers \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-nonroot-${{ matrix.arch }} \
-test.timeout=1h -test.v ${{ env.CONTAINER_TESTS_TO_RUN }}
- name: Push ${{ env.PULUMI_VERSION }}
run: |
docker push ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-${{ matrix.arch }}
docker push ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-nonroot-${{ matrix.arch }}
kitchen-sink-manifests:
name: Kitchen sink image manifests
needs: ["kitchen-sink"]
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Versioned manifest
run: |
# TODO: https://github.com/pulumi/pulumi-docker-containers/issues/297
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }} \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-nonroot \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-nonroot-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-nonroot
- name: Latest manifest
if: ${{ github.event.inputs.tag_latest || github.event_name == 'repository_dispatch' }}
# Manifest lists can't be a source for `docker tag`, so we create an
# additional copy of the previous manifest to tag latest:
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi:latest \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi:latest
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi:latest-nonroot \
${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }}-nonroot-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi:latest-nonroot
provider-build-environment:
name: Provider Build Environment image
strategy:
matrix:
go-version: [1.21.1]
# Disabling arm64 for now as it takes too long to build Python when running Docker with QEMU.
# Once arm64 runners are availble to OSS projects, we can re-enable this.
# TODO: https://github.com/pulumi/pulumi-docker-containers/issues/297
arch: ["amd64"] # "arm64"
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@master
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Build
# This image is only built for AMD64 for the same reasons as
# the "kitchen sink" image, listed above.
run: |
docker build \
-f docker/pulumi/Dockerfile \
--platform linux/${{ matrix.arch }} \
-t ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }}-${{ matrix.arch }} \
--target build-environment \
--build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \
--load \
docker/pulumi
- name: Install go
uses: actions/setup-go@v5
with:
go-version: "1.22"
cache-dependency-path: tests/go.sum
- name: Compile tests
working-directory: tests
run: |
GOOS=linux GOARCH=amd64 go test -c -o /tmp/pulumi-test-containers ./...
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
role-duration-seconds: 14400 # 4 hours
role-session-name: pulumi-docker-containers@githubActions
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
- name: Authenticate with Google Cloud
uses: google-github-actions/auth@v2
with:
service_account: ${{ env.GCP_SERVICE_ACCOUNT_EMAIL }}
workload_identity_provider: projects/${{ env.GCP_PROJECT_NUMBER
}}/locations/global/workloadIdentityPools/${{ env.GCP_WORKLOAD_IDENTITY_POOL
}}/providers/${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }}
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v2'
- name: Tests
run: |
docker run \
-e RUN_CONTAINER_TESTS=true \
-e IMAGE_VARIANT=pulumi \
-e PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
-e PULUMI_ORG=${PULUMI_ORG} \
-e ARM_CLIENT_ID=${ARM_CLIENT_ID} \
-e ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET} \
-e ARM_TENANT_ID=${ARM_TENANT_ID} \
-e ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID} \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
-e AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN} \
-e AWS_REGION=${AWS_REGION} \
-e GCP_PROJECT_NAME=${GCP_PROJECT_NAME} \
-e GCP_PROJECT_NUMBER=${GCP_PROJECT_NUMBER} \
-e GOOGLE_APPLICATION_CREDENTIALS=/src/creds.json \
--mount type=bind,source=$GOOGLE_APPLICATION_CREDENTIALS,target=/src/creds.json \
--volume /tmp:/src \
--entrypoint /src/pulumi-test-containers \
${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }}-${{ matrix.arch }} \
-test.parallel=1 -test.timeout=1h -test.v
- name: Push ${{ env.PULUMI_VERSION }}
run: docker push ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }}-${{ matrix.arch }}
provider-build-environment-manifests:
name: Provider Build Environment manifests
needs: ["provider-build-environment"]
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Versioned manifest
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }} \
${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }}-amd64
- name: Latest manifest
if: ${{ github.event.inputs.tag_latest || github.event_name == 'repository_dispatch' }}
# Manifest lists can't be a source for `docker tag`, so we create an
# additional copy of the previous manifest to tag latest:
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:latest \
${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }}-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:latest
base:
name: Base image
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: ["debian", "ubi"]
arch: ["arm64", "amd64"]
steps:
- uses: actions/checkout@master
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Build
run: |
docker build \
-f docker/base/Dockerfile.${{ matrix.os }} \
--platform linux/${{ matrix.arch }} \
. \
-t ${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-${{ matrix.os }}-${{ matrix.arch }} \
--build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \
--load
- name: Push image
run: |
docker push ${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-${{ matrix.os}}-${{ matrix.arch }}
base-manifests:
name: Base image manifests
needs: ["base"]
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Debian manifest
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian
- name: UBI manifest
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-ubi \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-ubi-arm64 \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-ubi-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-ubi
- name: Suffix-less manifest (version)
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }} \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}
- name: Suffix-less manifest (latest)
if: ${{ github.event.inputs.tag_latest || github.event_name == 'repository_dispatch' }}
# Manifest lists can't be a source for `docker tag`, so we create an
# additional copy of the previous manifest to tag latest:
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-base:latest \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-base:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-base:latest
define-debian-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.define-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@master
- name: Define Matrix
id: define-matrix
run: |
echo matrix=$(python ./.github/scripts/matrix/gen-matrix.py) >> "$GITHUB_OUTPUT"
debian-sdk:
name: Debian SDK images
needs: define-debian-matrix
runs-on: ubuntu-latest
permissions:
id-token: write
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.define-debian-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@master
- name: Set image name
run: |
echo "IMAGE_NAME=${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-${{ matrix.arch }}" >> $GITHUB_ENV
- name: Set default language version image name
# For the default language version, we also set a default image name that doesn't include the version suffix
if: ${{ (matrix.default == true) && (matrix.suffix != '') }}
run: |
echo "DEFAULT_IMAGE_NAME=${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:${{ env.PULUMI_VERSION }}-debian-${{ matrix.arch }}" >> $GITHUB_ENV
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Build
run: |
docker build \
-f docker/${{ matrix.sdk }}/Dockerfile.debian \
--platform linux/${{ matrix.arch }} \
-t ${{ env.IMAGE_NAME }} \
--build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \
--build-arg LANGUAGE_VERSION=${{ matrix.language_version }} \
docker/${{ matrix.sdk }} \
--load
- name: Install go
uses: actions/setup-go@v5
with:
go-version: "1.22"
cache-dependency-path: tests/go.sum
- name: Compile tests
working-directory: tests
run: |
GOOS=linux GOARCH=${{ matrix.arch }} go test -c -o /tmp/pulumi-test-containers ./...
- name: Set SDKS_TO_TEST (dotnet)
if: ${{ matrix.sdk == 'dotnet' }}
run: echo "SDKS_TO_TEST=csharp" >> $GITHUB_ENV
- name: Set SDKS_TO_TEST (nodejs)
if: ${{ matrix.sdk == 'nodejs' }}
run: echo "SDKS_TO_TEST=typescript" >> $GITHUB_ENV
- name: Set SDKS_TO_TEST (default)
if: ${{ matrix.sdk != 'dotnet' && matrix.sdk != 'nodejs' }}
run: echo "SDKS_TO_TEST=${{ matrix.sdk}}" >> $GITHUB_ENV
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
role-duration-seconds: 14400 # 4 hours
role-session-name: pulumi-docker-containers@githubActions
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
- name: Authenticate with Google Cloud
uses: google-github-actions/auth@v2
with:
service_account: ${{ env.GCP_SERVICE_ACCOUNT_EMAIL }}
workload_identity_provider: projects/${{ env.GCP_PROJECT_NUMBER
}}/locations/global/workloadIdentityPools/${{ env.GCP_WORKLOAD_IDENTITY_POOL
}}/providers/${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }}
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v2'
- if: ${{ !(matrix.arch == 'arm64' && matrix.sdk == 'dotnet') }}
# We use QEMU to run ARM64 images on AMD64, but .NET Core isn't supported by QEMU, skip
# running the tests for this combination.
# https://gitlab.com/qemu-project/qemu/-/issues/249
name: Tests
run: |
docker run \
-e RUN_CONTAINER_TESTS=true \
-e IMAGE_VARIANT=pulumi-debian-${{ matrix.sdk }} \
-e LANGUAGE_VERSION=${{ matrix.language_version }} \
-e SDKS_TO_TEST=${SDKS_TO_TEST} \
-e PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
-e PULUMI_ORG=${PULUMI_ORG} \
-e ARM_CLIENT_ID=${ARM_CLIENT_ID} \
-e ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET} \
-e ARM_TENANT_ID=${ARM_TENANT_ID} \
-e ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID} \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
-e AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN} \
-e AWS_REGION=${AWS_REGION} \
-e GCP_PROJECT_NAME=${GCP_PROJECT_NAME} \
-e GCP_PROJECT_NUMBER=${GCP_PROJECT_NUMBER} \
-e GOOGLE_APPLICATION_CREDENTIALS=/src/creds.json \
--mount type=bind,source=$GOOGLE_APPLICATION_CREDENTIALS,target=/src/creds.json \
--volume /tmp:/src \
--entrypoint /src/pulumi-test-containers \
--platform ${{ matrix.arch }} \
${{ env.IMAGE_NAME }} \
-test.parallel=1 -test.timeout=1h -test.v -test.run "TestPulumiTemplateTests|TestEnvironment"
- name: Push image
run: |
docker push ${{ env.IMAGE_NAME }}
- name: Push default language version image
if: ${{ (matrix.default == true) && (matrix.suffix != '') }}
run: |
docker tag ${{ env.IMAGE_NAME }} ${{ env.DEFAULT_IMAGE_NAME }}
docker push ${{ env.DEFAULT_IMAGE_NAME }}
define-matrix-sdk-manifests:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.define-matrix-sdk-manifests.outputs.matrix }}
steps:
- uses: actions/checkout@master
- name: Define Matrix for SDK Manifests
id: define-matrix-sdk-manifests
run: |
echo matrix=$(python ./.github/scripts/matrix/gen-matrix.py) >> "$GITHUB_OUTPUT"
debian-sdk-manifests:
name: Debian SDK manifests
needs: ["debian-sdk", "define-matrix-sdk-manifests"]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.define-matrix-sdk-manifests.outputs.matrix) }}
steps:
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Debian manifest
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian
- name: Debian manifest without language version suffix
if: ${{ (matrix.default == true) && (matrix.suffix != '') }}
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:${{ env.PULUMI_VERSION }}-debian \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:${{ env.PULUMI_VERSION }}-debian
- name: Manifest without debian suffix
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }} \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}
- name: Manifest without debian suffix, without language version suffix
if: ${{ (matrix.default == true) && (matrix.suffix != '') }}
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:${{ env.PULUMI_VERSION }} \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:${{ env.PULUMI_VERSION }}
- name: Latest manifest
# Manifest lists can't be a source for `docker tag`, so we create an
# additional copy of the previous manifest to tag latest:
if: ${{ (github.event.inputs.tag_latest || github.event_name == 'repository_dispatch') }}
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:latest \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:latest
- name: Latest manifest, without language version suffix
# Manifest lists can't be a source for `docker tag`, so we create an
# additional copy of the previous manifest to tag latest:
if: ${{ (github.event.inputs.tag_latest || github.event_name == 'repository_dispatch') && (matrix.default == true) && (matrix.suffix != '') }}
run: |
docker manifest create \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:latest \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-arm64 \
${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-debian-amd64
docker manifest push ${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:latest
define-ubi-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.define-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@master
- name: Define Matrix for UBI SDK Manifests
id: define-matrix
# Filter out the nodejs 22 and 23 versions from the matrix, as they are not supported on UBI.
# https://access.redhat.com/articles/3376841
# Filter out the python 3.10 and 3.13 versions from the matrix, as they are not supported on UBI.
# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/installing_and_using_dynamic_programming_languages/assembly_introduction-to-python_installing-and-using-dynamic-programming-languages#con_python-versions_assembly_introduction-to-python
run: |
echo matrix=$(python ./.github/scripts/matrix/gen-matrix.py --no-arch |
jq '.include |= map(
select(
(.sdk != "nodejs" or .language_version != "22") and
(.sdk != "nodejs" or .language_version != "23") and
(.sdk != "python" or .language_version != "3.10") and
(.sdk != "python" or .language_version != "3.13")
)
)') >> "$GITHUB_OUTPUT"
ubi-sdk:
name: UBI SDK images
runs-on: ubuntu-latest
permissions:
id-token: write
needs: define-ubi-matrix
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.define-ubi-matrix.outputs.matrix) }}
steps:
- name: Set image name
run: |
echo "IMAGE_NAME=${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}${{ matrix.suffix }}:${{ env.PULUMI_VERSION }}-ubi" >> $GITHUB_ENV
- name: Set default language version image name
# For the default language version, we also set a default image name that doesn't include the version suffix
if: ${{ (matrix.default == true) && (matrix.suffix != '') }}
run: |
echo "DEFAULT_IMAGE_NAME=${{ env.DOCKER_ORG }}/pulumi-${{ matrix.sdk }}:${{ env.PULUMI_VERSION }}-ubi" >> $GITHUB_ENV
- uses: actions/checkout@master
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Build
# We only build UBI for amd64 due to arm64 builds hanging on `npm
# install -g yarn` with no additional output.
run: |
docker build \
-f docker/${{ matrix.sdk }}/Dockerfile.ubi \
--platform linux/amd64 \
-t ${{ env.IMAGE_NAME }} \
--build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \
--build-arg LANGUAGE_VERSION=${{ matrix.language_version }} \
docker/${{ matrix.sdk }} \
--load
- name: Install go
uses: actions/setup-go@v5
with:
go-version: "1.22"
cache-dependency-path: tests/go.sum
- name: Compile tests
working-directory: tests
run: |
GOOS=linux GOARCH=amd64 go test -c -o /tmp/pulumi-test-containers ./...
- name: Set SDKS_TO_TEST (dotnet)
if: ${{ matrix.sdk == 'dotnet' }}
run: echo "SDKS_TO_TEST=csharp" >> $GITHUB_ENV
- name: Set SDKS_TO_TEST (nodejs)
if: ${{ matrix.sdk == 'nodejs' }}
run: echo "SDKS_TO_TEST=typescript" >> $GITHUB_ENV
- name: Set SDKS_TO_TEST (default)
if: ${{ matrix.sdk != 'dotnet' && matrix.sdk != 'nodejs' }}
run: echo "SDKS_TO_TEST=${{ matrix.sdk}}" >> $GITHUB_ENV
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
role-duration-seconds: 14400 # 4 hours
role-session-name: pulumi-docker-containers@githubActions
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
- name: Authenticate with Google Cloud
uses: google-github-actions/auth@v2
with:
service_account: ${{ env.GCP_SERVICE_ACCOUNT_EMAIL }}
workload_identity_provider: projects/${{ env.GCP_PROJECT_NUMBER
}}/locations/global/workloadIdentityPools/${{ env.GCP_WORKLOAD_IDENTITY_POOL
}}/providers/${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }}
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v2'
- name: Tests
run: |
docker run \
-e RUN_CONTAINER_TESTS=true \
-e IMAGE_VARIANT=pulumi-ubi-${{ matrix.sdk }} \
-e LANGUAGE_VERSION=${{ matrix.language_version }} \
-e SDKS_TO_TEST=${SDKS_TO_TEST} \
-e PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
-e PULUMI_ORG=${PULUMI_ORG} \
-e ARM_CLIENT_ID=${ARM_CLIENT_ID} \
-e ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET} \
-e ARM_TENANT_ID=${ARM_TENANT_ID} \
-e ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID} \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
-e AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN} \
-e AWS_REGION=${AWS_REGION} \
-e GCP_PROJECT_NAME=${GCP_PROJECT_NAME} \
-e GCP_PROJECT_NUMBER=${GCP_PROJECT_NUMBER} \
-e GOOGLE_APPLICATION_CREDENTIALS=/src/creds.json \
--mount type=bind,source=$GOOGLE_APPLICATION_CREDENTIALS,target=/src/creds.json \
--volume /tmp:/src \
--entrypoint /src/pulumi-test-containers \
${{ env.IMAGE_NAME }} \
-test.parallel=1 -test.timeout=1h -test.v -test.run "TestPulumiTemplateTests|TestEnvironment"
- name: Push image
run: |
docker push ${{ env.IMAGE_NAME }}
- name: Push default language version image
if: ${{ (matrix.default == true) && (matrix.suffix != '') }}
run: |
docker tag ${{ env.IMAGE_NAME }} ${{ env.DEFAULT_IMAGE_NAME }}
docker push ${{ env.DEFAULT_IMAGE_NAME }}
start-syncs:
name: Start syncs to other container registries
needs: ["kitchen-sink", "base-manifests", "debian-sdk-manifests", "ubi-sdk"]
runs-on: ubuntu-latest
# This workflow can be triggered by 2 events: workflow_dispatch, i.e., a
# manual run, or repository_dispatch, which is triggered by a Pulumi
# release. In the case of a new Pulumi release (i.e. repository_dispatch),
# we will always want to sync to the other repos. However, in the event of
# a workflow_dispatch we are probably debugging an issue and we do not
# necessarily want to automatically sync to the other repos. Both repo sync
# workflows allow for their own manual trigger (i.e. repository_dispatch),
# so it's not too much work to run the sync workflows manually.
#
# This design choice also allows us avoid having to alter pulumictl to
# accept arbitrary parameters, as we would need to persist the tag_latest
# option from a workflow_dispatch in this workflow to each of the sync
# workflows.
if: ${{ github.event.inputs.force_release || github.event_name == 'repository_dispatch' }}
steps:
- name: Install Pulumictl
uses: jaxxstorm/[email protected]
with:
repo: pulumi/pulumictl
- name: Kick off ECR sync
run: pulumictl dispatch -r pulumi/pulumi-docker-containers -c sync-ecr ${{ env.PULUMI_VERSION }}
- name: Kick off GHCR sync
run: pulumictl dispatch -r pulumi/pulumi-docker-containers -c sync-ghcr ${{ env.PULUMI_VERSION }}