Build base images on native hardware #377
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-images: | |
name: "Build heroku-${{ matrix.stack-version }} (${{ matrix.arch }})" | |
needs: | |
- shellcheck | |
runs-on: ${{ matrix.arch == 'arm64' && 'pub-hk-ubuntu-24.04-arm-medium' || 'ubuntu-24.04' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
arch: ["amd64", "arm64"] | |
stack-version: ["20", "22", "24"] | |
exclude: | |
- arch: "arm64" | |
stack-version: "20" | |
- arch: "arm64" | |
stack-version: "22" | |
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 | |
if: github.ref_name == 'main' || github.ref_type == 'tag' | |
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 | |
if: github.ref_name == 'main' || github.ref_type == 'tag' | |
uses: actions/cache/save@v4 | |
with: | |
key: ${{ github.run_id}}-${{ matrix.stack-version }}-${{ matrix.arch }} | |
path: images.tar.zst | |
publish-images: | |
if: github.ref_name == 'main' || github.ref_type == 'tag' | |
name: "Publish heroku-${{ matrix.stack-version }} (${{ matrix.arch }})" | |
needs: | |
- build-images | |
runs-on: ${{ matrix.arch == 'arm64' && 'pub-hk-ubuntu-24.04-arm-medium' || 'ubuntu-24.04' }} | |
env: | |
TAG_SUFFIX: ".${{ github.ref_type == 'tag' && github.ref_name || 'nightly' }}" | |
strategy: | |
fail-fast: false | |
matrix: | |
arch: ["amd64", "arm64"] | |
stack-version: ["20", "22", "24"] | |
exclude: | |
- arch: "arm64" | |
stack-version: "20" | |
- arch: "arm64" | |
stack-version: "22" | |
steps: | |
- 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: | | |
variants=("" "-build") | |
platformSuffix="" | |
if (( ${{ matrix.stack-version }} >= 24 )); then | |
platformSuffix="_linux-${{ matrix.arch }}" | |
else | |
variants+=("-cnb" "-cnb-build") | |
fi | |
for variant in "${variants[@]}"; do | |
srcTag="heroku/heroku:${{ matrix.stack-version}}${variant}" | |
destTag="${srcTag}${platformSuffix}${TAG_SUFFIX}" | |
docker tag "${srcTag}" "${destTag}" | |
docker push "${destTag}" | |
done | |
publish-indicies: | |
if: github.ref_name == 'main' || github.ref_type == 'tag' | |
name: "Publish heroku-${{ matrix.stack-version }} indicies" | |
needs: | |
- publish-images | |
runs-on: ubuntu-24.04 | |
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" | |
docker manifest push "$indexTag" | |
done | |
promote-tags: | |
if: github.ref_type == 'tag' | |
name: "Promote heroku-${{ matrix.stack-version }} tags" | |
needs: | |
- publish-images | |
- publish-indicies | |
runs-on: ubuntu-24.04 | |
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: Install crane | |
uses: buildpacks/github-actions/[email protected] | |
- 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 | |
fi | |
for destTag in "${destTags[@]}"; do | |
srcTag="${destTag}.${{ github.ref_name }}" | |
echo "${srcTag}" "${destTag}" | |
done | |
publish-stack: | |
if: github.ref_type == 'tag' | |
name: "Publish heroku-${{ matrix.stack-version }} stack" | |
needs: | |
- promote-tags | |
runs-on: ubuntu-24.04 | |
strategy: | |
fail-fast: false | |
matrix: | |
stack-version: ["20", "22", "24"] | |
env: | |
STACK: heroku-${{ matrix.stack-version }} | |
MANIFEST_APP_TOKEN: "${{ secrets.MANIFEST_APP_TOKEN }}" | |
MANIFEST_APP_URL: "${{ secrets.MANIFEST_APP_URL }}" | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Pull base images | |
run: | | |
docker pull heroku/heroku:${{matrix.stack-version}} | |
docker pull heroku/heroku:${{matrix.stack-version}}-build | |
- name: Convert docker image and for Git tags release to Heroku staging | |
run: bin/convert-and-publish-to-heroku.sh |