ci: Add prd image build workflows + fix TimescaleDB wrong default version image - #674
Merged
Conversation
Four per-environment build workflows collapse into two that take an `environment` input, and prd becomes reachable on both. `build.yml` replaces build-dev.yml + build-stg.yml. A push to main still publishes `stg/wallet-backend:<sha>` automatically; dev, stg and prd are all reachable by manual dispatch, which is what allows a specific commit to be exercised in production before a release is cut around it. Its SHA tags never collide with promote-release.yml's `vX.Y.Z` tags, so a verification build cannot overwrite a promoted release image. `build-cnpg-timescaledb.yml` replaces the dev/stg pair, adds prd, validates `pg_major`/`tsdb_version` before anything is pushed, and serialises concurrent dispatches that target the same tag. Both call `stellar/actions/sdf-ecr-login` with no inputs: the action declares only `login-public-ecr`, so the `aws-oidc-role`/`aws-ecr-login-role` values the replaced files passed were never read.
… honest
TimescaleDB ships two Debian packages: the bundle
(`timescaledb-2-postgresql-NN`) carries the versioned `.so` and `.sql`
artifacts, while the loader (`timescaledb-2-loader-postgresql-NN`) carries the
unversioned loader `.so` and `timescaledb.control`. The control file is what
supplies `default_version`, and it is stamped with the *loader's* version.
The bundle depends on the loader with `>=`, so pinning only the bundle leaves
the loader free to resolve to the newest published release. The build then
produces an image whose control file names a version it does not carry: as of
today a `pg17-tsdb2.28.2` build picks up the 2.29.0 loader, so
`default_version` reads 2.29.0 against 2.28.2 artifacts. Bare
`CREATE EXTENSION timescaledb` and bare `ALTER EXTENSION timescaledb UPDATE`
then fail with no installation script, `pg_available_extensions` reports a
phantom upgrade, and the `version:` pin in the CNPG `Database` resource becomes
load-bearing for a fresh bootstrap. Pinning both packages is what Timescale's
own installation docs prescribe.
Two gates make a recurrence a red build rather than a bootstrap failure. Stage
one asserts what apt actually resolved for both packages, which also rejects a
longer upstream version the `${TSDB_VERSION}*` glob would otherwise match
(2.28.21 for a 2.28.2 request). Stage two asserts the assembled image: the
control file's `default_version` and `module_pathname`, the versioned install
script, and the versioned, tsl and loader libraries.
`TSDB_VERSION` moves to a global ARG so both stages share one default; stage two
needs it for the assertion. The `.so` copy glob deliberately keeps every version
the bundle ships — a database with an older extension version registered
resolves `pg_proc.probin` to that version's library — and now says so.
Verified locally: bare `CREATE EXTENSION timescaledb` on the built image yields
`default_version = installed_version = 2.28.2` and a working hypertable insert.
Dropping the loader pin reproduces the 2.29.0 resolution and fails the stage-one
gate; a drifted control file fails the stage-two gate.
Contributor
There was a problem hiding this comment.
Pull request overview
Consolidates environment-specific image workflows and ensures CNPG images contain the requested TimescaleDB version.
Changes:
- Replaces four workflows with two environment-parameterized workflows supporting dev, stg, and prd.
- Pins and verifies both TimescaleDB packages and assembled artifacts.
- Documents image-building and production tagging flows.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
README.md |
Documents consolidated workflows and database image builds. |
Dockerfile-timescale-cnpg |
Pins and verifies TimescaleDB versions. |
.github/workflows/build.yml |
Adds unified application image workflow. |
.github/workflows/build-stg.yml |
Removes superseded staging workflow. |
.github/workflows/build-dev.yml |
Removes superseded development workflow. |
.github/workflows/build-cnpg-timescaledb.yml |
Adds unified database image workflow. |
.github/workflows/build-cnpg-timescaledb-stg.yml |
Removes superseded staging database workflow. |
.github/workflows/build-cnpg-timescaledb-dev.yml |
Removes superseded development database workflow. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
aristidesstaffieri
approved these changes
Jul 31, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes prd reachable for both images, and fixes a bug where the database image's version tag was wrong.
1. Four build workflows → two
build.ymlbuild-dev.yml,build-stg.ymlmain→ stg (unchanged) ·-f environment=dev|stg|prdbuild-cnpg-timescaledb.ymlbuild-cnpg-timescaledb-{dev,stg}.yml-f environment=… -f pg_major=17 -f tsdb_version=2.28.2Why a prd app build when
promote-release.ymlexists? To exercise a commit in prd before cutting a release. Tags don't collide, so it can't touch a released image:build.yml→prd/wallet-backend:<sha>promote-release.yml→prd/wallet-backend:vX.Y.Z(still the only release path)2. The database image lied about its TimescaleDB version
timescaledb.control— which suppliesdefault_version— ships in the loader package, not the extension bundle. We pinned only the bundle, so apt took the newest loader. Apg17-tsdb2.28.2build today gets the 2.29.0 loader:Result: bare
CREATE EXTENSION timescaledband bareALTER EXTENSION timescaledb UPDATEfail (no installation script), andpg_available_extensionsshows a phantom upgrade forever. Silent otherwise, which is why it survived — once created with an explicit version, queries work fine.Timescale's docs say to pin both packages; we pinned one. Known upstream trap: timescale/timescaledb#3297.
Fix: pin both packages + two build-time gates, so a recurrence is a red build instead of a bootstrap failure.
Verification
Built locally at
pg_major=17,tsdb_version=2.28.2.✅
default_version = '2.28.2',module_pathname = '$libdir/timescaledb-2.28.2', 37 versioned libs intact✅ Booted PostgreSQL from the image — bare
CREATE EXTENSION timescaledbgivesdefault_version = installed_version = 2.28.2,ALTER EXTENSION … UPDATEreturns "already installed", hypertable insert works✅ Each gate observed failing, so neither is decorative:
resolved to 2.29.0~debian12-1710, expected 2.28.2default_version=2.99.9 … expected 2.28.2tsdb_version=9.9.9Version '9.9.9*' … was not found✅
actionlintclean · everypushevent resolves tostg(staging stream unchanged) ·make checkpassesReviewer notes
Nothing changes except prd being added — same full-SHA tags, same
make docker-build/docker-push, same auto-publish to stg on push tomain. No:latest, no short-SHA tags.New invocations:
gh workflow run build.yml -f environment=dev # was: build-dev.yml gh workflow run build-cnpg-timescaledb.yml -f environment=prd -f pg_major=17 -f tsdb_version=2.28.2Action items:
Build and Push Wallet Backend (Dev)/(Stg)— those job names are goneprd/cnpg-timescaledbECR repo before the first prd DB build (prd/wallet-backendalready exists)Two things deliberately left alone:
.socopy glob still keeps all 37 versions (now commented): a DB registered at an older extension version resolvespg_proc.probinto that version's library, so narrowing it would break pod restarts on a lagging cluster.sdf-ecr-loginis now called bare — the action only declareslogin-public-ecr, so theaws-oidc-role/aws-ecr-login-roleinputs the old files passed were never read.Follow-up (not here): the CNPG base
17-bookwormis PG 17.6, but TimescaleDB 2.28.x wantspostgresql-17 (>= 17.10). The builder pulls 17.10 and its libs run on 17.6 — works (minors are ABI-compatible), but a 17.10+ base tag would remove the skew.