Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2bd2640
tests: move Citus DROP TABLE out of teardown into an explicit test step
dimitri Jul 13, 2026
6041d26
tests: fix five categories of spurious CI failures
dimitri Jul 13, 2026
ca1b344
tests: fix Citus DROP TABLE race against metadata sync
dimitri Jul 13, 2026
c246528
tests: extend has_needed_replication_slots retry to cover list_replic…
dimitri Jul 13, 2026
a20edf4
tests: pgaftest summary, drop-node coverage, CI image caching, pg_aut…
dimitri Jul 13, 2026
5ac9377
cleanup: remove accidentally staged run-test.sh and pycache files
dimitri Jul 13, 2026
5e67447
tests: simplify Docker command to pg_autoctl node run, unify init/run…
dimitri Jul 13, 2026
062bd42
fix: restore \n in compose_gen command/healthcheck stanzas (\\→\n)
dimitri Jul 13, 2026
6e1b16e
pgaftest: two-gate deferred (createDeferred + launchDeferred), TAP fi…
dimitri Jul 13, 2026
ebc1a20
pgaftest: fix debian cluster volume mount and pg_createcluster invoca…
dimitri Jul 13, 2026
ae5aeef
nodespec: rename [launch] mode key to run
dimitri Jul 13, 2026
e8e665a
pgaftest: TAP spec header, drop_node_destroy sequence, debian backup …
dimitri Jul 13, 2026
93c0a7f
cli_node: use initdb --allow-group-access for Debian clusters
dimitri Jul 13, 2026
cd1c8c2
monitor: post-init formation service; fix createDeferred buf; nonha_c…
dimitri Jul 13, 2026
84f9100
docker: add shared base image with all PG versions and Citus builds
dimitri Jul 13, 2026
cc1a8eb
node post-init: proper supervisor service via pg_autoctl node post-init
dimitri Jul 13, 2026
e68b470
ci: merge into single workflow; fix BASE org and BINDIR
dimitri Jul 13, 2026
9f6dc1c
build: refactor Makefile and Docker infrastructure
dimitri Jul 13, 2026
6e8a913
style: exclude bison/flex generated files from citus-style; replace f…
dimitri Jul 13, 2026
0076082
fix: scope Citus build cd in subshell to avoid cwd-deleted error on r…
dimitri Jul 13, 2026
ab1e559
fix: three CI failures from logs analysis
dimitri Jul 14, 2026
78cf896
build: move version target to Makefile.docker; fix run-test target name
dimitri Jul 14, 2026
43499ac
ci: run style_checker and ensure_base in parallel; fix test_spec_pars…
dimitri Jul 14, 2026
68a9fd0
Fix CI failures: debian_clusters, SSL certs, teardown, grammar, defer…
dimitri Jul 14, 2026
b4b1dec
Fix debian_clusters setup, SSL cert truncation, and upgrade Makefile
dimitri Jul 14, 2026
823dfbe
debian_clusters: chown version dir after pg_createcluster
dimitri Jul 14, 2026
425701c
refactor: move pg_createcluster test setup into debian.c
dimitri Jul 14, 2026
d8480d7
fix: four pre-existing test failures
dimitri Jul 14, 2026
b378c20
fix: drop_node_destroy test suite and test_015_003 regression
dimitri Jul 14, 2026
dbc02c5
Fix debian_clusters: /usr/bin/sudo path + single [options] INI section
dimitri Jul 14, 2026
0cbd60a
fix: upgrade build, login-action Node 24, Dockerfile Makefile* glob
dimitri Jul 14, 2026
89ff563
Fix CI warnings, citus_skip_pg_hba failure, and add log capture
dimitri Jul 14, 2026
67c29eb
Fix CI warnings and tablespaces prebuilt path
dimitri Jul 14, 2026
98dda07
Fix config write race: use temp-file + rename for atomic writes
dimitri Jul 14, 2026
185ade3
Fix Monitor.failover() race: wait for stable primary before perform_f…
dimitri Jul 14, 2026
5e67265
Fix test_003_002_stop_primary race: check assigned state not reported…
dimitri Jul 14, 2026
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
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ src/bin/lib/libs/** -citus-style
src/bin/lib/pg/** -citus-style
src/bin/lib/subcommands.c/** -citus-style
src/monitor/version_compat.c -citus-style
# bison/flex generated files — not subject to style checks
src/bin/pgaftest/test_spec_parse.c -citus-style
src/bin/pgaftest/test_spec_parse.h -citus-style
src/bin/pgaftest/test_spec_scan.c -citus-style
108 changes: 108 additions & 0 deletions .github/workflows/base-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: Base image

# Builds and pushes the pgaf-base image to ghcr.io.
#
# The base image contains every supported Postgres major version
# (from apt.postgresql.org) plus one Citus build per Postgres version.
# Per-PG pg_auto_failover builds use it as their FROM so the heavy
# apt/Citus work is cached long-term across all PR runs.
#
# Triggered by:
# - push: changes to Dockerfile.base on main
# - workflow_dispatch: manual rebuild (optionally force)
# - workflow_call: called by run-pgaftest.yml on cache-miss
# - check-versions.yml: when PGDG or Citus versions change

on:
push:
branches:
- main
paths:
- Dockerfile.base

workflow_dispatch:
inputs:
force_rebuild:
description: 'Rebuild even if the image already exists'
type: boolean
default: false

workflow_call:
inputs:
force_rebuild:
description: 'Rebuild even if the image already exists'
type: boolean
default: false

permissions:
contents: read
packages: write

env:
IMAGE: ghcr.io/hapostgres/pg_auto_failover/pgaf-base:bookworm
CITUSTAG_14: v12.1.5
CITUSTAG_15: v12.1.5
CITUSTAG_16: v13.2.0
CITUSTAG_17: v13.2.0
CITUSTAG_18: v14.1.0
CITUSTAG_19: none

jobs:
build-base:
name: Build / push base image
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7.0.0

- name: Log in to ghcr.io
uses: docker/login-action@v4.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Check whether base image already exists
id: check
run: |
if docker manifest inspect "$IMAGE" > /dev/null 2>&1; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi

- name: Set up Docker BuildKit
if: steps.check.outputs.exists == 'false' || inputs.force_rebuild == true || github.event_name == 'push'
uses: docker/setup-buildx-action@v4.2.0

- name: Build and push base image
if: steps.check.outputs.exists == 'false' || inputs.force_rebuild == true || github.event_name == 'push'
run: |
docker buildx build \
-f Dockerfile.base \
--build-arg CITUSTAG_14="${CITUSTAG_14}" \
--build-arg CITUSTAG_15="${CITUSTAG_15}" \
--build-arg CITUSTAG_16="${CITUSTAG_16}" \
--build-arg CITUSTAG_17="${CITUSTAG_17}" \
--build-arg CITUSTAG_18="${CITUSTAG_18}" \
--build-arg CITUSTAG_19="${CITUSTAG_19}" \
--label "org.pgaf.citustag.14=${CITUSTAG_14}" \
--label "org.pgaf.citustag.15=${CITUSTAG_15}" \
--label "org.pgaf.citustag.16=${CITUSTAG_16}" \
--label "org.pgaf.citustag.17=${CITUSTAG_17}" \
--label "org.pgaf.citustag.18=${CITUSTAG_18}" \
--label "org.pgaf.citustag.19=${CITUSTAG_19}" \
--platform linux/amd64 \
-t "$IMAGE" \
--push \
.

- name: Report
run: |
if [ "${{ steps.check.outputs.exists }}" = "true" ] && \
[ "${{ inputs.force_rebuild }}" != "true" ] && \
[ "${{ github.event_name }}" != "push" ]; then
echo "Base image already exists at ${IMAGE} — skipped build."
else
echo "Base image built and pushed: ${IMAGE}"
fi
165 changes: 165 additions & 0 deletions .github/workflows/check-versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
name: Check base image versions

# Runs weekly to detect new PGDG minor releases or Citus tags.
# When versions have changed since the base image was last built,
# triggers a forced rebuild of the base image.
#
# Checks:
# - apt.postgresql.org: latest available version for PG 14–17
# - github.com/citusdata/citus: latest release in each supported series
#
# The base image stores the Citus tags it was built with as Docker
# labels (org.pgaf.citustag.<PG>). PGDG versions are checked live
# against the apt repo; if any PG package has a newer version than
# what a test container currently reports, the base image is stale.

on:
schedule:
# Monday 06:00 UTC
- cron: '0 6 * * 1'
workflow_dispatch:

permissions:
contents: read
packages: write

env:
IMAGE: ghcr.io/hapostgres/pg_auto_failover/pgaf-base:bookworm

jobs:
check-versions:
name: Check PGDG + Citus versions
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7.0.0

- name: Log in to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# -----------------------------------------------------------------------
# Pull current base image labels
# -----------------------------------------------------------------------
- name: Pull base image labels
id: labels
run: |
if ! docker manifest inspect "$IMAGE" > /tmp/manifest.json 2>&1; then
echo "Base image does not exist — will build it."
echo "needs_rebuild=true" >> "$GITHUB_OUTPUT"
exit 0
fi

# Extract labels via docker inspect (needs a pull)
docker pull "$IMAGE" --quiet
for pg in 14 15 16 17; do
val=$(docker inspect "$IMAGE" \
--format "{{ index .Config.Labels \"org.pgaf.citustag.${pg}\" }}" 2>/dev/null || echo "")
echo "CURRENT_CITUSTAG_${pg}=${val}" >> "$GITHUB_OUTPUT"
done
echo "needs_rebuild=false" >> "$GITHUB_OUTPUT"

# -----------------------------------------------------------------------
# Check latest Citus tags per release series via GitHub Releases API
# -----------------------------------------------------------------------
- name: Check latest Citus tags
id: citus
if: steps.labels.outputs.needs_rebuild == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Fetch all Citus releases (latest 100) once
curl -fsSL \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/citusdata/citus/releases?per_page=100" \
> /tmp/citus-releases.json

# Latest tag in a given semver series (major.minor match)
latest_in_series() {
local prefix="$1" # e.g. "v12."
jq -r --arg p "$prefix" \
'[.[] | select(.tag_name | startswith($p)) | .tag_name] | sort | last' \
/tmp/citus-releases.json
}

LATEST_12=$(latest_in_series "v12.")
LATEST_13=$(latest_in_series "v13.")

# Map PG versions to series
# PG14,15 → v12.x PG16,17 → v13.x
echo "LATEST_CITUSTAG_14=${LATEST_12}" >> "$GITHUB_OUTPUT"
echo "LATEST_CITUSTAG_15=${LATEST_12}" >> "$GITHUB_OUTPUT"
echo "LATEST_CITUSTAG_16=${LATEST_13}" >> "$GITHUB_OUTPUT"
echo "LATEST_CITUSTAG_17=${LATEST_13}" >> "$GITHUB_OUTPUT"

# Detect any mismatch — read current tags from the pulled image labels
CHANGED=false
for pg in 14 15 16 17; do
current=$(docker inspect "$IMAGE" \
--format "{{ index .Config.Labels \"org.pgaf.citustag.${pg}\" }}" 2>/dev/null || echo "")
latest=$(eval echo "\$LATEST_CITUSTAG_${pg}")
if [ -n "$latest" ] && [ "$current" != "$latest" ]; then
echo "Citus PG${pg}: ${current} → ${latest}"
CHANGED=true
else
echo "Citus PG${pg}: ${current} (up to date)"
fi
done
echo "citus_changed=${CHANGED}" >> "$GITHUB_OUTPUT"

# -----------------------------------------------------------------------
# Check PGDG minor versions via apt-cache inside a throwaway container
# -----------------------------------------------------------------------
- name: Check PGDG minor versions
id: pgdg
if: steps.labels.outputs.needs_rebuild == 'false'
run: |
# Run apt-cache inside the existing base image to compare what's
# installed vs. what's available in the PGDG repo
docker run --rm "$IMAGE" bash -c '
apt-get update -qq 2>/dev/null
CHANGED=false
for pg in 14 15 16 17; do
installed=$(dpkg-query -W -f="\\${Version}" postgresql-${pg} 2>/dev/null || echo "")
available=$(apt-cache show postgresql-${pg} 2>/dev/null \
| awk "/^Version:/{print \$2; exit}")
if [ -z "$installed" ] && [ -z "$available" ]; then
continue # PG version not applicable
fi
if [ "$installed" != "$available" ]; then
echo "PGDG PG${pg}: installed=${installed}, available=${available} → STALE"
CHANGED=true
else
echo "PGDG PG${pg}: ${installed} (up to date)"
fi
done
[ "$CHANGED" = "true" ] && exit 1 || exit 0
'
if [ $? -ne 0 ]; then
echo "pgdg_changed=true" >> "$GITHUB_OUTPUT"
else
echo "pgdg_changed=false" >> "$GITHUB_OUTPUT"
fi

# -----------------------------------------------------------------------
# Trigger base image rebuild if anything changed
# -----------------------------------------------------------------------
- name: Rebuild base image if stale
if: |
steps.labels.outputs.needs_rebuild == 'true' ||
steps.citus.outputs.citus_changed == 'true' ||
steps.pgdg.outputs.pgdg_changed == 'true'
uses: ./.github/workflows/base-image.yml
with:
force_rebuild: true

- name: Report — nothing to do
if: |
steps.labels.outputs.needs_rebuild != 'true' &&
steps.citus.outputs.citus_changed != 'true' &&
steps.pgdg.outputs.pgdg_changed != 'true'
run: echo "Base image is up to date. No rebuild needed."
Loading