11name : Build QEMU image
22
33on :
4- push :
5- branches :
6- - develop
7- - release/*
8- paths :
9- - ansible/postgres_release.yml
4+ workflow_call :
5+ inputs :
6+ arch :
7+ description : Guest architecture (amd64 is experimental and publishes only to staging)
8+ type : string
9+ default : arm64
10+ publish :
11+ description : Upload the built disk image as an artifact for the release workflow
12+ type : boolean
13+ default : false
14+ outputs :
15+ version :
16+ description : Image tag for this build
17+ value : ${{ jobs.build.outputs.version }}
18+ artifact :
19+ description : Name of the uploaded disk image artifact (empty unless publish was set)
20+ value : ${{ jobs.build.outputs.artifact }}
1021 workflow_dispatch :
1122 inputs :
1223 arch :
13- description : ' Guest architecture (amd64 is experimental and publishes only to staging)'
24+ description : Guest architecture (amd64 is experimental and publishes only to staging)
1425 type : choice
1526 default : arm64
1627 options :
1728 - arm64
1829 - amd64
30+ publish :
31+ description : Upload the built disk image as an artifact for the release workflow
32+ type : boolean
33+ default : false
1934
2035permissions :
2136 contents : read
22- id-token : write
2337
2438jobs :
25- prepare :
26- runs-on : blacksmith-2vcpu-ubuntu-2404
27- outputs :
28- postgres_versions : ${{ steps.set-versions.outputs.postgres_versions }}
29- steps :
30- - name : Checkout Repo
31- uses : actions/checkout@v7.0.1
32-
33- - name : Set PostgreSQL versions - only builds pg17 atm
34- id : set-versions
35- run : |
36- VERSIONS=$(yq -e -o=json -I=0 '[.postgres_major[1]]' ansible/vars.yml)
37- echo "postgres_versions=$VERSIONS" >> $GITHUB_OUTPUT
38-
3939 build :
40- needs : prepare
41- strategy :
42- matrix :
43- postgres_version : ${{ fromJson(needs.prepare.outputs.postgres_versions) }}
44- arch : ["${{ inputs.arch || 'arm64' }}"]
45- runs-on : ${{ matrix.arch == 'amd64' && 'blacksmith-16vcpu-ubuntu-2404' || 'arm-native-runner' }}
40+ runs-on : ${{ inputs.arch == 'amd64' && 'blacksmith-16vcpu-ubuntu-2404' || 'arm-native-runner' }}
4641 env :
47- TARGET_ARCH : ${{ matrix.arch }}
42+ # only builds pg17 atm
43+ POSTGRES_MAJOR_VERSION : " 17"
44+ TARGET_ARCH : ${{ inputs.arch || 'arm64' }}
4845 timeout-minutes : 150
46+ outputs :
47+ version : ${{ steps.process_release_version.outputs.version }}
48+ artifact : ${{ inputs.publish && format('qemu-image-{0}', inputs.arch || 'arm64') || '' }}
4949 permissions :
50- contents : write
51- packages : write
52- id-token : write
50+ contents : read
5351
5452 steps :
5553 - name : Checkout Repo
5654 uses : actions/checkout@v7.0.1
5755
58- - name : enable KVM support
59- run : |
60- sudo chown runner /dev/kvm
61- sudo chmod 666 /dev/kvm
62-
63- - name : Set PostgreSQL version environment variable
64- run : |
65- echo "POSTGRES_MAJOR_VERSION=${{ matrix.postgres_version }}" >> $GITHUB_ENV
66-
6756 - name : Install Nix
6857 uses : $/.github/actions/install-nix
6958
70- - name : Run checks if triggered manually
71- if : ${{ github.event_name == 'workflow_dispatch' && matrix.arch == 'arm64' }}
72- run : |
73- SUFFIX=$(nix run nixpkgs#yq -- -e '.postgres_release.postgres${{ matrix.postgres_version }}' ansible/postgres_release.yml | sed -E 's/[0-9\.]+(.*)$/\1/')
74- if [[ -z $SUFFIX ]] ; then
75- echo "Version must include non-numeric characters if built manually."
76- exit 1
77- fi
78-
7959 - name : Verify QEMU can use KVM
8060 shell : bash
8161 run : |
@@ -99,81 +79,35 @@ jobs:
9979 - name : Build QEMU artifact
10080 env :
10181 GIT_SHA : ${{ steps.resolve-git-sha.outputs.sha }}
102- run : BUILD_QEMU_IMAGE_HW_VIRT_ONLY=1 nix run .#build-qemu-image "${{ matrix.postgres_version }} " "$TARGET_ARCH"
82+ run : BUILD_QEMU_IMAGE_HW_VIRT_ONLY=1 nix run .#build-qemu-image "$POSTGRES_MAJOR_VERSION " "$TARGET_ARCH"
10383
10484 - name : Grab release version
10585 id : process_release_version
10686 run : |
107- PG_VERSION=$(nix run nixpkgs#yq -- -er ' .postgres_release.postgres${{ matrix.postgres_version }}' ansible/postgres_release.yml)
87+ PG_VERSION=$(nix run nixpkgs#yq -- -er " .postgres_release.postgres$POSTGRES_MAJOR_VERSION" ansible/postgres_release.yml)
10888 if [[ "$TARGET_ARCH" == amd64 ]]; then
10989 PG_VERSION="$PG_VERSION-amd64-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
11090 fi
11191 echo "version=$PG_VERSION" >> $GITHUB_OUTPUT
11292
113- - name : configure aws credentials - staging
114- if : ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/') }}
115- uses : aws-actions/configure-aws-credentials@v6.3.0
116- with :
117- role-to-assume : ${{ secrets.CONTROL_PLANE_DEV_ROLE }}
118- aws-region : " us-east-1"
119-
120- - name : Login to Amazon ECR Staging
121- if : ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/') }}
122- id : login-ecr-private-dev
123- uses : aws-actions/amazon-ecr-login@v2.1.7
124-
12593 - name : Build image
12694 env :
12795 IMAGE_TAG : ${{ steps.process_release_version.outputs.version }}
12896 run : |
12997 docker build --platform "linux/$TARGET_ARCH" -f Dockerfile-kubernetes -t "postgres:$IMAGE_TAG" packer-work-qemu-*
13098
131- - name : Push docker image to Amazon ECR
132- if : ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/') }}
133- env :
134- REGISTRY : 812073016711.dkr.ecr.us-east-1.amazonaws.com
135- REPOSITORY : postgres-vm-image
136- IMAGE_TAG : ${{ steps.process_release_version.outputs.version }}
137- run : |
138- docker tag "postgres:$IMAGE_TAG" "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
139- docker push "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
140-
141- # TODO (darora): temporarily also push to prod account from here - add a guard to only publish proper tagged releases to prod?
142- - name : configure aws credentials - prod
143- if : ${{ matrix.arch == 'arm64' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/')) }}
144- uses : aws-actions/configure-aws-credentials@v6.3.0
145- with :
146- role-to-assume : ${{ secrets.CONTROL_PLANE_PROD_ROLE }}
147- aws-region : " us-east-1"
148-
149- - name : Login to Amazon ECR Prod
150- if : ${{ matrix.arch == 'arm64' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/')) }}
151- id : login-ecr-private-prod
152- uses : aws-actions/amazon-ecr-login@v2.1.7
153-
154- - name : Push docker image to Amazon ECR Prod
155- if : ${{ matrix.arch == 'arm64' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/')) }}
156- env :
157- REGISTRY : 156470330064.dkr.ecr.us-east-1.amazonaws.com
158- REPOSITORY : postgres-vm-image
159- IMAGE_TAG : ${{ steps.process_release_version.outputs.version }}
99+ - name : Compress disk image
100+ if : inputs.publish
160101 run : |
161- docker tag "postgres:$IMAGE_TAG" "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
162- docker push "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
102+ nix run nixpkgs#zstd -- -T0 -o "$RUNNER_TEMP/packer-cloudimg.zst" packer-work-qemu-*/output-cloudimg/packer-cloudimg
163103
164- - name : Slack Notification on Failure
165- if : ${{ failure() }}
166- uses : slackapi/slack-github-action@v4 .0.0
104+ - name : Upload disk image
105+ if : inputs.publish
106+ uses : actions/upload-artifact@v7 .0.2
167107 with :
168- webhook : ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }}
169- webhook-type : incoming-webhook
170- payload : |
171- username: gha-failure
172- icon_emoji: ':old_man_yells_at_github_actions:'
173- channel: C0C16MJ8WHX
174- text: |
175- *Building Postgres QEMU artifact failed*
176- *Actions URL:* <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}/checks|${{ github.workflow }}>
177- *Event:* ${{ github.event_name }}
178- *Ref:* ${{ github.ref }}
179- *Commit:* <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>
108+ name : qemu-image-${{ env.TARGET_ARCH }}
109+ path : ${{ runner.temp }}/packer-cloudimg.zst
110+ # already zstd-compressed
111+ compression-level : 0
112+ retention-days : 3
113+ if-no-files-found : error
0 commit comments