Skip to content

chore: output single matrix for each version #11

chore: output single matrix for each version

chore: output single matrix for each version #11

name: Release all major versions on Dockerhub
on:
push:
branches:
- develop
- release/*
- sam/docker-oriole17
paths:
- '**'
workflow_dispatch:
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
matrix_config: ${{ steps.set-matrix.outputs.matrix_config }}
steps:
- name: Checkout Repo
uses: actions/checkout@v3
- uses: DeterminateSystems/nix-installer-action@main
- name: Generate build matrix
id: set-matrix
run: |
# Get all postgres versions from vars.yml
VERSIONS=$(nix run nixpkgs#yq -- '.postgres_major[]' ansible/vars.yml)
# Create matrix config
MATRIX_CONFIG="{"
MATRIX_CONFIG+="\"include\":["
FIRST=true
while IFS= read -r version; do
# Remove quotes from version
version=$(echo "$version" | tr -d '"')
# Simply look for Dockerfile-{version}
dockerfile="Dockerfile-${version}"
# Check if Dockerfile exists
if [ -f "$dockerfile" ]; then
if [ "$FIRST" = true ]; then
FIRST=false
else
MATRIX_CONFIG+=","
fi
MATRIX_CONFIG+="{\"version\":\"$version\",\"dockerfile\":\"$dockerfile\"}"
fi
done <<< "$VERSIONS"
MATRIX_CONFIG+="]}"
# Output the matrix configuration
echo "matrix_config=$MATRIX_CONFIG" >> $GITHUB_OUTPUT
build:
needs: prepare
strategy:
matrix: ${{ fromJson(needs.prepare.outputs.matrix_config) }}
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.create-matrix.outputs.matrix }}
build_args: ${{ steps.args.outputs.result }}
steps:
- uses: actions/checkout@v3
- uses: DeterminateSystems/nix-installer-action@main
- name: Set PostgreSQL version environment variable
run: echo "POSTGRES_MAJOR_VERSION=${{ matrix.version }}" >> $GITHUB_ENV
- name: Generate common-nix.vars.pkr.hcl
run: |
PG_VERSION=$(nix run nixpkgs#yq -- '.postgres_release["postgres${{ matrix.version }}"]' ansible/vars.yml)
PG_VERSION=$(echo $PG_VERSION | tr -d '"') # Remove any surrounding quotes
echo 'postgres-version = "'$PG_VERSION'"' > common-nix.vars.pkr.hcl
echo "" >> common-nix.vars.pkr.hcl
- id: settings
run: sed -r 's/(\s|\")+//g' common-nix.vars.pkr.hcl >> $GITHUB_OUTPUT
- id: args
uses: mikefarah/yq@master
with:
cmd: yq 'to_entries | map(select(.value|type == "!!str")) | map(.key + "=" + .value) | join("\n")' 'ansible/vars.yml'
- id: create-matrix
run: |
# Create a matrix entry for this version
matrix_entry="{\"version\":\"${{ matrix.version }}\",\"image_tag\":\"supabase/postgres:${{ steps.settings.outputs.postgres-version }}\"}"
echo "matrix={\"include\":[$matrix_entry]}" >> $GITHUB_OUTPUT
collect_versions:
needs: build
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.create-final-matrix.outputs.matrix }}
steps:
- id: create-final-matrix
run: |
# Combine all matrix configurations from build job
MATRIX="{\"include\":["
FIRST=true
for matrix_config in ${{ toJSON(needs.build.outputs.matrix) }}; do
if [ "$FIRST" = true ]; then
FIRST=false
else
MATRIX+=","
fi
# Extract the include array content from each matrix config
include_content=$(echo "$matrix_config" | jq -r '.include[]')
MATRIX+="$include_content"
done
# Add architecture combinations for each version
FINAL_MATRIX="{\"include\":["
FIRST=true
echo "$MATRIX]}" | jq -c '.include[]' | while read -r entry; do
version=$(echo "$entry" | jq -r '.version')
image_tag=$(echo "$entry" | jq -r '.image_tag')
# Add amd64 entry
if [ "$FIRST" = true ]; then
FIRST=false
else
FINAL_MATRIX+=","
fi
FINAL_MATRIX+="{\"version\":\"$version\",\"image_tag\":\"$image_tag\",\"arch\":\"amd64\",\"runner\":[\"self-hosted\",\"X64\"]}"
# Add arm64 entry
FINAL_MATRIX+=",{\"version\":\"$version\",\"image_tag\":\"$image_tag\",\"arch\":\"arm64\",\"runner\":\"arm-runner\"}"
done
FINAL_MATRIX+="]}"
# Output the final matrix
echo "matrix=$FINAL_MATRIX" >> $GITHUB_OUTPUT
build_release_image:
needs: collect_versions
strategy:
matrix: ${{ fromJson(needs.collect_versions.outputs.matrix) }}
runs-on: ${{ matrix.runner }}
timeout-minutes: 180
steps:
- uses: actions/checkout@v3
- run: docker context create builders
- uses: docker/setup-buildx-action@v3
with:
endpoint: builders
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- id: build
uses: docker/build-push-action@v5
with:
push: true
build-args: |
${{ needs.build.outputs.build_args }}
target: production
tags: ${{ matrix.image_tag }}_${{ matrix.arch }}
platforms: linux/${{ matrix.arch }}
cache-from: type=gha,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
file: Dockerfile-${{ matrix.version }}
- name: Slack Notification
if: ${{ failure() }}
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }}
SLACK_USERNAME: "gha-failures-notifier"
SLACK_COLOR: "danger"
SLACK_MESSAGE: "Building Postgres ${{ matrix.arch }} image failed for version ${{ matrix.version }}"
SLACK_FOOTER: ""
merge_manifest:
needs: [build, build_release_image]
strategy:
matrix:
image_tag: ${{ fromJson(needs.collect_versions.outputs.matrix) }}
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Merge multi-arch manifests
run: |
docker buildx imagetools create -t ${{ matrix.image_tag }} \
${{ matrix.image_tag }}_amd64 \
${{ matrix.image_tag }}_arm64
- name: Slack Notification
if: ${{ failure() }}
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }}
SLACK_USERNAME: "gha-failures-notifier"
SLACK_COLOR: "danger"
SLACK_MESSAGE: "Building Postgres image failed for version ${{ matrix.version }}"
SLACK_FOOTER: ""
publish:
needs: [build, merge_manifest]
uses: ./.github/workflows/mirror.yml
with:
version: ${{ needs.build.outputs.docker_version }}
secrets: inherit