feat(auto-derive): atomic flip — retire bump-tag.yml + tools/release/ PHP toolchain#141
Conversation
… PHP toolchain The auto-derive bot (PRs openemr#135, openemr#138) is now the canonical writer of ip_map_branch.txt + docker/scripts/demoLibrary.source. The legacy PHP-based per-tag bumper is fully redundant; remove it. Changes: - Delete .github/workflows/bump-tag.yml (repository_dispatch openemr-tag consumer). - Delete tools/release/ (composer/PHPUnit/IpMapBumper.php toolchain). - Add `repository_dispatch types=release-targets-changed` listener to derive-ip-map.yml so the bot reconciles immediately when upstream pushes release-targets.yml instead of waiting for the next 07:00 UTC tick. - Update reconcile job's if-guard to allow repository_dispatch while preserving the existing schedule + workflow_dispatch-reconcile paths and the repo-owner/test-success gates. pull_request is still excluded from reconcile by the explicit allowlist. - README + workflow header comments updated to reflect retired-state. Cross-repo follow-up (tracked separately): openemr/openemr companion PR to (a) dispatch `release-targets-changed` from a workflow that watches .github/release-targets.yml on master and (b) stop dispatching the now unlistened-for `openemr-tag` event from release-prep.yml:328-337. During the transition the openemr-tag dispatches land here with no listener — harmless no-op. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (13)
💤 Files with no reviewable changes (11)
📝 WalkthroughWalkthroughRemoves the Release toolchain removal and event-driven reconcile
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Adds a fifth cross-repo dispatch event, `release-targets-changed`, plus a workflow that emits it whenever `.github/release-targets.yml` is pushed to master. Companion to openemr/demo_farm_openemr#141, which adds a `repository_dispatch` listener to that repo's `derive-ip-map.yml` so its auto-derive bot reconciles immediately instead of waiting for the next daily 07:00 UTC tick — removes up to 24h of latency without changing the bot's existing daily-schedule safety net. Schema (`tools/release/contracts/dispatch.schema.json`): - Add `release-targets-changed` to the `event` enum and a matching `oneOf` arm bound to a new `releaseTargetsChangedData` definition. - The data block is intentionally empty (`additionalProperties:false`, no properties). The envelope's `sha`/`actor`/`dispatched_at` fully identify the change; consumers re-read release-targets.yml directly from openemr/openemr@master rather than carrying it in the payload. - Update the `event` field description to reflect the conductor now also emits this event alongside the rel-cut/rel-update/tag trio. PHP: - `DispatchRequest::EVENT_RELEASE_TARGETS_CHANGED` constant. - `DispatchDataBuilder` match arm returning `[]` (no CLI options to collect; the empty `data` block is built from no inputs). - `Dispatcher::DEFAULT_TARGET_REPOS` is left untouched — the new workflow scopes the dispatch via explicit `--target-repos=openemr/demo_farm_openemr` so devops + website don't receive an event they don't consume. Workflow (`.github/workflows/notify-release-targets-changed.yml`): - Trigger: push to master touching `.github/release-targets.yml`, plus manual `workflow_dispatch` as a recovery / rerun escape hatch. - Mints a release-App installation token scoped to demo_farm_openemr only (`repositories: demo_farm_openemr`) — minimum surface needed. - Reuses the existing `./.github/actions/setup-php-composer` composite action on PHP 8.5, matching the release-permissions-check pattern (conductor tooling tracks latest stable PHP, not the app floor). - Runs `tools/release/bin/dispatch.php` with `--event=release-targets-changed` and the explicit target-repos. - `permissions: {}` at the workflow level; the dispatch authenticates via the App token, not the workflow's `GITHUB_TOKEN`. Tests: - `DispatchDataBuilderTest::testReleaseTargetsChangedBuildsEmptyData` asserts the match arm returns `[]`. - `DispatchSchemaTest` data providers add good + bad fixtures for the new event. Good fixture: minimal envelope with `"data": {}`. Bad fixture: a stray field inside `data` to exercise `additionalProperties:false`. Existing `openemr-tag` dispatch (release-prep.yml lines ~328-342) is left intact — openemr-devops's release-announcements.yml still consumes it. Vendor-sync follow-up: openemr-devops carries a vendored copy of `dispatch.schema.json` validated by `tools/release/bin/check-vendored.php` in its CI. That check will fail on the next devops PR after this lands; a small sync PR there resolves it. Not blocking for this PR — demo_farm_openemr consumes the dispatch directly via the workflow listener and does no schema validation of its own. Assisted-by: Claude Code Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a fifth cross-repo dispatch event, `release-targets-changed`, plus a workflow that emits it whenever `.github/release-targets.yml` is pushed to master. Companion to openemr/demo_farm_openemr#141, which adds a `repository_dispatch` listener to that repo's `derive-ip-map.yml` so its auto-derive bot reconciles immediately instead of waiting for the next daily 07:00 UTC tick — removes up to 24h of latency without changing the bot's existing daily-schedule safety net. Schema (`tools/release/contracts/dispatch.schema.json`): - Add `release-targets-changed` to the `event` enum and a matching `oneOf` arm bound to a new `releaseTargetsChangedData` definition. - The data block is intentionally empty (`additionalProperties:false`, no properties). The envelope's `sha`/`actor`/`dispatched_at` fully identify the change; consumers re-read release-targets.yml directly from openemr/openemr@master rather than carrying it in the payload. - Update the `event` field description to reflect the conductor now also emits this event alongside the rel-cut/rel-update/tag trio. PHP: - `DispatchRequest::EVENT_RELEASE_TARGETS_CHANGED` constant. - `DispatchDataBuilder` match arm returning `[]` (no CLI options to collect; the empty `data` block is built from no inputs). - `Dispatcher::DEFAULT_TARGET_REPOS` is left untouched — the new workflow scopes the dispatch via explicit `--target-repos=openemr/demo_farm_openemr` so devops + website don't receive an event they don't consume. Workflow (`.github/workflows/notify-release-targets-changed.yml`): - Trigger: push to master touching `.github/release-targets.yml`, plus manual `workflow_dispatch` as a recovery / rerun escape hatch. - Mints a release-App installation token scoped to demo_farm_openemr only (`repositories: demo_farm_openemr`) — minimum surface needed. - Reuses the existing `./.github/actions/setup-php-composer` composite action on PHP 8.5, matching the release-permissions-check pattern (conductor tooling tracks latest stable PHP, not the app floor). - Runs `tools/release/bin/dispatch.php` with `--event=release-targets-changed` and the explicit target-repos. - `permissions: {}` at the workflow level; the dispatch authenticates via the App token, not the workflow's `GITHUB_TOKEN`. Tests: - `DispatchDataBuilderTest::testReleaseTargetsChangedBuildsEmptyData` asserts the match arm returns `[]`. - `DispatchSchemaTest` data providers add good + bad fixtures for the new event. Good fixture: minimal envelope with `"data": {}`. Bad fixture: a stray field inside `data` to exercise `additionalProperties:false`. Existing `openemr-tag` dispatch (release-prep.yml lines ~328-342) is left intact — openemr-devops's release-announcements.yml still consumes it. Vendor-sync follow-up: openemr-devops carries a vendored copy of `dispatch.schema.json` validated by `tools/release/bin/check-vendored.php` in its CI. That check will fail on the next devops PR after this lands; a small sync PR there resolves it. Not blocking for this PR — demo_farm_openemr consumes the dispatch directly via the workflow listener and does no schema validation of its own. Assisted-by: Claude Code Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…12657) ## What Adds a fifth cross-repo dispatch event, `release-targets-changed`, plus a new workflow that emits it: - **Schema** (`tools/release/contracts/dispatch.schema.json`): - `release-targets-changed` added to the `event` enum - New `releaseTargetsChangedData` definition with `additionalProperties: false` and no properties (the envelope's `sha`/`actor`/`dispatched_at` fully identify the change; consumers re-read release-targets.yml directly from `openemr/openemr@master`) - Matching `oneOf` arm - `event` field description updated - **PHP**: - `DispatchRequest::EVENT_RELEASE_TARGETS_CHANGED` - `DispatchDataBuilder` match arm returning `[]` - **Workflow** (`.github/workflows/notify-release-targets-changed.yml`): - Triggered by push to `master` touching `.github/release-targets.yml`, plus manual `workflow_dispatch` - Mints the release App token scoped to `demo_farm_openemr` only - Reuses `./.github/actions/setup-php-composer` on PHP 8.5 (conductor-tooling convention) - Calls `tools/release/bin/dispatch.php --event=release-targets-changed --target-repos=openemr/demo_farm_openemr` - **Tests**: - `DispatchDataBuilderTest::testReleaseTargetsChangedBuildsEmptyData` - `DispatchSchemaTest` good + bad fixtures (bad fixture exercises `additionalProperties: false` via a stray data key) ## Why To drive openemr/demo_farm_openemr's auto-derive bot immediately when `.github/release-targets.yml` changes, instead of waiting for its daily 07:00 UTC tick. Removes up to ~24h of latency between editing release-targets.yml and demo_farm reconciling. The bot's existing daily-schedule safety net is unaffected — this is purely additive. ## Companion PR openemr/demo_farm_openemr#141 adds the `repository_dispatch: types: [release-targets-changed]` listener on the bot side. That PR works on its own (daily schedule still ticks). This PR is what makes the dispatch arrive. ## Scope decisions - **`Dispatcher::DEFAULT_TARGET_REPOS` left untouched** — the new workflow scopes via explicit `--target-repos` so openemr-devops and website-openemr don't receive an event they don't consume. - **Existing `openemr-tag` dispatch in `release-prep.yml` left intact** — openemr-devops's `release-announcements.yml` still consumes it. ## Vendor sync follow-up openemr-devops carries a vendored copy of `dispatch.schema.json` validated by `tools/release/bin/check-vendored.php` in its CI. That check will fail on the next devops PR after this lands; a small sync PR there will resolve it. **Not blocking for this PR** — demo_farm_openemr consumes the dispatch directly via the workflow listener and does no schema validation itself, so the bot works end-to-end the moment both PRs are merged regardless of when the devops vendor copy catches up. ## Test plan - [ ] CI passes (isolated release tests run all schema fixtures + new DispatchDataBuilder case; actionlint passes on the new workflow) - [ ] After merge: editing `.github/release-targets.yml` on master fires `notify-release-targets-changed`, which dispatches `release-targets-changed` to demo_farm_openemr; the demo_farm bot's derive-ip-map run starts within seconds rather than at the next 07:00 UTC tick - [ ] `openemr-tag` dispatch from `release-prep.yml` continues to fire normally on the next release-prep merge - [ ] Open the follow-up vendor-sync PR against openemr-devops once that repo's CI surfaces the drift 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rgets-changed event (#12660) ## Summary Updates `docs/RELEASE_PROCESS.md` to describe the new demo_farm flow that shipped 2026-06-28. **What changed in the demo_farm flow.** The old `bump-tag.yml` workflow in `demo_farm_openemr` (which consumed `openemr-tag` and pushed directly to master after rewriting matching production-demo rows in `ip_map_branch.txt`) was retired. The new `derive-ip-map` auto-derive bot is now the canonical writer for `ip_map_branch.txt` + `docker/scripts/demoLibrary.source`: it regenerates both files from upstream `openemr/openemr` state (`.github/release-targets.yml` + per-rel-branch Dockerfile ARGs + `ci/apache_*` listing + flex Dockerfile) and reconciles them onto the `auto-derive/reconciliation` stable branch via a reviewable PR. Triggers: `repository_dispatch types: [release-targets-changed]` (immediate), daily 07:00 UTC cron (self-healing fallback), `workflow_dispatch` (manual). **Why.** This is the cross-repo trio's final piece — companion to: - #12657 — added the notifier side in this repo (`.github/workflows/notify-release-targets-changed.yml`, fires `release-targets-changed` to demo_farm on master pushes that touch `.github/release-targets.yml`) - openemr/demo_farm_openemr#141 series (PRs #135/#138/#141/#142/#143) — added the consumer side: the auto-derive bot, the reconciliation PR pattern, and retirement of `bump-tag.yml` Without this doc update, `RELEASE_PROCESS.md` describes a flow that no longer exists. ## Sections rewritten - **Intro paragraph (line ~5):** now correctly says *three* repos open reviewable PRs (conductor, docs, demo_farm reconciliation), not two. - **Per-repo role table (line ~16):** `demo_farm_openemr` row rewritten for the auto-derive bot's trigger set, output files, and reviewable-PR pattern. - **Cross-repo flow mermaid diagram:** `bump-tag.yml` workflow node (purple hex) replaced with the auto-derive reconciliation PR as a blue (reviewable) node — same shape as the conductor + docs PRs. The `openemr-tag -> bump` arrow is gone; the new `release-targets-changed` arrow sources from the `oe` subgraph (since the dispatch fires on master pushes, not from the conductor PR). - **Diagram legend:** rewritten to describe the auto-derive bot's three triggers (dispatch + daily cron + manual `workflow_dispatch`) instead of `bump-tag.yml`. - **Cross-repo events intro + table:** intro now mentions `master`-push-driven dispatch; `openemr-tag` row drops `demo_farm_openemr` as a consumer; new `release-targets-changed` row added with payload `{}` (envelope's `sha`/`actor`/`dispatched_at` fully identify the change). - **Phase 2 step 2:** production-demo-row seeding prerequisite for new minor lines is gone — `release-targets.yml` is the contract; new minor lines flow through naturally once represented there. - **Phase 4 prelude (ship phase):** "demo-farm bump" dropped from the `openemr-tag` cascade list; demo-farm runs on its own track (step 15). - **Phase 6 step 15:** full rewrite for the `derive-ip-map` bot — workflow link, derivation inputs, reconciliation-branch PR pattern, triggers, maintainer-review note. - **Automation gaps table:** `demo_farm_openemr#110` row (seed-new-minor-rows) removed; added to the "Recently closed" paragraph with the auto-derive-rewrite as rationale. Umbrella issue's sub-issue count updated from five to four. - **Out-of-band tag recovery row (line ~230):** stray `bump-tag.yml` reference dropped from the "dispatch fired" sub-case. ## Test plan - [ ] Render the mermaid diagram (GitHub PR preview is sufficient) and confirm the new `auto-derive/reconciliation PR` node renders blue and the `release-targets-changed` arrow lands on it - [ ] Scan the rendered doc end-to-end for any remaining `bump-tag.yml`, `production-demo` seeding, or `direct push to master` references — none should remain - [ ] Confirm cross-repo events table reads cleanly with the new fourth row and the trimmed `openemr-tag` target list - [ ] Confirm Phase 2 step 2 no longer carries a demo_farm seeding prerequisite ## Out of scope - The conductor's `release-prep.yml` still emits `openemr-tag` to `demo_farm_openemr` (`.github/workflows/release-prep.yml:328-337`). With no listener there it's a harmless no-op; cleanup is its own follow-up PR. - Other sections of `RELEASE_PROCESS.md` unrelated to the demo_farm flow.
What changes
.github/workflows/bump-tag.yml(therepository_dispatch types=openemr-tagconsumer).tools/release/(composer/PHPUnit/IpMapBumper.php PHP toolchain).repository_dispatch types=release-targets-changedlistener toderive-ip-map.yml.if:guard to allow the new event (alongside existing schedule +workflow_dispatch mode=reconcile).Why now
PRs #135 + #138 made the auto-derive bot the canonical writer of
ip_map_branch.txt+docker/scripts/demoLibrary.source. The PHP bumper's job (manual tag-bump of production-demo rows on each release) is now performed daily and idempotently by the bot from upstreamrelease-targets.yml. Keeping both wired risks dueling writers; pulling the PHP toolchain is the atomic flip.Behavior during transition (before openemr-side companion lands)
workflow_dispatch.Behavior after openemr-side companion lands
openemr/openemrmaster.github/release-targets.yml-> openemr-side workflow dispatchesrelease-targets-changedto this repo -> bot reconciles immediately.Existing
openemr-tagdispatchStill fires from
openemr/openemr/.github/workflows/release-prep.yml:328-337but now lands here with no listener (harmless no-op). The companion PR will both add the new dispatch and remove the dead one.Trigger x job matrix (post-flip)
schedule(07:00 UTC)repository_dispatch release-targets-changedworkflow_dispatch mode=reconcileworkflow_dispatch mode=dry-runpull_request(touching scoped paths)pull_requestis excluded fromreconcileby the explicit-allowlistevent_nameclause. Repo-owner +repository == openemr/demo_farm_openemrguards preserved.Test plan
test+dry-runjobs gated as before)workflow_dispatch mode=reconcilefrom master after merge produces sensible outputopenemr/openemrfiled as follow-up (addrelease-targets-changeddispatch on master push of.github/release-targets.yml; remove now-deadopenemr-tagdispatch fromrelease-prep.yml)Verification done locally
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/derive-ip-map.yml'))"-> cleangrep -rn "bump-tag|tools/release|IpMapBumper|bump-ip-map|openemr-tag"-> only this PR's historical README lines explaining what was retiredfindconfirms no remainingtools/release/and no.github/workflows/bump-tag*🤖 Generated with Claude Code
Summary by CodeRabbit