Build QEMU image #234
This file contains hidden or 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: Build QEMU image | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| - release/* | |
| paths: | |
| - '.github/workflows/qemu-image-build.yml' | |
| - 'qemu-arm64-nix.pkr.hcl' | |
| - 'common-nix.vars.pkr.hcl' | |
| - 'ansible/vars.yml' | |
| - 'scripts/*' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| id-token: write | |
| jobs: | |
| build: | |
| strategy: | |
| matrix: | |
| postgres_version: [17] | |
| runs-on: arm-native-runner | |
| timeout-minutes: 150 | |
| permissions: | |
| contents: write | |
| packages: write | |
| id-token: write | |
| steps: | |
| - name: Checkout Repo | |
| uses: supabase/postgres/.github/actions/shared-checkout@HEAD | |
| - name: Configure AWS credentials for image check | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.CONTROL_PLANE_DEV_ROLE }} | |
| aws-region: "us-east-1" | |
| - name: Check if image already exists in ECR | |
| id: check-image | |
| env: | |
| AWS_REGION: us-east-1 | |
| REPOSITORY: postgres-vm-image | |
| run: | | |
| VERSION=$(yq '.postgres_release["postgres${{ matrix.postgres_version }}"]' ansible/vars.yml | tr -d '"') | |
| if aws ecr describe-images --repository-name "$REPOSITORY" --image-ids imageTag="$VERSION" --region "$AWS_REGION" 2>/dev/null; then | |
| echo "::notice title=Qemu image::Image with tag $VERSION already exists. Skipping build. Please update the version in ansible/vars.yml if you want to upload a new image." | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Image with tag $VERSION does not exist. Proceeding with build." | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - uses: DeterminateSystems/nix-installer-action@main | |
| if: steps.check-image.outputs.skip == 'false' | |
| - name: Run checks if triggered manually | |
| if: ${{ github.event_name == 'workflow_dispatch' && steps.check-image.outputs.skip == 'false' }} | |
| run: | | |
| SUFFIX=$(yq ".postgres_release[\"postgres${{ matrix.postgres_version }}\"]" ansible/vars.yml | sed -E 's/[0-9\.]+(.*)$/\1/') | |
| if [[ -z $SUFFIX ]] ; then | |
| echo "Version must include non-numeric characters if built manually." | |
| exit 1 | |
| fi | |
| - name: enable KVM support | |
| if: steps.check-image.outputs.skip == 'false' | |
| run: | | |
| sudo chown runner /dev/kvm | |
| sudo chmod 666 /dev/kvm | |
| - name: Set PostgreSQL version environment variable | |
| if: steps.check-image.outputs.skip == 'false' | |
| run: | | |
| echo "POSTGRES_MAJOR_VERSION=${{ matrix.postgres_version }}" >> "$GITHUB_ENV" | |
| echo "EXECUTION_ID=${{ github.run_id }}-${{ matrix.postgres_version }}" >> "$GITHUB_ENV" | |
| - name: Generate common-nix.vars.pkr.hcl | |
| if: steps.check-image.outputs.skip == 'false' | |
| run: | | |
| curl -L https://github.com/mikefarah/yq/releases/download/v4.45.1/yq_linux_arm64 -o yq && chmod +x yq | |
| PG_VERSION=$(./yq '.postgres_release["postgres${{ matrix.postgres_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 "postgres-major-version = \"${POSTGRES_MAJOR_VERSION}\"" >> common-nix.vars.pkr.hcl | |
| # Ensure there's a newline at the end of the file | |
| echo "" >> common-nix.vars.pkr.hcl | |
| # TODO (darora): not quite sure why I'm having to uninstall and re-install these deps, but the build fails w/o this | |
| - name: Install dependencies | |
| if: steps.check-image.outputs.skip == 'false' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get remove -y qemu-efi-aarch64 cloud-image-utils qemu-system-arm qemu-utils | |
| sudo apt-get install -y qemu-efi-aarch64 cloud-image-utils qemu-system-arm qemu-utils | |
| - name: Build QEMU artifact | |
| if: steps.check-image.outputs.skip == 'false' | |
| run: | | |
| make init | |
| GIT_SHA=${{github.sha}} | |
| export PACKER_LOG=1 | |
| packer build -var "git_sha=${GIT_SHA}" -var-file="common-nix.vars.pkr.hcl" qemu-arm64-nix.pkr.hcl | |
| - name: Grab release version | |
| if: steps.check-image.outputs.skip == 'false' | |
| id: process_release_version | |
| run: | | |
| VERSION=$(sed -e 's/postgres-version = "\(.*\)"/\1/g' common-nix.vars.pkr.hcl) | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Login to Amazon ECR | |
| if: steps.check-image.outputs.skip == 'false' | |
| id: login-ecr-private-dev | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Build image | |
| if: steps.check-image.outputs.skip == 'false' | |
| env: | |
| IMAGE_TAG: ${{ steps.process_release_version.outputs.version }} | |
| run: | | |
| docker build -f Dockerfile-kubernetes -t "postgres:$IMAGE_TAG" . | |
| - name: Push docker image to Amazon ECR | |
| if: steps.check-image.outputs.skip == 'false' | |
| env: | |
| REGISTRY: 812073016711.dkr.ecr.us-east-1.amazonaws.com | |
| REPOSITORY: postgres-vm-image | |
| IMAGE_TAG: ${{ steps.process_release_version.outputs.version }} | |
| run: | | |
| docker tag "postgres:$IMAGE_TAG" "$REGISTRY/$REPOSITORY:$IMAGE_TAG" | |
| docker push "$REGISTRY/$REPOSITORY:$IMAGE_TAG" | |
| # TODO (darora): temporarily also push to prod account from here - add a guard to only publish proper tagged releases to prod? | |
| - name: configure aws credentials - prod | |
| if: steps.check-image.outputs.skip == 'false' | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.CONTROL_PLANE_PROD_ROLE }} | |
| aws-region: "us-east-1" | |
| - name: Login to Amazon ECR | |
| if: steps.check-image.outputs.skip == 'false' | |
| id: login-ecr-private-prod | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Push docker image to Amazon ECR | |
| if: steps.check-image.outputs.skip == 'false' | |
| env: | |
| REGISTRY: 156470330064.dkr.ecr.us-east-1.amazonaws.com | |
| REPOSITORY: postgres-vm-image | |
| IMAGE_TAG: ${{ steps.process_release_version.outputs.version }} | |
| run: | | |
| docker tag "postgres:$IMAGE_TAG" "$REGISTRY/$REPOSITORY:$IMAGE_TAG" | |
| docker push "$REGISTRY/$REPOSITORY:$IMAGE_TAG" | |
| - name: Slack Notification on Failure | |
| 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 QEMU artifact failed' | |
| SLACK_FOOTER: '' | |
| - name: Cleanup resources after build | |
| if: ${{ always() }} | |
| run: | | |
| aws ec2 describe-instances --filters "Name=tag:packerExecutionId,Values=${EXECUTION_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -r aws ec2 terminate-instances --instance-ids | |
| - name: Cleanup resources on build cancellation | |
| if: ${{ cancelled() }} | |
| run: | | |
| aws ec2 describe-instances --filters "Name=tag:packerExecutionId,Values=${EXECUTION_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -r aws ec2 terminate-instances --instance-ids |