Skip to content

Commit f921e18

Browse files
committed
feat(build): publish version.php-derived tags per slot (8.0.0.3 / 8.1.1-dev)
The merge job now derives each slot's published version from the OpenEMR version.php at the slot Dockerfile's OPENEMR_VERSION ref, instead of using the bare symlink dir name. current publishes its true 8.0.0.3 and dev self-identifies as 8.1.1-dev (no longer colliding with the eventual real 8.1.1 release). Each slot gets float + :ver + dated tags, plus the bare-dir tag for current/next only. Standardize the 8.0.0 Dockerfile to ARG OPENEMR_VERSION=rel-800 so the merge-job grep is uniform across all three slots, and update the registry, Docker Hub overview template, and renderer test to the docker_dir + full model. Assisted-by: Claude Code
1 parent d4caf49 commit f921e18

6 files changed

Lines changed: 39 additions & 32 deletions

File tree

.github/workflows/build-openemr.yml

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ jobs:
3131
- name: Resolve slot version
3232
id: resolve
3333
run: |
34-
version="$(basename "$(readlink "docker/openemr/${{ matrix.slot }}")")"
35-
echo "version=$version" >> "$GITHUB_OUTPUT"
34+
dir="$(basename "$(readlink "docker/openemr/${{ matrix.slot }}")")"
35+
echo "dir=$dir" >> "$GITHUB_OUTPUT"
3636
3737
- name: Prepare platform pair
3838
run: |
@@ -52,7 +52,7 @@ jobs:
5252
id: build
5353
uses: docker/build-push-action@v7
5454
with:
55-
context: docker/openemr/${{ steps.resolve.outputs.version }}
55+
context: docker/openemr/${{ steps.resolve.outputs.dir }}
5656
platforms: ${{ matrix.platform.arch }}
5757
outputs: type=image,name=openemr/openemr,push-by-digest=true,name-canonical=true,push=true
5858
no-cache: true
@@ -81,19 +81,27 @@ jobs:
8181
include:
8282
- slot: current
8383
float: latest
84+
bare_dir: true
8485
- slot: next
8586
float: next
87+
bare_dir: true
8688
- slot: dev
8789
float: dev
90+
bare_dir: false
8891
steps:
8992
- name: Checkout
9093
uses: actions/checkout@v6
9194

9295
- name: Resolve slot version
9396
id: resolve
9497
run: |
95-
version="$(basename "$(readlink "docker/openemr/${{ matrix.slot }}")")"
96-
echo "version=$version" >> "$GITHUB_OUTPUT"
98+
dir="$(basename "$(readlink "docker/openemr/${{ matrix.slot }}")")"
99+
ref="$(grep -oE 'OPENEMR_VERSION=[A-Za-z0-9._-]+' "docker/openemr/${dir}/Dockerfile" | head -1 | cut -d= -f2)"
100+
curl -fsSL "https://raw.githubusercontent.com/openemr/openemr/${ref}/version.php" -o /tmp/version.php
101+
# shellcheck disable=SC2016 # PHP variables, not shell
102+
ver="$(php -r 'require "/tmp/version.php"; $rp = $v_realpatch > 0 ? "." . $v_realpatch : ""; echo $v_major . "." . $v_minor . "." . $v_patch . $rp . $v_tag;')"
103+
echo "dir=$dir" >> "$GITHUB_OUTPUT"
104+
echo "ver=$ver" >> "$GITHUB_OUTPUT"
97105
98106
- name: Download digests
99107
uses: actions/download-artifact@v8
@@ -118,16 +126,18 @@ jobs:
118126
- name: Create manifest and push
119127
working-directory: /tmp/digests
120128
env:
121-
VERSION: ${{ steps.resolve.outputs.version }}
129+
VER: ${{ steps.resolve.outputs.ver }}
130+
DIR: ${{ steps.resolve.outputs.dir }}
122131
FLOAT: ${{ matrix.float }}
123132
BUILD_DATE: ${{ steps.build_date.outputs.date }}
133+
BARE_DIR: ${{ matrix.bare_dir }}
124134
run: |
125135
mapfile -t digests < <(find . -maxdepth 1 -type f -printf 'openemr/openemr@sha256:%f\n')
126-
docker buildx imagetools create \
127-
-t "openemr/openemr:${VERSION}" \
128-
-t "openemr/openemr:${FLOAT}" \
129-
-t "openemr/openemr:${VERSION}-${BUILD_DATE}" \
130-
"${digests[@]}"
136+
tags=(-t "openemr/openemr:${VER}" -t "openemr/openemr:${FLOAT}" -t "openemr/openemr:${VER}-${BUILD_DATE}")
137+
if [ "${BARE_DIR}" = "true" ] && [ "${DIR}" != "${VER}" ]; then
138+
tags+=(-t "openemr/openemr:${DIR}")
139+
fi
140+
docker buildx imagetools create "${tags[@]}" "${digests[@]}"
131141
132142
- name: Push Docker Hub readme
133143
uses: ./.github/actions/push-dockerhub-readme

docker/openemr/8.0.0/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ RUN ln -sf /usr/bin/php${PHP_VERSION_ABBR} /usr/bin/php
9090
# Install composer for openemr package building
9191
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
9292

93+
ARG OPENEMR_VERSION=rel-800
9394
RUN apk add --no-cache build-base \
94-
&& git clone https://github.com/openemr/openemr.git --branch rel-800 --depth 1 \
95+
&& git clone https://github.com/openemr/openemr.git --branch "${OPENEMR_VERSION}" --depth 1 \
9596
&& rm -rf openemr/.git \
9697
&& cd openemr \
9798
&& composer install --no-dev \

docs/release-automation-plan.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,13 @@ host most of the rewrite logic.
9393
`docker/openemr/{current,next,dev}` (e.g. `current → 8.0.0`) and builds
9494
from the resolved version dir. Because the workflow holds no version
9595
strings, rotation never rewrites it; instead `SlotRotator` re-points the
96-
symlink when a slot's `docker_dir` changes. Each slot publishes its
97-
floating tag (`current → :latest`, `next → :next`, `dev → :dev`) plus
98-
`:<full>` and `:<full>-<date>`.
96+
symlink when a slot's `docker_dir` changes. The merge job derives the
97+
published `:<ver>` from `version.php` (fetched at the slot Dockerfile's
98+
`OPENEMR_VERSION` ref), so `current` publishes its true `8.0.0.3` and
99+
`dev` self-identifies as `8.1.1-dev`. Each slot publishes its floating tag
100+
(`current → :latest`, `next → :next`, `dev → :dev`) plus `:<ver>` and
101+
`:<ver>-<date>`, and `current`/`next` (never `dev`) additionally publish
102+
the bare-dir tag (`8.0.0` / `8.1.0`) when it differs from `:<ver>`.
99103
- Remaining: same matrix-collapse for the `test-flex-*.yml` matrices.
100104

101105
## Permissions self-check

tools/release/templates/dockerhub-overview.md.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Supported tags:
66

7-
* `{{ current.full }}`, `{{ current.patch }}`, `latest` [Dockerfile](https://github.com/openemr/openemr-devops/blob/master/docker/openemr/{{ current.docker_dir }}/Dockerfile) | [Instructions](https://github.com/openemr/openemr-devops/tree/master/docker/openemr/{{ current.docker_dir }}/#openemr-official-docker-image)
7+
* `{{ current.docker_dir }}`, `{{ current.full }}`, `latest` [Dockerfile](https://github.com/openemr/openemr-devops/blob/master/docker/openemr/{{ current.docker_dir }}/Dockerfile) | [Instructions](https://github.com/openemr/openemr-devops/tree/master/docker/openemr/{{ current.docker_dir }}/#openemr-official-docker-image)
88
* `7.0.4`, `7.0.4.0` [Dockerfile](https://github.com/openemr/openemr-devops/blob/master/docker/openemr/7.0.4/Dockerfile) | [Instructions](https://github.com/openemr/openemr-devops/tree/master/docker/openemr/7.0.4/#openemr-official-docker-image)
99
* `{{ next.full }}`, `next` [Dockerfile](https://github.com/openemr/openemr-devops/blob/master/docker/openemr/{{ next.docker_dir }}/Dockerfile) | [Instructions](https://github.com/openemr/openemr-devops/tree/master/docker/openemr/{{ next.docker_dir }}/#openemr-official-docker-image)
1010
* `{{ dev.full }}`, `dev` [Dockerfile](https://github.com/openemr/openemr-devops/blob/master/docker/openemr/{{ dev.docker_dir }}/Dockerfile) | [Instructions](https://github.com/openemr/openemr-devops/tree/master/docker/openemr/{{ dev.docker_dir }}/#openemr-official-docker-image)
@@ -18,7 +18,7 @@ Supported tags:
1818
* `flex-edge-php-8.4` [Dockerfile](https://github.com/openemr/openemr-devops/blob/master/docker/openemr/flex/Dockerfile) | [Instructions](https://github.com/openemr/openemr-devops/tree/master/docker/openemr/flex/#openemr-official-docker-image)
1919
* `flex-edge-php-8.3` [Dockerfile](https://github.com/openemr/openemr-devops/blob/master/docker/openemr/flex/Dockerfile) | [Instructions](https://github.com/openemr/openemr-devops/tree/master/docker/openemr/flex/#openemr-official-docker-image)
2020

21-
Each production build also pushes an immutable `X.Y.Z-YYYY-MM-DD` tag (e.g. `{{ current.patch }}-2026-03-25`) so a deployment can pin a specific build and survive future rebuilds of the same version. See the [Tags page](https://hub.docker.com/r/openemr/openemr/tags) for the most recent dated tag of each track.
21+
Each production build also pushes an immutable `X.Y.Z-YYYY-MM-DD` tag (e.g. `{{ current.full }}-2026-03-25`) so a deployment can pin a specific build and survive future rebuilds of the same version. See the [Tags page](https://hub.docker.com/r/openemr/openemr/tags) for the most recent dated tag of each track.
2222

2323
This [OpenEMR](http://www.open-emr.org) official docker supports automated installation/configuration of OpenEMR. It requires a companion mysql/mariadb container to work.
2424

tools/release/tests/DockerHubOverviewRendererTest.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ public function testRendersAllSlotScalars(): void
4242
{
4343
$rendered = (new DockerHubOverviewRenderer($this->registryPath, self::TEMPLATE_DIR))->render();
4444

45-
self::assertStringContainsString('Current production OpenEMR version is 8.0.0', $rendered);
45+
self::assertStringContainsString('Current production OpenEMR version is 8.0.0.3', $rendered);
4646
self::assertStringContainsString('`8.0.0`, `8.0.0.3`, `latest`', $rendered);
4747
self::assertStringContainsString('docker/openemr/8.0.0/Dockerfile', $rendered);
4848
self::assertStringContainsString('`8.1.0`, `next`', $rendered);
4949
self::assertStringContainsString('docker/openemr/8.1.0/Dockerfile', $rendered);
50-
self::assertStringContainsString('`8.1.1`, `dev`', $rendered);
50+
self::assertStringContainsString('`8.1.1-dev`, `dev`', $rendered);
5151
self::assertStringContainsString('docker/openemr/8.1.1/Dockerfile', $rendered);
5252
}
5353

@@ -102,8 +102,7 @@ private function fixtureRegistry(): string
102102
slots:
103103
current:
104104
minor: "8.0"
105-
full: "8.0.0"
106-
patch: "8.0.0.3"
105+
full: "8.0.0.3"
107106
branch: "rel-800"
108107
docker_dir: "8.0.0"
109108
next:
@@ -113,7 +112,7 @@ private function fixtureRegistry(): string
113112
docker_dir: "8.1.0"
114113
dev:
115114
minor: "8.1"
116-
full: "8.1.1"
115+
full: "8.1.1-dev"
117116
branch: "master"
118117
docker_dir: "8.1.1"
119118
YAML;

tools/release/versions.yml

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,7 @@ version: 1
2020
slots:
2121
current:
2222
minor: "8.0"
23-
full: "8.0.0"
24-
# Legacy quaternary tag (#746). The consolidated build-openemr.yml no longer
25-
# emits `:8.0.0.3` / `:8.0.0.3-<date>` — it publishes only `:<full>`, the
26-
# floating slot tag (current -> :latest), and `:<full>-<date>`. This field is
27-
# now vestigial registry metadata; drop it when current rotates off 8.0.0
28-
# onto plain semver (8.1.x is the next release after 8.1.0, not a 4-part
29-
# patch). See #746, #760.
30-
patch: "8.0.0.3"
23+
full: "8.0.0.3"
3124
branch: "rel-800"
3225
docker_dir: "8.0.0"
3326
next:
@@ -37,7 +30,7 @@ slots:
3730
docker_dir: "8.1.0"
3831
dev:
3932
minor: "8.1"
40-
full: "8.1.1"
33+
full: "8.1.1-dev"
4134
branch: "master"
4235
docker_dir: "8.1.1"
4336

@@ -60,7 +53,7 @@ slots:
6053
files:
6154
- path: docker/openemr/8.0.0/Dockerfile
6255
slot: current
63-
kinds: [docker_clone_branch]
56+
kinds: [docker_arg_branch]
6457

6558
- path: docker/openemr/8.1.0/Dockerfile
6659
slot: next

0 commit comments

Comments
 (0)