Skip to content

feat(ci): cut over to unified ci.yml, delete legacy workflows (PR 5/6)#60

Merged
phramz merged 1 commit into
mainfrom
feat/local-ci-pr5-old-workflow-cutover
Apr 24, 2026
Merged

feat(ci): cut over to unified ci.yml, delete legacy workflows (PR 5/6)#60
phramz merged 1 commit into
mainfrom
feat/local-ci-pr5-old-workflow-cutover

Conversation

@phramz

@phramz phramz commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Fifth of the six-PR rollout in docs/superpowers/specs/2026-04-23-local-ci-unification-design.md. PR 4 (#59) shipped the unified ci.yml running alongside the legacy pipeline; this PR retires the legacy side.

Deleted (13 files):

  • Workflows: build-php-core.yml, build-extension.yml, plan.yml, plan-and-build.yml, on-push.yml, integration-test.yml, compat-harness.yml, nightly.yml, manual.yml, gc-bundles.yml, bootstrap.yml (depended on deleted workflows), ci-lint.yml (folded into ci.yml::lint).
  • test/smoke/local-ci.sh — replaced by make ci-cell OS=… ARCH=… PHP=….

Flipped:

  • ci.yml::publish drops the vars.PHPUP_NEW_CI_PUBLISH == '1' gate and the (new ci.yml) marker in the lockfile commit message — it's now the sole GHCR + lockfile writer.

Folded + retargeted:

  • ci.yml::lint gained the go vet step from the deleted ci-lint.yml. Everything else ci-lint used to cover (golangci-lint, gofmt, mod-tidy, go test, go build) was already exercised by ci.yml's lint + unit + pipeline jobs.
  • Makefile: dropped check-fast (became redundant without local-ci) and the local-ci target. make check is the pre-push gate; make ci-cell reproduces one pipeline cell locally.

Retained (per design):

  • ci.yml, release-please.yml, check-release-pr.yml (release engineering), security-rebuild.yml, watch-*.yml (orthogonal; re-trigger ci.yml).

Docs refreshed:

  • CLAUDE.md Quality Gates + Testing sections point at make ci-cell instead of the deleted local-ci smoke.
  • CONTRIBUTING.md refers to ci.yml (not ci-lint.yml) and notes gc-bundles is now manual on-demand.
  • README.md v2-compat section describes fixture coverage inside ci.yml::pipeline instead of the deleted compat-harness.yml.
  • Stale code comments in cmd/{planner,gc-bundles,phpup}, internal/build/, internal/planner/, internal/registry/ that pointed at deleted workflow files have been refreshed to describe current behavior.

Test plan

  • make check — green locally
  • CI ci.yml green on this PR (lint + unit + 16 Pipeline cells + publish job should only fire post-merge on main)
  • After merge, first push to main runs ci.yml::publish (previously gated off) — verify GHCR receives bundles and the lockfile-update commit lands on main

Complete the cutover planned in docs/superpowers/specs/2026-04-23-
local-ci-unification-design.md. The new ci.yml (PR 4) is now the sole
CI + publish path; the parallel-run grace period is over.

Deleted workflows:
  build-php-core.yml, build-extension.yml — superseded by
    ci.yml::pipeline (phpup build cell + phpup test)
  plan.yml, plan-and-build.yml, on-push.yml — orchestrator layer
    replaced by ci.yml's inline matrix
  integration-test.yml, compat-harness.yml — fixtures now run
    inside each pipeline cell via phpup test (see
    test/compat/fixtures.yaml)
  nightly.yml, manual.yml, gc-bundles.yml — scheduled/dispatch
    entry points removed; gc-bundles still usable on-demand as
    `go run ./cmd/gc-bundles --org buildrush --min-age-days N`
  bootstrap.yml — depended on plan.yml + build-php-core.yml +
    build-extension.yml; dead after those deletions
  ci-lint.yml — folded into ci.yml::lint (adds `go vet` step;
    golangci-lint / gofmt / mod-tidy / test / build were already
    covered by ci.yml's lint+unit jobs)

Deleted scripts:
  test/smoke/local-ci.sh — docker smoke replaced by `make ci-cell`,
    which runs one full pipeline cell (phpup build cell + phpup test)
    locally. The `local-ci` Makefile target is removed with it.

Publish cutover:
  ci.yml::publish drops the `vars.PHPUP_NEW_CI_PUBLISH == '1'` gate
  and the "(new ci.yml)" marker in the lockfile commit message —
  it's now the sole writer to ghcr.io and the lockfile.

Housekeeping:
  - Makefile: drop `check-fast` (was only distinct from `check` via
    the now-gone local-ci smoke), retarget `check` at the fast path.
  - CLAUDE.md: Quality Gates + Testing sections updated to point at
    `make ci-cell` for full-cell validation instead of the deleted
    local-ci smoke.
  - CONTRIBUTING.md: refer to ci.yml instead of ci-lint.yml; note
    that gc-bundles is now manual.
  - README.md: v2-compat section now describes fixture coverage
    inside ci.yml::pipeline instead of the deleted compat-harness.yml.
  - Refresh stale code comments in cmd/{planner,gc-bundles,phpup},
    internal/build/, internal/planner/, internal/registry/ that
    pointed at deleted workflow files.

Verification: make check passes; verified ci.yml is the only CI
workflow triggering on push/PR to main (watch-*.yml and
security-rebuild.yml re-trigger ci.yml; release-please.yml +
check-release-pr.yml are orthogonal release tooling, retained).
@phramz
phramz merged commit 34a9129 into main Apr 24, 2026
20 checks passed
@phramz
phramz deleted the feat/local-ci-pr5-old-workflow-cutover branch April 24, 2026 08:57
phramz added a commit that referenced this pull request Apr 24, 2026
Adds an on-demand rebuild surface to ci.yml and rewires the stale
dispatch glue that PR #60 (legacy workflow cutover) left hanging.

ci.yml
  - New `workflow_dispatch` trigger with a `force: boolean` input.
    Defaults to false; a force=true dispatch skips the spec-hash
    cache-probe in every pipeline cell so security-class rebuilds
    produce fresh artifacts even when the inputs are unchanged.
  - `pipeline` cell threads `inputs.force` into `make ci-cell`
    via a FORCE env var so the downstream phpup gets --force.

internal/build + Makefile
  - phpOpts / extOpts / cellOpts grow a Force field; each parse*
    FlagSet exposes --force.
  - BuildPHP and BuildExt bypass the LookupBySpec cache-probe when
    opts.Force is set, printing a "--force, skipping cache-probe"
    note so the pipeline log is obvious about why the build ran.
  - BuildCell forwards --force to both downstream BuildPHP and each
    BuildExt so a cell invocation does the right thing end-to-end.
  - `make ci-cell FORCE=1` threads through to the CLI.
  - Unit test: TestBuildPHP_Force_BypassesCacheHit seeds a layout
    with an identically-spec-hashed bundle, invokes BuildPHP with
    --force, asserts the runner was called and no "cache hit" line
    hit stdout. Closes the gap that the plain cache-hit test left.

security-rebuild.yml
  - Pre-existing: `uses: ./.github/workflows/plan-and-build.yml` —
    but that file was deleted in PR #60, so any dispatch failed at
    parse-time. Replaced with a single actions/github-script@v7
    step that calls actions.createWorkflowDispatch against ci.yml
    with force=true. Preserves the `repository_dispatch: [security-
    rebuild]` public entry point.

watch-*.yml
  - Both workflows previously emitted peter-evans/repository-dispatch
    events (`php-release-detected`, `runner-image-updated`) that no
    workflow listened for — a silent no-op. Swap both steps to
    actions/github-script workflow_dispatch calls against ci.yml
    (force=false — a new upstream signal doesn't by itself
    invalidate existing bundles; catalog updates land separately).
  - watch-runner-images.yml also pulls the github token out of the
    run: block into an env var to quiet the workflow-injection
    pre-commit guard.

The force ergonomics split intentionally:
  - routine main push + nightly observer poll: no force; pipeline
    short-circuits unchanged cells via the existing spec-hash probe.
  - manual "gh workflow run ci.yml -f force=true" + security-rebuild
    dispatch: force=true rebuilds everything.

Verification: make check green; 15/15 Node tests; all 21 Go packages
pass. The new TestBuildPHP_Force_BypassesCacheHit fails as expected
if the --force conditional is reverted to the old unconditional
cache-probe, and passes with the new branch.
phramz added a commit that referenced this pull request Apr 24, 2026
Adds a new `smoke-action` job to ci.yml that invokes the public
action.yml + src/index.js wrapper the way a user's
`uses: buildrush/setup-php@v1` would — previously not covered
anywhere in CI.

Coverage gap this closes:
  - ci.yml::pipeline exercises phpup as a CLI inside bare-ubuntu
    containers (bundle build + fixture probe). It bypasses the
    composite-action entry point entirely.
  - A PR that broke action.yml (typo an input name, wrong output
    binding, etc.) or src/index.js (input parsing regression,
    misresolved cache path) would pass every existing job and still
    ship a broken action.

How the new job runs the PR's phpup, not a released one:
  src/index.js:runMain() checks existsSync($RUNNER_TOOL_CACHE/
  buildrush-bin/phpup) before hitting the network. We `go build`
  the PR's phpup binary directly into that cache path, then invoke
  `uses: ./` — the wrapper finds the binary, skips the release
  download, and the end-to-end path is: PR's action.yml → PR's
  src/index.js → PR's phpup. Zero changes to src/index.js were
  needed; the cache-hit path was the right hook.

Matrix is deliberately narrower than `pipeline`:
  - 2 OS (jammy, noble) × 2 arch (amd64, arm64) × 1 PHP (8.4) = 4 cells
  - Wrapper is OS-invariant and arch-variant; 4 cells catch the
    real regressions without multiplying the existing 20-cell
    `pipeline` cost.

Assertions per cell:
  - php -v succeeds (smoke)
  - extension_loaded("redis") + extension_loaded("intl")
    (extensions input was honored + extensions loaded at runtime)
  - ini_get("memory_limit") == "256M"
    (ini-values input was parsed + applied)

Wiring:
  - smoke-action needs: pipeline (fails fast if the CLI side broke)
  - publish needs: [pipeline, smoke-action] (a broken wrapper on
    main would otherwise publish a bundle the action can't use)

v2 drop-in compat (the coverage lost when compat-harness.yml was
deleted in PR #60) is deferred to a follow-up PR — this one keeps
the change surface small and easy to revert.
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.

1 participant