Skip to content

ci(github): publish the Docker image to GHCR on release - #482

Merged
halcwb merged 2 commits into
informedica:masterfrom
7sharp9:ci/459-publish-docker-image
Aug 25, 2026
Merged

ci(github): publish the Docker image to GHCR on release#482
halcwb merged 2 commits into
informedica:masterfrom
7sharp9:ci/459-publish-docker-image

Conversation

@7sharp9

@7sharp9 7sharp9 commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator
  • Add publish-docker-image to tag-release.yml, gated on tag-and-release succeeding, so a Docker image is only published for a commit that was actually tagged and released.
  • Builds Dockerfile at the same merge commit, linux/amd64 only, APP_VERSION build-arg matching the local DockerBuild target, GHA layer caching.
  • Smoke tests the image (demo GENPRES_URL_ID, random throwaway password, / must return 200 within 60s) before pushing — verified locally against a real build, not just in CI.
  • Pushes ghcr.io/informedica/genpres:<version>, plus :latest only on a stable (non-pre-release) version. GHCR is interim pending the informedica Docker Hub account (see issue thread); the registry is a single IMAGE_NAME env var so switching later is a small change.
  • Amends ADR-0021 with the decisions table, updates DEVELOPMENT.md's Release Automation section, adds a design-history change log entry.

Follow-up needed after merge (not automatable)

  • Package visibility: the first push creates the GHCR package as private under informedica. Someone with org admin rights needs to set informedica/genpres public in GitHub package settings, or the image is unpullable without a token.
  • Build.fs's local DockerBuild default (halcwb/genpres) is unchanged in this PR — separate decision.

Test plan

  • Built Dockerfile locally with the same APP_VERSION build-arg the workflow uses; build succeeded.
  • Ran the built image with the demo GENPRES_URL_ID and a random password; / returned 200 on first poll, confirming the smoke-test step's assumptions (port 8085, startup timing).
  • First real run of publish-docker-image on the next release PR merge (cannot be dry-run outside GitHub Actions).

Closes #234 item 3, addresses #459.

- Add `publish-docker-image` to `tag-release.yml`, gated on `tag-and-release` succeeding, so a Docker image is only published for a commit that was actually tagged and released.
- Builds `Dockerfile` at the same merge commit, `linux/amd64` only, `APP_VERSION` build-arg matching the local `DockerBuild` target, GHA layer caching.
- Smoke tests the image (demo `GENPRES_URL_ID`, random throwaway password, `/` must return 200 within 60s) before pushing — verified locally against a real build, not just in CI.
- Pushes `ghcr.io/informedica/genpres:<version>`, plus `:latest` only on a stable (non-pre-release) version. GHCR is interim pending the `informedica` Docker Hub account (see issue thread); the registry is a single `IMAGE_NAME` env var so switching later is a small change.
- Amends ADR-0021 with the decisions table, updates DEVELOPMENT.md's Release Automation section, adds a design-history change log entry.

## Follow-up needed after merge (not automatable)

- **Package visibility**: the first push creates the GHCR package as private under `informedica`. Someone with org admin rights needs to set `informedica/genpres` public in GitHub package settings, or the image is unpullable without a token.
- `Build.fs`'s local `DockerBuild` default (`halcwb/genpres`) is unchanged in this PR — separate decision.

## Test plan

- [x] Built `Dockerfile` locally with the same `APP_VERSION` build-arg the workflow uses; build succeeded.
- [x] Ran the built image with the demo `GENPRES_URL_ID` and a random password; `/` returned 200 on first poll, confirming the smoke-test step's assumptions (port 8085, startup timing).
- [ ] First real run of `publish-docker-image` on the next release PR merge (cannot be dry-run outside GitHub Actions).

Closes informedica#234 item 3, addresses informedica#459.
@greptile-apps

greptile-apps Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds a release-gated job that builds, smoke-tests, and publishes an amd64 GenPRES image to GHCR, with latest reserved for stable releases. It also documents the registry choice, package-visibility follow-up, and release process.

  • Exposes release metadata as outputs from tag-and-release.
  • Builds and smoke-tests the exact merge commit before pushing its versioned tags.
  • Updates release documentation and ADR history.
  • The Docker-tag construction does not account for supported SemVer build metadata.

Confidence Score: 4/5

The PR appears safe to merge, with a non-blocking compatibility gap for future releases that use SemVer build metadata.

The current version format follows the successful path, but a supported +build suffix would be copied into an invalid Docker tag after the GitHub Release had already been created.

Files Needing Attention: .github/workflows/tag-release.yml

Important Files Changed

Filename Overview
.github/workflows/tag-release.yml Adds the release-image build, smoke-test, and GHCR publication flow; version tags need Docker-compatible handling for SemVer build metadata.
DEVELOPMENT.md Documents the new publication flow, interim registry, smoke test, and required package-visibility operation.
docs/mdr/design-history/0021-build-system-versioning-and-release.md Records the Docker publication architecture, tag policy, tooling choices, and accepted operational trade-offs.
docs/mdr/design-history/0000-change-log.md Adds the corresponding reverse-chronological ADR amendment entry.

Sequence Diagram

sequenceDiagram
  participant R as Release PR merge
  participant T as tag-and-release
  participant D as publish-docker-image
  participant G as GHCR
  R->>T: Closed and merged release/master PR
  T->>T: Validate version and release notes
  T->>T: Create Git tag and GitHub Release
  T-->>D: version, tag, prerelease
  D->>D: Check out merge commit
  D->>D: Build amd64 image
  D->>D: Run container and smoke-test /
  alt Smoke test succeeds
    D->>G: Push version tag
    opt Stable release
      D->>G: Push latest tag
    end
  else Smoke test fails
    D-->>D: Stop before push
  end
Loading

Reviews (1): Last reviewed commit: "ci(github): publish the Docker image to ..." | Re-trigger Greptile

Comment thread .github/workflows/tag-release.yml
Versioning.fsx's isPreRelease already tolerates SemVer build metadata in <Version> (a `+build.N` suffix), even though no release has shipped one yet. Docker tags reject `+` outright, so a version like `1.0.0+build.7` would flow straight into `$IMAGE_NAME:$VERSION`, and the Git tag and GitHub Release for that version would already exist by the time `docker build` rejected the tag as invalid.

Fold `+` to `-` once, in the Determine image tags step, and expose the result as its own version_tag output. The smoke test step now reads that output instead of rebuilding a tag from the raw version, which was quietly wrong the same way: it would have run against a tag docker never actually built.

Caught by Greptile's review of informedica#482. ADR-0021's Tags pushed row and DEVELOPMENT.md's publish-docker-image steps note why the fold exists.

Refs informedica#459
@halcwb
halcwb merged commit 1bf8763 into informedica:master Aug 25, 2026
4 checks passed
@7sharp9
7sharp9 deleted the ci/459-publish-docker-image branch August 26, 2026 00:18
halcwb pushed a commit that referenced this pull request Aug 26, 2026
DockerBuild/DockerRun still defaulted to halcwb/genpres, left over from before #459/#482 wired up GHCR publishing on release. Align the local default with what tag-release.yml publishes so a plain `dotnet run DockerBuild` produces the same image name as CI.  Update the DEVELOPMENT.md references to match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve build system

2 participants