Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions .github/workflows/build-commitfest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
pg_branch: ${{ env.BRANCH }}
minimal_tag: ${{ env.registry }}/postgresql-trunk:${{ env.PG_MAJOR }}-minimal-${{ env.TAG }}
standard_tag: ${{ env.registry }}/postgresql-trunk:${{ env.PG_MAJOR }}-standard-${{ env.TAG }}
postgis_tag: ${{ env.registry }}/postgresql-trunk:${{ env.PG_MAJOR }}-postgis-${{ env.TAG }}
steps:
- name: Checkout Code
uses: actions/checkout@v7
Expand Down Expand Up @@ -69,23 +70,45 @@ jobs:
pg_branch: ${{ needs.prepare.outputs.pg_branch }}
pg_major: ${{ needs.prepare.outputs.pg_major }}
revision: ${{ github.sha }}
minimal_tags: ${{ needs.prepare.outputs.minimal_tag }}
standard_tags: ${{ needs.prepare.outputs.standard_tag }}
targets: |
minimal:${{ needs.prepare.outputs.minimal_tag }}
standard:${{ needs.prepare.outputs.standard_tag }}

# PostGIS periodically fails to build against PostgreSQL trunk. Kept as its
# own best-effort job so a break there doesn't fail this run or block the
# minimal/standard images above. See #158.
build-postgis:
name: Build PostGIS image for the patch (best-effort)
needs: prepare
uses: ./.github/workflows/reusable-build.yml
permissions:
contents: read
packages: write
with:
pg_repo: https://github.com/postgresql-cfbot/postgresql.git
pg_branch: ${{ needs.prepare.outputs.pg_branch }}
pg_major: ${{ needs.prepare.outputs.pg_major }}
revision: ${{ github.sha }}
targets: |
postgis:${{ needs.prepare.outputs.postgis_tag }}
best_effort: true

generate-summary:
name: Commitfest Image Build summary
runs-on: ubuntu-24.04
needs:
- build-pg
- build-postgis
steps:
- name: Output summary
env:
INPUT_PATCH_ID: ${{ github.event.inputs.patch_id }}
BUILD_PG_IMAGES: ${{ needs.build-pg.outputs.images }}
BUILD_POSTGIS_IMAGES: ${{ needs.build-postgis.outputs.images }}
run: |
commitFestPatchID="${INPUT_PATCH_ID}"
commitFestURL="https://commitfest.postgresql.org/patch/${commitFestPatchID}"
images="${BUILD_PG_IMAGES}"
images="${BUILD_PG_IMAGES} ${BUILD_POSTGIS_IMAGES}"
images_list="$(echo $images | tr ' ' '\n' | sed 's/^/https:\/\//')"
minimalImage="$(echo $images | tr ' ' '\n' | grep minimal)"

Expand Down
29 changes: 26 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
pg_major: ${{ env.PG_MAJOR }}
minimal_tag: ${{ env.registry }}/postgresql-trunk:${{ env.PG_MAJOR }}-minimal-${{ github.run_number }}
standard_tag: ${{ env.registry }}/postgresql-trunk:${{ env.PG_MAJOR }}-standard-${{ github.run_number }}
postgis_tag: ${{ env.registry }}/postgresql-trunk:${{ env.PG_MAJOR }}-postgis-${{ github.run_number }}
steps:
- name: Checkout Code
uses: actions/checkout@v7
Expand Down Expand Up @@ -64,23 +65,45 @@ jobs:
pg_branch: ${{ github.event.inputs.pg_branch }}
pg_major: ${{ needs.prepare.outputs.pg_major }}
revision: ${{ github.sha }}
minimal_tags: ${{ needs.prepare.outputs.minimal_tag }}
standard_tags: ${{ needs.prepare.outputs.standard_tag }}
targets: |
minimal:${{ needs.prepare.outputs.minimal_tag }}
standard:${{ needs.prepare.outputs.standard_tag }}

# PostGIS periodically fails to build against PostgreSQL trunk. Kept as its
# own best-effort job so a break there doesn't fail this run or block the
# minimal/standard images above. See #158.
build-postgis:
name: Build PostGIS image from sources (best-effort)
needs: prepare
uses: ./.github/workflows/reusable-build.yml
permissions:
contents: read
packages: write
with:
pg_repo: ${{ github.event.inputs.pg_repo }}
pg_branch: ${{ github.event.inputs.pg_branch }}
pg_major: ${{ needs.prepare.outputs.pg_major }}
revision: ${{ github.sha }}
targets: |
postgis:${{ needs.prepare.outputs.postgis_tag }}
best_effort: true

generate-summary:
name: PostgreSQL Image Build summary
runs-on: ubuntu-24.04
needs:
- prepare
- build-pg
- build-postgis
steps:
- name: Output summary
env:
BUILD_PG_MAJOR: ${{ needs.prepare.outputs.pg_major }}
BUILD_PG_IMAGES: ${{ needs.build-pg.outputs.images }}
BUILD_POSTGIS_IMAGES: ${{ needs.build-postgis.outputs.images }}
run: |
pg_major="${BUILD_PG_MAJOR}"
images="${BUILD_PG_IMAGES}"
images="${BUILD_PG_IMAGES} ${BUILD_POSTGIS_IMAGES}"
images_list="$(echo $images | tr ' ' '\n' | sed 's/^/https:\/\//')"
minimalImage="$(echo $images | tr ' ' '\n' | grep minimal)"

Expand Down
27 changes: 24 additions & 3 deletions .github/workflows/continuous-delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jobs:
barman_plugin: ${{ env.BARMAN_PLUGIN }}
minimal_tags: ${{ env.MINIMAL_TAGS }}
standard_tags: ${{ env.STANDARD_TAGS }}
postgis_tags: ${{ env.POSTGIS_TAGS }}
steps:
- name: Checkout Code
uses: actions/checkout@v7
Expand Down Expand Up @@ -74,7 +75,7 @@ jobs:
run: |
registry="ghcr.io/${{ github.repository_owner }}/postgresql-trunk"
timestamp="$(date -u +%Y%m%d%H%M)"
for tgt in MINIMAL STANDARD; do
for tgt in MINIMAL STANDARD POSTGIS; do
lower="${tgt,,}"
echo "${tgt}_TAGS=${registry}:${PG_MAJOR}-${lower}-${DISTRO},${registry}:${PG_MAJOR}-${timestamp}-${lower}-${DISTRO}" >> $GITHUB_ENV
done
Expand All @@ -89,12 +90,32 @@ jobs:
with:
pg_major: ${{ needs.prepare.outputs.pg_major }}
revision: ${{ github.sha }}
minimal_tags: ${{ needs.prepare.outputs.minimal_tags }}
standard_tags: ${{ needs.prepare.outputs.standard_tags }}
targets: |
minimal:${{ needs.prepare.outputs.minimal_tags }}
standard:${{ needs.prepare.outputs.standard_tags }}
# On pull_request runs, only build each arch to validate the Dockerfile
# compiles — don't push anything or publish a multi-arch manifest.
push: ${{ github.event_name != 'pull_request' }}

# PostGIS periodically fails to build against PostgreSQL trunk. It's built
# as its own job, independent from build-pg, so a break there (best_effort
# keeps it from failing this run) doesn't block minimal/standard image
# publishing or the E2E job below, which only depends on build-pg. See #158.
build-postgis:
name: Build the Trunk of PostgreSQL (PostGIS, best-effort)
needs: prepare
uses: ./.github/workflows/reusable-build.yml
permissions:
contents: read
packages: write
with:
pg_major: ${{ needs.prepare.outputs.pg_major }}
revision: ${{ github.sha }}
targets: |
postgis:${{ needs.prepare.outputs.postgis_tags }}
push: ${{ github.event_name != 'pull_request' }}
best_effort: true

select-pg-image:
name: Select the image built for E2E
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
Expand Down
61 changes: 41 additions & 20 deletions .github/workflows/reusable-build.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
name: Reusable Multi-Arch PostgreSQL Build

# Builds the minimal/standard images for linux/amd64 and linux/arm64
# Builds one or more docker-bake.hcl targets for linux/amd64 and linux/arm64
# natively (one arch per job, no QEMU emulation) and publishes a multi-arch
# manifest list for each requested tag by merging the two per-arch images
# with `docker buildx imagetools create`.
#
# PostGIS is currently excluded from the default docker-bake.hcl matrix
# (see #158), so it isn't wired through here either.
#
# Compiling PostgreSQL from source is CPU-bound, so cross-building linux/arm64
# under QEMU emulation on an amd64 runner would be dramatically slower than a
# native build. This workflow instead relies on GitHub-hosted native arm64
# runners (`ubuntu-24.04-arm`) for the arm64 leg.
#
# `best_effort: true` lets a caller build a target (e.g. postgis, which
# periodically fails against PostgreSQL trunk -- see #158) without a failure
# here failing the calling workflow run. This has to live inside this
# workflow's own jobs, rather than as `continue-on-error` on the caller's job,
# because GitHub Actions doesn't allow `continue-on-error` on a job that calls
# a reusable workflow via `uses:`.

on:
workflow_call:
Expand All @@ -34,19 +38,20 @@ on:
description: "Value used for the org.opencontainers.image.revision label/annotation"
required: true
type: string
minimal_tags:
description: "Comma-separated list of final (arch-less) tags for the minimal image"
required: true
type: string
standard_tags:
description: "Comma-separated list of final (arch-less) tags for the standard image"
targets:
description: "One '<docker-bake.hcl target>:<comma-separated final (arch-less) tags>' entry per line, e.g. 'minimal:tag1,tag2'"
required: true
type: string
push:
description: "Whether to push the built images. When false, each arch is only built (e.g. for PR validation) and no multi-arch manifest is published"
required: false
type: boolean
default: true
best_effort:
description: "When true, a build/publish failure doesn't fail this workflow (and so doesn't fail a caller job that just `uses:` it -- GitHub Actions doesn't allow `continue-on-error` on a job that calls a reusable workflow). Use for targets that are allowed to be broken, like postgis (#158)."
required: false
type: boolean
default: false
outputs:
images:
description: "Newline-separated list of the final multi-arch images that were built and pushed (empty when push=false)"
Expand All @@ -62,6 +67,7 @@ permissions: {}
jobs:
build:
name: Build (linux/${{ matrix.arch }})
continue-on-error: ${{ inputs.best_effort }}
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -90,30 +96,42 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

# For each image flavor, each tag is appended with
# an "-$arch" suffix (e.g. ...:19-minimal-trixie-arm64).
# For each image flavor, each tag is appended with an "-$arch" suffix
# (e.g. ...:19-minimal-trixie-arm64). `docker/bake-action` only builds the
# "default" group (docker-bake.hcl's `target "default"` matrix) unless
# told otherwise, so also collect the bake target names to build
# explicitly -- this is what lets a caller build just "postgis", which is
# intentionally kept out of the "default" group (see docker-bake.hcl).
- name: Compute bake overrides
id: overrides
env:
ARCH: ${{ matrix.arch }}
PG_REPO: ${{ inputs.pg_repo }}
PG_BRANCH: ${{ inputs.pg_branch }}
MINIMAL_TAGS: ${{ inputs.minimal_tags }}
STANDARD_TAGS: ${{ inputs.standard_tags }}
TARGETS: ${{ inputs.targets }}
run: |
{
echo "targets<<EOF"
while IFS= read -r target_tags; do
[[ -z "$target_tags" ]] && continue
echo "${target_tags%%:*}"
done <<< "$TARGETS"
echo "EOF"
} >> "$GITHUB_OUTPUT"
{
echo "set<<EOF"
echo "*.platform=linux/${ARCH}"
echo "*.args.PG_REPO=${PG_REPO}"
echo "*.args.PG_BRANCH=${PG_BRANCH}"
for target_tags in "minimal:${MINIMAL_TAGS}" "standard:${STANDARD_TAGS}"; do
while IFS= read -r target_tags; do
[[ -z "$target_tags" ]] && continue
target="${target_tags%%:*}"
tags="${target_tags#*:}"
IFS=',' read -ra tag_list <<< "$tags"
for tag in "${tag_list[@]}"; do
echo "${target}.tags=${tag}-${ARCH}"
done
done
done <<< "$TARGETS"
echo "EOF"
} >> "$GITHUB_OUTPUT"

Expand All @@ -124,13 +142,15 @@ jobs:
revision: ${{ inputs.revision }}
pgMajor: ${{ inputs.pg_major }}
with:
targets: ${{ steps.overrides.outputs.targets }}
set: ${{ steps.overrides.outputs.set }}
push: ${{ inputs.push }}

merge:
name: Publish multi-arch manifests
if: inputs.push
needs: build
continue-on-error: ${{ inputs.best_effort }}
runs-on: ubuntu-24.04
permissions:
contents: read
Expand All @@ -151,11 +171,12 @@ jobs:
- name: Create and push multi-arch manifests
id: merge
env:
MINIMAL_TAGS: ${{ inputs.minimal_tags }}
STANDARD_TAGS: ${{ inputs.standard_tags }}
TARGETS: ${{ inputs.targets }}
run: |
images=()
for tags in "$MINIMAL_TAGS" "$STANDARD_TAGS"; do
while IFS= read -r target_tags; do
[[ -z "$target_tags" ]] && continue
tags="${target_tags#*:}"
IFS=',' read -ra tag_list <<< "$tags"
for tag in "${tag_list[@]}"; do
docker buildx imagetools create \
Expand All @@ -164,7 +185,7 @@ jobs:
"$tag-arm64"
images+=("$tag")
done
done
done <<< "$TARGETS"
{
echo 'images<<EOF'
printf '%s\n' "${images[@]}"
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,21 @@ image.

If you want to build these images locally, first make sure you meet the
following [prerequisites](https://github.com/cloudnative-pg/postgres-containers/blob/main/BUILD.md#prerequisites).
To build and push every flavor (minimal and standard), run:
To build and push the minimal and standard flavors, run:

```
docker buildx bake --push
```

PostGIS periodically fails to build against PostgreSQL trunk, so it's kept
as a separate `postgis` target outside the default group above (see
[#158](https://github.com/cloudnative-pg/postgres-trunk-containers/issues/158)).
Build and push it explicitly with:

```
docker buildx bake postgis --push
```

By default, the build process assumes a registry server runs locally at `localhost:5000`.
You can either [deploy a disposable registry at localhost:5000](https://github.com/cloudnative-pg/postgres-containers/blob/main/BUILD.md#local-testing), or [specify a different registry](https://github.com/cloudnative-pg/postgres-containers/blob/main/BUILD.md#the-distribution-registry).

Expand Down
Loading
Loading