From 71e4692b6b79a3b9180dee37bd52ee7b8c079dd1 Mon Sep 17 00:00:00 2001 From: Patrick Dodgen Date: Wed, 10 Jun 2026 10:42:54 -0600 Subject: [PATCH 1/5] docs: add DEVEX-1628 design spec for nightly common bump build-on-tag --- ...-10-common-bump-build-on-nightly-design.md | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md diff --git a/docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md b/docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md new file mode 100644 index 0000000..77667b6 --- /dev/null +++ b/docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md @@ -0,0 +1,127 @@ +# Nightly common bumps should build & tag (DEVEX-1628) + +- **Date:** 2026-06-10 +- **Ticket:** DEVEX-1628 (Bug, In Progress) — "Automatic Common bumps are not getting built or deployed to integration" +- **Repos affected:** `encodium/.github` (shared `php-common-bump.yaml`) + 11 service repos (their nightly common-update workflow) + +## Problem + +`php-common-bump.yaml` commits the `revolutionparts/common` version bump with `[skip actions]` +([line 85](https://github.com/encodium/.github/blob/main/.github/workflows/php-common-bump.yaml)). +That suppresses the `push: main`-triggered `Build.yaml`, so a common bump never produces a +new image tag and the integration environment never receives the updated common. + +This interacts with DEVEX-1629: now that `workflow_dispatch` skips `integration-deploy`, +re-triggering a build via dispatch would not deploy either. The only clean way a common bump +reaches integration is for the bump to be a **real push to main** (which builds, tags, and — +being a push — deploys). The bump push is already made with `REPO_WRITE_PAT` (a PAT, which +*does* trigger workflows), so the literal `[skip actions]` text is the only thing stopping it. + +## Goal + +Every **nightly** common bump that actually changes common produces a new build/tag (and, for +integration repos, an integration deploy) — the ticket's "ideal scenario." Without disturbing +the many other `php-common-bump` consumers. + +## Decisions (agreed) + +- **Mechanism:** make the suppression configurable; do not remove `[skip actions]` globally. +- **Trigger context:** nightly only. The merge-path `upgrade-common.yaml` keeps skipping, so + normal app merges don't double-build. +- **Scope:** every repo that has a nightly common-update workflow (all such consumers). + +## Design + +### Change 1 — `php-common-bump.yaml` (shared, one edit) + +Add an optional input, **defaulting to today's behavior**: + +```yaml + skip_ci: + description: "Append [skip actions] to the bump commit so it does NOT trigger workflows." + required: false + type: boolean + default: true +``` + +In the `Commit Common Bump` step, append `[skip actions]` only when `skip_ci` is true (pass it +via `env:` to avoid expression-in-shell pitfalls): + +```bash +SUFFIX="" +[ "$SKIP_CI" = "true" ] && SUFFIX=" [skip actions]" +git commit -am "${COMMIT_MESSAGE}${SUFFIX}" +``` + +`default: true` makes this **byte-for-byte backward compatible**: every existing caller that +does not set `skip_ci` (the merge-path `upgrade-common.yaml`, daemons, batch, the merge-main +family, etc.) keeps committing with `[skip actions]` exactly as today. Nothing else in the +workflow changes (checkout, composer install, `composer update revolutionparts/common`, the +`git diff-index` no-change guard, and the rebase-retry push all stay). + +### Change 2 — nightly workflows opt in (11 repos) + +Each repo's nightly common-update workflow passes `skip_ci: false` to the reusable workflow: + +```yaml + update-common: + uses: encodium/.github/.github/workflows/php-common-bump.yaml@main + with: + php_version: "8.3" + commit_message: "chore: nightly update revolutionparts/common" + skip_ci: false # <-- added + secrets: + write_pat: ${{ secrets.REPO_WRITE_PAT }} + packagist_username: ${{ secrets.PACKAGIST_USERNAME }} + packagist_password: ${{ secrets.PACKAGIST_PASSWORD }} +``` + +**Repos (11):** +- `Nightly Common Update.yaml` (8): rp_api, internal_api, catalog_api, license_api, + returns-api, accounts-api, webstore, listings-url-service +- `nightly-common-update.yaml` (3): listings, marketplaces, payments + +The merge-path `upgrade-common.yaml` files are **left unchanged** in every repo. + +## Data flow (enabled) + +``` +nightly cron → composer update revolutionparts/common + → (only if common changed) commit WITHOUT [skip actions] → push main (REPO_WRITE_PAT) + → Build.yaml runs on push → tag-and-release cuts a new -main.N tag + → integration-deploy runs (push event; DEVEX-1629 gate allows push) → integration has fresh common +``` + +For each repo the effect follows that repo's own `push: main` pipeline: the integration-app +repos build → tag → integration-deploy; the merge-main-family repos (listings, marketplaces, +payments) build + tag per their flow. A repo with no `push: main` build pipeline is a harmless +no-op (the commit simply omits `[skip actions]`). + +## Edge cases / safety + +- **No loop.** The bump push also re-triggers `upgrade-common` (it is `push: main`); it runs + `composer update`, finds common already current, hits the `git diff-index` guard, commits + nothing, and terminates. +- **Bounded churn.** The `diff-index` guard means a build happens only when common actually + changed — at most one nightly build per repo per common change. +- **No merge double-builds.** Because `upgrade-common` keeps skipping, a normal app merge does + not spawn a second bump-build. +- **Tag mechanics unchanged.** The `chore:` bump commit takes the default patch bump → + `-main.N` prerelease tag, which the Start Release Train can later promote. + +## Interactions + +- **DEVEX-1630** (build-workflow unification): independent. This change edits *nightly* + workflows + `php-common-bump.yaml`, not `Build.yaml`. It relies only on the push→tag→deploy + behavior the thin callers preserve, so it works before or after that migration. No file + conflict. +- **DEVEX-1629** (integration gate): complementary. A common bump is a real push, so it deploys + via the push path — exactly the behavior the gate intends. + +## Out of scope + +- Repos without a nightly common-update workflow (daemons, batch, radmin, vin_decoder_service): + no nightly bump exists to opt in. Adding nightly workflows to them is a separate effort. +- The merge-path (`upgrade-common.yaml`) build-on-bump — deliberately excluded (nightly only). +- The disabled `Nightly Integration Deploy.yaml` placeholder (deploy-latest-tag) — a separate, + complementary idea, not needed for this ticket. From 37b08ba7922ab892ff2e7620bfe571d3ebf2afb2 Mon Sep 17 00:00:00 2001 From: Patrick Dodgen Date: Wed, 10 Jun 2026 10:50:45 -0600 Subject: [PATCH 2/5] docs: frame DEVEX-1628 goal as all common-dependents; note daemon follow-on --- ...-06-10-common-bump-build-on-nightly-design.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md b/docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md index 77667b6..c55bc90 100644 --- a/docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md +++ b/docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md @@ -19,9 +19,15 @@ being a push — deploys). The bump push is already made with `REPO_WRITE_PAT` ( ## Goal -Every **nightly** common bump that actually changes common produces a new build/tag (and, for -integration repos, an integration deploy) — the ticket's "ideal scenario." Without disturbing -the many other `php-common-bump` consumers. +**Anything that depends on common should receive a new tag and be deployed to integration when +common changes.** Concretely: every **nightly** common bump that actually changes common produces +a new build/tag (and, for repos with an integration pipeline, an integration deploy) — the +ticket's "ideal scenario" — without disturbing the many other `php-common-bump` consumers. + +This change covers every common-dependent repo that **has a nightly common-update workflow** +(the 11 below). Common-dependents that lack a nightly workflow (daemons, batch, radmin, +vin_decoder_service) cannot be opted in until one exists; bringing them to full coverage by +adding nightly workflows is a tracked follow-on (see Out of scope). ## Decisions (agreed) @@ -121,7 +127,9 @@ no-op (the commit simply omits `[skip actions]`). ## Out of scope - Repos without a nightly common-update workflow (daemons, batch, radmin, vin_decoder_service): - no nightly bump exists to opt in. Adding nightly workflows to them is a separate effort. + no nightly bump exists to opt in. To fully satisfy "anything that depends on common" they would + each need a nightly common-update workflow (and, for integration deploy, a push→integration + build pipeline) added — a tracked follow-on, not part of this change. - The merge-path (`upgrade-common.yaml`) build-on-bump — deliberately excluded (nightly only). - The disabled `Nightly Integration Deploy.yaml` placeholder (deploy-latest-tag) — a separate, complementary idea, not needed for this ticket. From fd0db35c1c90619fd1a33d50dc546164dc5455b9 Mon Sep 17 00:00:00 2001 From: Patrick Dodgen Date: Wed, 10 Jun 2026 10:52:53 -0600 Subject: [PATCH 3/5] docs: add DEVEX-1628 implementation plan --- ...2026-06-10-common-bump-build-on-nightly.md | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 docs/superpowers/plans/2026-06-10-common-bump-build-on-nightly.md diff --git a/docs/superpowers/plans/2026-06-10-common-bump-build-on-nightly.md b/docs/superpowers/plans/2026-06-10-common-bump-build-on-nightly.md new file mode 100644 index 0000000..490fc5f --- /dev/null +++ b/docs/superpowers/plans/2026-06-10-common-bump-build-on-nightly.md @@ -0,0 +1,194 @@ +# Nightly Common Bump Build-on-Tag Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make a nightly `revolutionparts/common` bump produce a new build/tag (and, for repos with an integration pipeline, an integration deploy) instead of being suppressed by `[skip actions]`. + +**Architecture:** Add an optional `skip_ci` input (default `true`, fully backward-compatible) to the shared `php-common-bump.yaml`; the bump commit appends `[skip actions]` only when `skip_ci` is true. The 11 repos that have a nightly common-update workflow opt in by passing `skip_ci: false`. The merge-path `upgrade-common.yaml` is left untouched (keeps skipping → no merge double-builds). + +**Tech Stack:** GitHub Actions reusable workflows (`workflow_call`), `mathieudutour/github-tag-action`, `REPO_WRITE_PAT` (PAT pushes trigger workflows). + +**Spec:** `docs/superpowers/specs/2026-06-10-common-bump-build-on-nightly-design.md` +**Ticket:** DEVEX-1628. + +--- + +## How "tests" work here + +There is no unit harness for workflows, and a common bump only commits when common **actually +changed** (a `git diff-index` guard), so a build can't be forced on demand without mutating +`main`. Verification is therefore: +1. **Static lint** — `actionlint` on every changed file. +2. **Logic review** — confirm the conditional `[skip actions]` suffix is correct. +3. **Live observation** — after merge + opt-in, `workflow_dispatch` the pilot's nightly workflow + and read the run: if common changed, confirm the bump commit has **no** `[skip actions]` and a + `Build` run was triggered; if common was already current, confirm the run no-ops cleanly + (expected) and confirm correctness on the next real common change. + +Reusable workflows are referenced by ref. The `skip_ci` input must exist on +`encodium/.github` **`main`** before any caller passes it (an unknown input fails the call), so +**Task 1 (the shared change) must merge before the opt-in PRs (Tasks 3+)**. + +--- + +## File Structure + +**`encodium/.github` (shared — merges first):** +- Modify: `.github/workflows/php-common-bump.yaml` — add `skip_ci` input; conditional `[skip actions]`. + +**Per service repo (one PR each) — add `skip_ci: false` to the nightly common-update workflow's `with:` block:** +- `Nightly Common Update.yaml` (8): rp_api, internal_api, catalog_api, license_api, returns-api, accounts-api, webstore, listings-url-service +- `nightly-common-update.yaml` (3): listings, marketplaces, payments + +--- + +## Task 1: Add `skip_ci` input to `php-common-bump.yaml` + +**Files:** Modify `.github/workflows/php-common-bump.yaml` (worktree `~/dev/claude/github-DEVEX-1628`, branch `DEVEX-1628-common-bump-build-on-nightly`). + +- [ ] **Step 1: Add the input.** Under `on.workflow_call.inputs`, after `continue_on_error`, add: + +```yaml + skip_ci: + description: "Append [skip actions] to the bump commit so it does NOT trigger workflows." + required: false + type: boolean + default: true +``` + +- [ ] **Step 2: Make the commit suffix conditional.** In the `Commit Common Bump` step + (`id: commit`), the bump currently runs: + +```bash + git commit -am "${{ inputs.commit_message }} [skip actions]" +``` + +Replace that single line with env-driven, conditional logic (keep everything else in the step — +the `diff-index` guard above it and the rebase-retry push below it — unchanged): + +```bash + SUFFIX="" + [ "$SKIP_CI" = "true" ] && SUFFIX=" [skip actions]" + git commit -am "${COMMIT_MESSAGE}${SUFFIX}" +``` + +And add an `env:` block to that step so the shell reads the inputs safely (place it on the +`Commit Common Bump` step, alongside `id: commit`): + +```yaml + env: + SKIP_CI: ${{ inputs.skip_ci }} + COMMIT_MESSAGE: ${{ inputs.commit_message }} +``` + +> `default: true` makes this byte-for-byte backward compatible — every caller that does not set +> `skip_ci` (upgrade-common, daemons, batch, the merge-main family) keeps committing with +> `[skip actions]`. Booleans render as the strings `"true"`/`"false"`, so `[ "$SKIP_CI" = "true" ]` +> is the correct test. + +- [ ] **Step 3: Lint.** `actionlint .github/workflows/php-common-bump.yaml` → expect zero errors. + Also confirm YAML parses: `ruby -ryaml -e "YAML.load_file('.github/workflows/php-common-bump.yaml')"`. + +- [ ] **Step 4: Commit, push, open draft PR.** + +```bash +git add .github/workflows/php-common-bump.yaml +git commit -m "feat: add skip_ci input to php-common-bump (default true)" +git push -u origin DEVEX-1628-common-bump-build-on-nightly +gh pr create --repo encodium/.github --draft --base main \ + --title "DEVEX-1628: optional skip_ci on php-common-bump" \ + --body "Adds an optional skip_ci input (default true = current behavior) so nightly common bumps can omit [skip actions] and trigger a build/tag. Backward-compatible: no existing caller changes behavior. Nightly workflows opt in via separate PRs. Refs DEVEX-1628" +``` + +## Task 2: Merge Task 1 (human review gate) + +- [ ] **Step 1:** Reviewer approves and merges the `encodium/.github` PR to `main`. The opt-in + PRs below reference `php-common-bump.yaml@main` and require the `skip_ci` input to exist there. + +## Task 3: Pilot opt-in — internal_api + +**Files:** Modify `internal_api/.github/workflows/Nightly Common Update.yaml`. + +- [ ] **Step 1: Create a worktree.** + +```bash +cd ~/dev/internal_api && git fetch origin -q +git worktree add -b DEVEX-1628-nightly-build ~/dev/claude/internal_api-DEVEX-1628 origin/main +``` + +- [ ] **Step 2: Add `skip_ci: false` to the `with:` block.** The job currently reads: + +```yaml + update-common: + uses: encodium/.github/.github/workflows/php-common-bump.yaml@main + with: + php_version: "8.3" + commit_message: "chore: nightly update revolutionparts/common" + secrets: + write_pat: ${{ secrets.REPO_WRITE_PAT }} + packagist_username: ${{ secrets.PACKAGIST_USERNAME }} + packagist_password: ${{ secrets.PACKAGIST_PASSWORD }} +``` + +Add one line to `with:`: + +```yaml + with: + php_version: "8.3" + commit_message: "chore: nightly update revolutionparts/common" + skip_ci: false +``` + +- [ ] **Step 3: Lint.** `actionlint ".github/workflows/Nightly Common Update.yaml"` → zero errors. + +- [ ] **Step 4: Commit, push, open draft PR.** + +```bash +git add ".github/workflows/Nightly Common Update.yaml" +git commit -m "ci: build & tag on nightly common bump (skip_ci false)" +git push -u origin DEVEX-1628-nightly-build +gh pr create --repo encodium/internal_api --draft --base main \ + --title "DEVEX-1628: build & tag on nightly common bump" \ + --body "Nightly common bump now omits [skip actions] so it builds, tags, and deploys to integration. Refs DEVEX-1628" +``` + +- [ ] **Step 5: Mark ready + merge** (after Task 2 is merged). Then **live-verify** by dispatching + the nightly workflow on `main`: + +```bash +gh workflow run "Nightly Common Update.yaml" --repo encodium/internal_api --ref main +# find the run, then read the upgrade-common job log: +gh run list --repo encodium/internal_api --workflow "Nightly Common Update.yaml" --limit 1 --json databaseId,status +``` +Expected, **if common changed**: a bump commit on `main` whose message has **no** `[skip actions]`, +and a new `Build` run kicks off (→ new `-main.N` tag → integration deploy). **If common was +already current**: the run logs "No changes to commit" and ends — that is correct; confirm the +suffix logic on the next real common change. Either way the run itself must succeed. + +## Task 4: Fan out `skip_ci: false` to the remaining 10 repos + +For each repo below: worktree off `origin/main`, add `skip_ci: false` to the nightly workflow's +`with:` block (exactly as Task 3 Step 2 — if a repo has no `with:` block, add one containing +`skip_ci: false`), `actionlint`, commit `ci: build & tag on nightly common bump (skip_ci false)`, +push, open a draft PR titled `DEVEX-1628: build & tag on nightly common bump`, then merge. + +- [ ] **`Nightly Common Update.yaml`:** rp_api, catalog_api, license_api, returns-api, accounts-api, webstore, listings-url-service +- [ ] **`nightly-common-update.yaml`** (lowercase filename — confirm the exact path per repo): listings, marketplaces, payments + +Per repo: +- [ ] Worktree: `git -C ~/dev/ worktree add -b DEVEX-1628-nightly-build ~/dev/claude/-DEVEX-1628 origin/main` +- [ ] Edit the nightly workflow `with:` → add `skip_ci: false` +- [ ] `actionlint ` → zero errors +- [ ] Commit `ci: build & tag on nightly common bump (skip_ci false)`, push, draft PR (`Refs DEVEX-1628`), merge + +> Note: the lowercase-`nightly-common-update.yaml` repos (listings, marketplaces, payments) are +> the merge-main family; their nightly bump triggers their own `push: main` build pipeline (build +> + tag per their flow) rather than the `Build.yaml` integration path. listings-url-service is a +> harmless no-op if it has no `push: main` build. All still take the uniform `skip_ci: false` edit. + +## Done criteria + +- [ ] `php-common-bump.yaml` on `main` has `skip_ci` (default `true`); no existing caller's behavior changed. +- [ ] All 11 nightly common-update workflows pass `skip_ci: false`; every `upgrade-common.yaml` is untouched. +- [ ] Pilot live-verified: a nightly bump with a real common change produces a commit without `[skip actions]` and triggers a build/tag (internal_api). +- [ ] No loop and no merge double-build observed (the `diff-index` guard + untouched merge path hold). From 1687430773b18f08a19dd6894c0816c16d6a235c Mon Sep 17 00:00:00 2001 From: Patrick Dodgen Date: Wed, 10 Jun 2026 10:53:53 -0600 Subject: [PATCH 4/5] feat: add skip_ci input to php-common-bump (default true) --- .github/workflows/php-common-bump.yaml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/php-common-bump.yaml b/.github/workflows/php-common-bump.yaml index 19ce88f..a3bccd0 100644 --- a/.github/workflows/php-common-bump.yaml +++ b/.github/workflows/php-common-bump.yaml @@ -14,6 +14,11 @@ on: required: false type: boolean default: false + skip_ci: + description: "Append [skip actions] to the bump commit so it does NOT trigger workflows." + required: false + type: boolean + default: true secrets: write_pat: required: true @@ -71,6 +76,9 @@ jobs: command: composer update revolutionparts/common --prefer-dist --no-interaction --no-progress --optimize-autoloader --apcu-autoloader - name: Commit Common Bump id: commit + env: + SKIP_CI: ${{ inputs.skip_ci }} + COMMIT_MESSAGE: ${{ inputs.commit_message }} run: | git config user.name github-actions git config user.email github-actions@github.com @@ -82,7 +90,9 @@ jobs: exit 0 fi - git commit -am "${{ inputs.commit_message }} [skip actions]" + SUFFIX="" + [ "$SKIP_CI" = "true" ] && SUFFIX=" [skip actions]" + git commit -am "${COMMIT_MESSAGE}${SUFFIX}" # Push with retry logic to handle race conditions where main has moved MAX_ATTEMPTS=5 From 4dc932cc42c3917701dca9e7b35190663fd159e7 Mon Sep 17 00:00:00 2001 From: Patrick Dodgen Date: Wed, 10 Jun 2026 10:56:51 -0600 Subject: [PATCH 5/5] fix: use if/then for skip_ci suffix (avoid set -e ambiguity) --- .github/workflows/php-common-bump.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/php-common-bump.yaml b/.github/workflows/php-common-bump.yaml index a3bccd0..f6d65cc 100644 --- a/.github/workflows/php-common-bump.yaml +++ b/.github/workflows/php-common-bump.yaml @@ -91,7 +91,9 @@ jobs: fi SUFFIX="" - [ "$SKIP_CI" = "true" ] && SUFFIX=" [skip actions]" + if [ "$SKIP_CI" = "true" ]; then + SUFFIX=" [skip actions]" + fi git commit -am "${COMMIT_MESSAGE}${SUFFIX}" # Push with retry logic to handle race conditions where main has moved