User Story
As a release engineer, I want to apply targeted fixes to an active release branch and cut a patch release without including unrelated changes from `main`, so that customers on a supported version can receive critical updates without being forced onto a newer major release.
Problem
Two related gaps were discovered when executing a patch release against `v26.04.28-02`:
1. No documented patch release process
There was no repeatable workflow for isolating specific commits from `main`, verifying them against an existing release baseline, and cutting a numbered patch (e.g. `26.04.28-03`) from that baseline.
2. No reliable way to run the full test suite against a patch branch
The LTS Auto-run Tests workflow (`cicd_5-lts.yml`) fires automatically on any `release-*` push, but Postman tests require a Docker image tagged `dotcms/dotcms-test:{version}`. This image is only built as a local GitHub Actions artifact — it is never published to Docker Hub. The publicly-released image (`dotcms/dotcms:{version}`) IS on Docker Hub after the release workflow completes, but the test infrastructure ignores it because `docker.output.image.name` in `parent/pom.xml` and `dotcms-integration/pom.xml` is hardcoded to `dotcms/dotcms-test`.
This creates a fragile ordering dependency: if the LTS workflow fires before the release build finishes, the locally-built artifact doesn't exist yet and tests fail with a 404. Even after the release completes, there is no first-class way to re-run the full test suite against the now-available image without manually re-triggering failed CI jobs.
Additionally, the LTS workflow had a hardcoded `version: '24.12.27'` in the build phase causing the artifact to always be tagged with that version, while the test phase derived the image name from `maven.config` at runtime — so they never agreed on release branches.
Solution
Patch release workflow (established & validated, PR #35608)
- Create `release-{version}-{patch}` from the existing `release-{version}` tag
- Cherry-pick only substantive commits (skip merge-from-main noise commits)
- Push branch, open PR against previous release branch for CI + reviews
- Trigger `cicd_6-release.yml` in parallel via `workflow_dispatch` — release build and CI run concurrently, cutting total wall-clock time significantly
- Re-run failed Postman jobs once release workflow completes: `gh run rerun --failed`
LTS workflow fix (PR #35612)
- Replaced hardcoded `version: '24.12.27'` with a `setup` job that reads `-Drevision` + `-Dchangelist` from `.mvn/maven.config` at runtime — Docker artifact tag now matches what Maven computes for `project.version`
- Added `workflow_dispatch` trigger with optional `version` input for manual re-triggers
- Removed stale `pull_request.number` reference from concurrency group
Known gap — future work
The root issue is that the Postman and integration test infrastructure is coupled to a locally-built `dotcms/dotcms-test` image that only exists inside a CI run. The published `dotcms/dotcms:{version}` image is already available on Docker Hub after any release, but the test runner never uses it.
Recommended fix: When running against a release branch, configure the test infrastructure to pull `dotcms/dotcms:{version}` directly from Docker Hub instead of requiring the locally-built artifact. This means updating `docker.output.image.name` in `parent/pom.xml` / `dotcms-integration/pom.xml` (or making it a configurable property) and updating the LTS workflow to skip the build/artifact phase and instead pass the Hub image tag to the test phase directly. This would eliminate the timing dependency entirely and allow the test suite to be re-run on demand against any released version.
Implementation Status
✅ Patch release shipped as `v26.04.28-03`
✅ LTS workflow version fix in PR #35612
Patch Release Runbook
# 1. Branch from the existing release
git checkout -b release-{yy.mm.dd}-{patch} origin/release-{yy.mm.dd}-{prev}
# 2. Cherry-pick substantive commits (skip merge-from-main commits)
git cherry-pick <sha1> <sha2> ... <shaN>
# 3. Push — LTS workflow starts automatically
git push -u origin release-{yy.mm.dd}-{patch}
# 4. Open PR against the previous release branch (for CI + reviews)
gh pr create --base release-{yy.mm.dd}-{prev} --head release-{yy.mm.dd}-{patch}
# 5. Trigger the release in parallel
gh workflow run cicd_6-release.yml \
--field release_version={yy.mm.dd}-{patch} \
--field release_commit=$(git rev-parse HEAD)
# 6. Once release build completes, re-run any Postman failures
gh run rerun <lts-run-id> --failed
References
User Story
As a release engineer, I want to apply targeted fixes to an active release branch and cut a patch release without including unrelated changes from `main`, so that customers on a supported version can receive critical updates without being forced onto a newer major release.
Problem
Two related gaps were discovered when executing a patch release against `v26.04.28-02`:
1. No documented patch release process
There was no repeatable workflow for isolating specific commits from `main`, verifying them against an existing release baseline, and cutting a numbered patch (e.g. `26.04.28-03`) from that baseline.
2. No reliable way to run the full test suite against a patch branch
The LTS Auto-run Tests workflow (`cicd_5-lts.yml`) fires automatically on any `release-*` push, but Postman tests require a Docker image tagged `dotcms/dotcms-test:{version}`. This image is only built as a local GitHub Actions artifact — it is never published to Docker Hub. The publicly-released image (`dotcms/dotcms:{version}`) IS on Docker Hub after the release workflow completes, but the test infrastructure ignores it because `docker.output.image.name` in `parent/pom.xml` and `dotcms-integration/pom.xml` is hardcoded to `dotcms/dotcms-test`.
This creates a fragile ordering dependency: if the LTS workflow fires before the release build finishes, the locally-built artifact doesn't exist yet and tests fail with a 404. Even after the release completes, there is no first-class way to re-run the full test suite against the now-available image without manually re-triggering failed CI jobs.
Additionally, the LTS workflow had a hardcoded `version: '24.12.27'` in the build phase causing the artifact to always be tagged with that version, while the test phase derived the image name from `maven.config` at runtime — so they never agreed on release branches.
Solution
Patch release workflow (established & validated, PR #35608)
LTS workflow fix (PR #35612)
Known gap — future work
The root issue is that the Postman and integration test infrastructure is coupled to a locally-built `dotcms/dotcms-test` image that only exists inside a CI run. The published `dotcms/dotcms:{version}` image is already available on Docker Hub after any release, but the test runner never uses it.
Recommended fix: When running against a release branch, configure the test infrastructure to pull `dotcms/dotcms:{version}` directly from Docker Hub instead of requiring the locally-built artifact. This means updating `docker.output.image.name` in `parent/pom.xml` / `dotcms-integration/pom.xml` (or making it a configurable property) and updating the LTS workflow to skip the build/artifact phase and instead pass the Hub image tag to the test phase directly. This would eliminate the timing dependency entirely and allow the test suite to be re-run on demand against any released version.
Implementation Status
✅ Patch release shipped as `v26.04.28-03`
✅ LTS workflow version fix in PR #35612
Patch Release Runbook
References