Build base images on native hardware #348
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
name: CI | |
on: | |
push: | |
# Avoid duplicate builds on PRs. | |
branches: | |
- main | |
tags: | |
- v* | |
pull_request: | |
permissions: | |
contents: read | |
jobs: | |
shellcheck: | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Run shellcheck | |
run: find . -type f \( -name "*.sh" -o -path "*/bin/*" \) ! -name '*.jq' | xargs -t shellcheck | |
build: | |
runs-on: ${{ matrix.arch == 'arm64' && 'pub-hk-ubuntu-24.04-arm-medium' || 'ubuntu-24.04' }} | |
needs: | |
- shellcheck | |
env: | |
STACK: heroku-${{ matrix.stack-version }} | |
STACK_VERSION: "${{ matrix.stack-version }}" | |
strategy: | |
fail-fast: false | |
matrix: | |
arch: ["amd64"] | |
stack-version: ["20", "22", "24"] | |
include: | |
- arch: "arm64" | |
stack-version: "24" | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Build images | |
run: bin/build.sh "${{ matrix.stack-version }}" "${{ matrix.arch }}" | |
- name: Check that the generated files are in sync | |
run: |- | |
status="$(git status --porcelain)" | |
if [[ -n "$status" ]]; then | |
echo "Generated files differ from checked-in versions! Run bin/build.sh to regenerate them locally." | |
echo -e "\nChanged files:\n${status}\n" | |
git diff | |
exit 1 | |
fi | |
- name: Export base images from the Docker daemon | |
run: | | |
docker save $(docker images --format '{{.Repository}}:{{.Tag}}' | grep "heroku/heroku:${{ matrix.stack-version }}") | zstd -T0 --long=31 -o images.tar.zst | |
- name: Save base images to the cache | |
uses: actions/cache/save@v4 | |
with: | |
key: ${{ github.run_id}}-${{ matrix.stack-version }}-${{ matrix.arch }} | |
path: images.tar.zst | |
publish-image: | |
if: github.ref_name == 'main' || github.ref_type == 'tag' | |
runs-on: ${{ matrix.arch == 'arm64' && 'pub-hk-ubuntu-24.04-arm-medium' || 'ubuntu-24.04' }} | |
needs: | |
- build | |
env: | |
TAG_SUFFIX: ".${{ github.ref_type == 'tag' && github.ref_name || 'nightly' }}" | |
strategy: | |
fail-fast: false | |
matrix: | |
arch: ["amd64"] | |
stack-version: ["20", "22", "24"] | |
include: | |
- arch: "arm64" | |
stack-version: "24" | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Restore base images from the cache | |
uses: actions/cache/restore@v4 | |
with: | |
fail-on-cache-miss: true | |
key: ${{ github.run_id}}-${{ matrix.stack-version }}-${{ matrix.arch }} | |
path: images.tar.zst | |
env: | |
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1 | |
- name: Load Docker images into the Docker daemon | |
run: zstd -dc --long=31 images.tar.zst | docker load | |
- name: Log into Docker Hub | |
run: echo '${{ secrets.DOCKER_HUB_TOKEN }}' | docker login -u '${{ secrets.DOCKER_HUB_USERNAME }}' --password-stdin | |
- name: Publish base images to registries | |
run: | |
bin/publish-image-group.sh ${{ matrix.stack-version }} ${{ matrix.arch }} "${TAG_SUFFIX}" | |
publish-index: | |
if: github.ref_name == 'main' || github.ref_type == 'tag' | |
runs-on: ubuntu-24.04 | |
needs: | |
- publish-image | |
env: | |
TAG_SUFFIX: ".${{ github.ref_type == 'tag' && github.ref_name || 'nightly' }}" | |
strategy: | |
fail-fast: false | |
matrix: | |
stack-version: ["24"] | |
steps: | |
- name: Log into Docker Hub | |
run: echo '${{ secrets.DOCKER_HUB_TOKEN }}' | docker login -u '${{ secrets.DOCKER_HUB_USERNAME }}' --password-stdin | |
- name: Publish multi-arch image index | |
run: | | |
for variant in ("" "-build"); do | |
indexTag="heroku/heroku:${{ matrix.stack-version }}${variant}${TAG_SUFFIX}" | |
armTag="heroku/heroku:${{ matrix.stack-version }}${variant}_linux-arm64${TAG_SUFFIX}" | |
amdTag="heroku/heroku:${{ matrix.stack-version }}${variant}_linux-amd64${TAG_SUFFIX}" | |
docker manifest create "$indexTag" "$amdTag" "$armTag" | |
done | |
promote-images: | |
if: github.ref_type == 'tag' | |
runs-on: ubuntu-24.04 | |
needs: | |
- publish-image | |
- publish-index | |
strategy: | |
fail-fast: false | |
matrix: | |
stack-version: ["20", "22", "24"] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Log into Docker Hub | |
run: echo '${{ secrets.DOCKER_HUB_TOKEN }}' | docker login -u '${{ secrets.DOCKER_HUB_USERNAME }}' --password-stdin | |
- name: Promote images to stable tag | |
run: | | |
destTags=( ) | |
if (( ${{ matrix.stack-version }} >= 24 )); then | |
for variant in ("" "-build"); do | |
for arch in ("amd64" "arm64"); do | |
destTags+=("heroku/heroku:${{ matrix.stack-version }}${variant}_linux-${arch}") | |
done | |
destTags+=("heroku/heroku:${{ matrix.stack-version }}${variant}") | |
done | |
else | |
for variant in ("" "-build" "-cnb" "-cnb-build"); do | |
destTags+=("heroku/heroku:${{ matrix.stack-version }}${variant}") | |
done | |
end | |
for destTag in "$destTags[@]"; do | |
sourceTag="${destTag}.${{ github.ref_name }}" | |
crane copy "${sourceTag}" "${destTag}" | |
done | |
promote-stack: | |
if: github.ref_type == 'tag' | |
runs-on: ubuntu-24.04 | |
needs: | |
- promote-images | |
env: | |
MANIFEST_APP_TOKEN: "${{ secrets.MANIFEST_APP_TOKEN }}" | |
MANIFEST_APP_URL: "${{ secrets.MANIFEST_APP_URL }}" | |
steps: | |
- name: Convert docker image and for Git tags release to Heroku staging | |
run: bin/convert-and-publish-to-heroku.sh |