Skip to content

smoke-action should consume pipeline-built bundles for PR self-containment #83

Description

@phramz

Summary

The current `ci.yml` violates the stated PR self-containment design from `docs/superpowers/specs/2026-04-23-local-ci-unification-design.md` and `docs/superpowers/specs/2026-04-20-bundle-schema-and-rollout-design.md`. PRs that bump a bundle version cannot pass the `smoke-action` checks because `smoke-action` resolves bundles through the committed `bundles.lock` + GHCR, and PR runs do not publish bundles to GHCR or update `bundles.lock`.

Design intent vs. current behavior

Design (2026-04-23-local-ci-unification-design.md §"No cross-job GHCR roundtrip"):

A pipeline cell builds PHP-core → builds extensions → runs fixtures against the just-built artifacts in its own OCI layout. GHCR is touched only by the `publish` job after the full matrix passes on `main`.

Design (2026-04-20-bundle-schema-and-rollout-design.md §goals):

PR CI produces a self-consistent artifact set: every runtime assertion the PR introduces is validated against a bundle that the PR itself published.

Current implementation:

  • `pipeline` job builds bundles in-cell and tests fixtures against them in a local oci-layout (matches design).
  • `pipeline` Step `Upload oci-layout artifact` is gated on `if: github.ref == 'refs/heads/main'` (.github/workflows/ci.yml:117) — PR runs build the artifacts then discard them.
  • `smoke-action` builds phpup from PR HEAD, invokes `uses: ./` which runs `phpup install`. `phpup install` reads the committed `bundles.lock` + fetches from GHCR. No way to point it at a PR-local layout.
  • Result: PRs that change any bundle version (catalog version bump, configure-flag change, etc.) leave `smoke-action` red until merged. The redis 6.3.0 bump in Bump redis PECL from 6.2.0 to 6.3.0 for PHP 8.5 support #38 / PR feat(catalog): bump redis PECL 6.2.0 → 6.3.0 (restores PHP 8.5) #76 is the trigger that surfaced this.

Repro

Open any PR that bumps a PECL extension version in `catalog/extensions/*.yaml`. `smoke-action` cells will fail with:

```
resolve: extension for PHP 8.4 linux/x86_64/nts not found in lockfile
```

(see PR #76 — runs $(gh pr view 76 --json url -q .url) — for a concrete instance.)

Proposed fix

Infrastructure for the fix already exists. `phpup` honors `PHPUP_REGISTRY=oci-layout:` and `PHPUP_LOCKFILE=` env overrides. `internal/testsuite/runner.go:writeLayoutLockfileOverride` already synthesizes a lockfile JSON from an oci-layout — but it is unexported and inaccessible from a CI shell step.

Three small changes:

  1. ci.yml pipeline job: drop the `if: github.ref == 'refs/heads/main'` on the `Upload oci-layout artifact` step. PR runs upload per-cell layouts (cost: artifact storage per PR run, retention 7d already set).
  2. New phpup subcommand: `phpup internal lockfile-from-layout --layout oci-layout: --out ` — a thin wrapper that calls the existing logic in `internal/testsuite/runner.go:writeLayoutLockfileOverride` (the function may need to be moved or have a sibling exported).
  3. ci.yml smoke-action job: before `uses: ./`, download the matching `oci-layout---` artifact, run the new subcommand to synthesize a lockfile override, and set `PHPUP_REGISTRY=oci-layout:...` and `PHPUP_LOCKFILE=...` env vars on the action invocation.

After this, `smoke-action` validates the public action surface against the PR's own bundles, end-to-end, with no GHCR roundtrip. Matches the design.

Out of scope (deliberate)

  • Promoting PR-local bundles to GHCR (the `publish` job remains main-only — that's intended).
  • Changing the smoke-action matrix shape.
  • Touching `pipeline`'s test execution (already self-contained).

Why a separate slice

Discovered while working on #38 / PR #76 (redis PECL bump). The fix is a CI workflow change cross-cutting all bump PRs, not specific to redis — better landed as its own slice with its own review and isolated risk surface.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions