Skip to content

Publishing a pgAdmin Release

Dave Page edited this page Sep 22, 2026 · 6 revisions

Publishing a pgAdmin Release

The packaging and publishing run on GitHub Actions, so anyone with write access to the repository can build and publish a release; there is no longer any requirement to be on a particular network.

Everything is on Actions, including the container images, the Helm chart and the upload to PyPI.

Preparing for the release

Ahead of the release, for the translators:

  1. Extract, merge and compile the message catalogues: make msg-extract && make msg-update && make msg-compile.
  2. Email pgadmin-hackers asking for translation updates.

On the day the candidate is built:

  1. Ensure the release notes are up to date and carry the release date.
  2. Update the version numbers in web/version.py.
  3. Update the version in pkg/helm/Chart.yaml.
  4. Ensure everything is committed and that the build checks on master are green.

Building a release candidate

Run the Release candidate workflow from the Actions tab.

Input Value
location The build directory, normally today's date. A second attempt on the same day needs a suffix, such as 2026-09-21-2.
publish Tick it. Without this the builds happen but nothing is published.

The workflow builds every package, signs the macOS bundle and the Windows installer, publishes the result to https://developer.pgadmin.org/builds/<location>/, and then runs the acceptance test against it.

What the acceptance test covers

It does not inspect the tree; it does what the repository README tells a user to do, and fails if that does not work:

  • Installs from the APT repository on Debian 12 and 13 and Ubuntu 22.04, 24.04 and 26.04, and from the YUM repository on AlmaLinux 9 and 10 and Fedora 43 and 44, with no verification bypassed, so a bad signature or a missing architecture fails the job.
  • Downloads and silently installs the Windows installer, then checks the Authenticode signature on the installed pgAdmin4.exe.
  • Mounts the macOS disk image with the quarantine attribute a browser would set, checks Gatekeeper and stapling, and fails if any bundled binary still references a path outside the bundle.
  • Verifies every detached signature from the published URL, installs the wheel into a virtual environment, and checks the tarballs and documents.

A red acceptance test is a candidate that must not be promoted. Fix the cause and build a new candidate with a new suffix; candidates are not repaired in place.

The container

The candidate workflow builds the container for both architectures and pushes it as dpage/pgadmin4:<location> and ghcr.io/pgadmin-org/pgadmin4:<location>. Test that image as part of verifying the candidate: promotion re-tags this exact manifest rather than rebuilding, so what ships is what was tested.

The Helm chart is built as a check but not published until promotion, since its version comes from pkg/helm/Chart.yaml and a registry has no notion of a candidate version.

Promoting to general availability

Once the candidate is verified, run the Promote release workflow.

Input Value
version The released version, for example 9.18.
location The candidate being promoted, for example 2026-09-21-1.
confirm The version again.
container-tags Space separated tags for the container, for example 9 9.18 9.18.0 latest.
scope everything for a real release.

The version and the location are separate on purpose: 2026-09-21-1 is a build and 9.18 is what users will call it, and conflating the two is how the wrong tree gets published under the right name. The version is typed twice for the same reason.

scope decides how far it goes, in increasing order of permanence:

  • release-directory writes only v<VERSION>, which can simply be deleted afterwards. This is the default.
  • files also copies packages into the production repositories and re-signs every index clients read.
  • everything also updates the website database and copies to the S3 archive. Neither can be undone: the archive sync carries no --delete.

There is also registries, which is not part of that progression: it skips the download server entirely and runs only the container re-tag and the chart push, so those can be exercised against a candidate tag without a release. It does not upload to PyPI, there being no published wheel to upload. Between it and release-directory, both halves of a promotion can be rehearsed without touching anything that cannot be deleted afterwards.

Publishing is single-shot. A version that already exists is refused, so a correction means a new version rather than a repair.

Afterwards, verify that the files appear under the PostgreSQL FTP site. This can take up to an hour, since the download server syncs to the mirror network on a schedule.

The same run also publishes to the registries, in a separate job that touches none of the download infrastructure. Afterwards, check:

The organisation is configured so that a package GHCR has not seen before is created public, but it is worth an anonymous pull the first time a new package name is published: if that setting is ever changed back, the push still succeeds and the pull returns 401. The fix is Package settings, where the visibility and the Manage Actions access link to the repository both live.

Updating the website

Activate the downloads:

  1. Log in at pgadmin.org/admin.
  2. Under Download, open Versions.
  3. Open the version being published, tick Active, and save.
  4. Check the downloads appear on the relevant pages.

Update the version pgAdmin itself checks for upgrade notifications:

  1. From the admin menu, open Versions under the Versions section.
  2. There is a single record. Open it.
  3. Set Version (String), and set Version (Integer) to APP_VERSION_INT from the released version's web/version.py.
  4. Save, then check the Current Version text at the foot of the home page and versions.json.

Add the announcement:

  1. Run the Purge website cache workflow, so the edits below are not hidden behind the cache.
  2. From the admin menu, open News Articles under News.
  3. Add an article, using a previous one as a model.
  4. Untick Display on articles no longer needed. We normally show the latest release of each major version.
  5. Check the home page.

Announcing

Submit the news article at postgresql.org/account/edit/news.

Send the announcement separately to pgadmin-support@postgresql.org and pgadmin-hackers@postgresql.org. Announcements are usually close to the website article, but should also explain briefly what pgAdmin is, for readers who do not know. Previous announcements are a good model.

Tagging

Tag the release in git. Tag the commit the release was actually built from, which may not be the tip: the tree may have moved on since the candidate.

git tag -a REL-9_18 <commit hash> -m "Tag v9.18"
git push --tags

Closing the milestone

Close the milestone for the release.