Skip to content

Commit aecde92

Browse files
committed
ci: move qemu images builds into nix-build
Split publish into its own workflow, mimicing AMI Release Nix. We don't need the publish steps most of the time so better to avoid all the unnecessary stuff in this file. When we do want to publish compress the output with zstd since its nice and fast, compresses from ~5G to ~1G and should be fine.
1 parent b712eeb commit aecde92

4 files changed

Lines changed: 180 additions & 111 deletions

File tree

‎.github/workflows/actions.lock‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ workflows:
8787
- 'aws-actions/amazon-ecr-login@v2.1.7'
8888
- 'aws-actions/configure-aws-credentials@v6.3.0'
8989
- 'slackapi/slack-github-action@v4.0.0'
90+
'.github/workflows/qemu-image-release.yml': []
9091
'.github/workflows/test.yml':
9192
- 'actions/checkout@v7.0.1'
9293
- 'aws-actions/configure-aws-credentials@v6.3.0'

‎.github/workflows/nix-build.yml‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ jobs:
231231
- checks-aarch64-darwin
232232
- checks-aarch64-linux
233233
- checks-x86_64-linux
234-
# must always run, otherwise if any of the needs fail then this is skipped and PR is allowed through
234+
# must always run, otherwise if any of the needs fail then this is skipped and PR is allowed through
235235
# not sure what GH's thinking is there that skipped == passed for the branch protection rule...
236236
# insert Mr Incredible meme -> pass is pass, skipped is not passed, PR should not merge
237237
if: always()
@@ -264,6 +264,10 @@ jobs:
264264
DEV_AWS_ROLE: ${{ secrets.DEV_AWS_ROLE }}
265265
NIX_SIGN_SECRET_KEY: ${{ secrets.NIX_SIGN_SECRET_KEY }}
266266

267+
qemu:
268+
needs: builds-aarch64-linux
269+
uses: $/.github/workflows/qemu-image-build.yml
270+
267271
check:
268272
name: Nix CI ✅
269273
if: always()
@@ -272,6 +276,7 @@ jobs:
272276
- amis
273277
- checks
274278
- containers
279+
- qemu
275280
- schema
276281
steps:
277282
- name: Check dependent job results
Lines changed: 44 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,61 @@
11
name: Build QEMU image
22

33
on:
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

2035
permissions:
2136
contents: read
22-
id-token: write
2337

2438
jobs:
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
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: Release QEMU image
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
- release/*
8+
paths:
9+
- ansible/postgres_release.yml
10+
workflow_dispatch:
11+
inputs:
12+
arch:
13+
description: Guest architecture (amd64 is experimental and publishes only to staging)
14+
type: choice
15+
default: arm64
16+
options:
17+
- arm64
18+
- amd64
19+
20+
permissions:
21+
contents: read
22+
23+
jobs:
24+
build:
25+
uses: $/.github/workflows/qemu-image-build.yml
26+
with:
27+
arch: ${{ inputs.arch || 'arm64' }}
28+
publish: true
29+
30+
publish:
31+
needs: build
32+
runs-on: ${{ inputs.arch == 'amd64' && 'blacksmith-16vcpu-ubuntu-2404' || 'arm-native-runner' }}
33+
timeout-minutes: 60
34+
env:
35+
POSTGRES_MAJOR_VERSION: "17"
36+
TARGET_ARCH: ${{ inputs.arch || 'arm64' }}
37+
IMAGE_TAG: ${{ needs.build.outputs.version }}
38+
permissions:
39+
contents: read
40+
id-token: write
41+
42+
steps:
43+
- name: Checkout Repo
44+
uses: actions/checkout@v7.0.1
45+
46+
- name: Install Nix
47+
uses: $/.github/actions/install-nix
48+
49+
- name: Run checks if publishing manually
50+
if: github.event_name == 'workflow_dispatch' && env.TARGET_ARCH == 'arm64'
51+
run: |
52+
SUFFIX=$(nix run nixpkgs#yq -- -e ".postgres_release.postgres$POSTGRES_MAJOR_VERSION" ansible/postgres_release.yml | sed -E 's/[0-9\.]+(.*)$/\1/')
53+
if [[ -z $SUFFIX ]] ; then
54+
echo "Version must include non-numeric characters if published manually."
55+
exit 1
56+
fi
57+
58+
- name: Download disk image
59+
uses: actions/download-artifact@v8.0.2
60+
with:
61+
name: ${{ needs.build.outputs.artifact }}
62+
path: ${{ runner.temp }}/disk-image
63+
64+
- name: Build image
65+
run: |
66+
mkdir -p image-context/output-cloudimg
67+
nix run nixpkgs#zstd -- -d -o image-context/output-cloudimg/packer-cloudimg "$RUNNER_TEMP/disk-image/packer-cloudimg.zst"
68+
docker build --platform "linux/$TARGET_ARCH" -f Dockerfile-kubernetes -t "postgres:$IMAGE_TAG" image-context
69+
70+
- name: configure aws credentials - staging
71+
uses: aws-actions/configure-aws-credentials@v6.3.0
72+
with:
73+
role-to-assume: ${{ secrets.CONTROL_PLANE_DEV_ROLE }}
74+
aws-region: "us-east-1"
75+
76+
- name: Login to Amazon ECR Staging
77+
id: login-ecr-private-dev
78+
uses: aws-actions/amazon-ecr-login@v2.1.7
79+
80+
- name: Push docker image to Amazon ECR
81+
env:
82+
REGISTRY: 812073016711.dkr.ecr.us-east-1.amazonaws.com
83+
REPOSITORY: postgres-vm-image
84+
run: |
85+
docker tag "postgres:$IMAGE_TAG" "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
86+
docker push "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
87+
88+
# TODO (darora): temporarily also push to prod account from here - add a guard to only publish proper tagged releases to prod?
89+
- name: configure aws credentials - prod
90+
if: env.TARGET_ARCH == 'arm64'
91+
uses: aws-actions/configure-aws-credentials@v6.3.0
92+
with:
93+
role-to-assume: ${{ secrets.CONTROL_PLANE_PROD_ROLE }}
94+
aws-region: "us-east-1"
95+
96+
- name: Login to Amazon ECR Prod
97+
if: env.TARGET_ARCH == 'arm64'
98+
id: login-ecr-private-prod
99+
uses: aws-actions/amazon-ecr-login@v2.1.7
100+
101+
- name: Push docker image to Amazon ECR Prod
102+
if: env.TARGET_ARCH == 'arm64'
103+
env:
104+
REGISTRY: 156470330064.dkr.ecr.us-east-1.amazonaws.com
105+
REPOSITORY: postgres-vm-image
106+
run: |
107+
docker tag "postgres:$IMAGE_TAG" "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
108+
docker push "$REGISTRY/$REPOSITORY:$IMAGE_TAG"
109+
110+
notify:
111+
needs: [build, publish]
112+
if: failure()
113+
runs-on: blacksmith-2vcpu-ubuntu-2404
114+
steps:
115+
- name: Slack Notification on Failure
116+
uses: slackapi/slack-github-action@v4.0.0
117+
with:
118+
webhook: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }}
119+
webhook-type: incoming-webhook
120+
payload: |
121+
username: gha-failure
122+
icon_emoji: ':old_man_yells_at_github_actions:'
123+
channel: C0C16MJ8WHX
124+
text: |
125+
*Building Postgres QEMU artifact failed*
126+
*Actions URL:* <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}/checks|${{ github.workflow }}>
127+
*Event:* ${{ github.event_name }}
128+
*Ref:* ${{ github.ref }}
129+
*Commit:* <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>

0 commit comments

Comments
 (0)