Polish nub init and enforce the release-age floor #653
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Lockfile round-trip | |
| # Bidirectional cross-tool lockfile round-trip gates. Two harnesses, both | |
| # shelling out to REAL pinned package managers as the honest judge: | |
| # | |
| # tests/conformance/run.sh — drop-in round-trip. Direction A: a real PM | |
| # writes its lockfile, nub `--frozen-lockfile` installs from it. Direction | |
| # B: nub writes the lockfile, the real PM frozen-installs it with zero | |
| # churn (`cmp`). The real PM judges BOTH directions. | |
| # tests/conversion/run.sh — cross-format migration: a source PM writes its | |
| # lockfile, `nub pm use <target>` converts it, the target PM frozen-accepts. | |
| # tests/mutation/run-mutations.sh — the WRITE-PATH differential: a real PM | |
| # installs, nub MUTATES (`nub add`/`remove`/`update`), the real PM frozen- | |
| # accepts nub's mutated lockfile AND the mutated graph is semantically equal | |
| # to what the real PM produces for the same mutation. NIGHTLY only (heavier: | |
| # two installs + a mutation per leg). | |
| # | |
| # Both harnesses invoke pnpm/npm/bun/yarn by name off PATH (NOT npx-pinned like | |
| # tests/aube-conformance/run.sh), so this workflow pins each one deterministically | |
| # on PATH before running — see the "Pin package managers" step. Keep these pins | |
| # in sync with the tool/version matrices documented in each harness README and | |
| # with BUN_PIN/PNPM_PIN/NPM_PIN defaults in the run.sh scripts. | |
| # | |
| # Two cadences: | |
| # per-PR — the conformance harness on a TIGHT, fast fixture set, so it doesn't | |
| # heavily gate every push. Skips yarn (slowest leg) to stay quick. | |
| # nightly — the FULL conformance matrix + the full conversion matrix + the | |
| # mutation differential, all PMs. The mutation leg is nightly-only | |
| # (no per-PR gate) because it is heavier than a static round-trip. | |
| # | |
| # Real registry installs run, so these need network. Known-red scenarios live in | |
| # each harness's expected-failures.txt and must shrink (a stale entry fails the | |
| # run). | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "tests/conformance/**" | |
| - "tests/conversion/**" | |
| - "tests/mutation/**" | |
| - "crates/**" | |
| - "vendor/aube/**" | |
| - "Cargo.lock" | |
| - ".github/workflows/lockfile-roundtrip.yml" | |
| push: | |
| branches: [main] | |
| paths: | |
| - "tests/conformance/**" | |
| - "tests/conversion/**" | |
| - "tests/mutation/**" | |
| - ".github/workflows/lockfile-roundtrip.yml" | |
| schedule: | |
| # Nightly full matrix at 07:00 UTC. | |
| - cron: "0 7 * * *" | |
| workflow_dispatch: {} | |
| permissions: {} | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| # Pinned package-manager versions. Keep in sync with the harness READMEs and | |
| # the *_PIN defaults in tests/conversion/run.sh. | |
| NPM_PIN: "11.13.0" | |
| PNPM_PIN: "10.15.1" | |
| BUN_PIN: "1.3.14" | |
| YARN_PIN: "1.22.22" | |
| jobs: | |
| # ── Per-PR: tight, fast drop-in round-trip ──────────────────────────────── | |
| conformance-pr: | |
| name: drop-in round-trip, tight set (ubuntu) | |
| # Skip the scheduled run — the nightly job covers the full set. | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable # zizmor: ignore[impostor-commit,ref-version-mismatch] dtolnay force-pushes its version tags, so pinned SHAs go unreachable; commit verified genuine upstream | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 | |
| with: | |
| node-version: "24" | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version: ${{ env.BUN_PIN }} | |
| - name: Pin package managers on PATH | |
| run: | # zizmor: ignore[adhoc-packages] versions pinned via workflow-level *_PIN env vars | |
| npm install -g "npm@${NPM_PIN}" "pnpm@${PNPM_PIN}" | |
| echo "npm: $(npm --version)" | |
| echo "pnpm: $(pnpm --version)" | |
| echo "bun: $(bun --version)" | |
| - name: Build nub | |
| run: cargo build -p nub-cli | |
| - name: Drop-in round-trip (tight fixture set, no yarn) | |
| # The tight set: table-stakes (simple, scoped) + the feature fixtures | |
| # that exercise the bug-prone diverging fields. yarn is skipped here to | |
| # keep the PR gate fast; the nightly job runs it. | |
| env: | |
| SKIP_YARN: "1" | |
| run: tests/conformance/run.sh target/debug/nub simple scoped peers overrides-ref overrides-nested patched-deps catalog workspace workspace-dedup empty-root-importer git-dep platform-optional dist-tag-spec range-forms alias-scoped has-install-script injected-deps | |
| # ── Nightly: full conformance matrix + full conversion matrix ───────────── | |
| conformance-nightly: | |
| name: drop-in round-trip, full matrix (ubuntu) | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable # zizmor: ignore[impostor-commit,ref-version-mismatch] dtolnay force-pushes its version tags, so pinned SHAs go unreachable; commit verified genuine upstream | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 | |
| with: | |
| node-version: "24" | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version: ${{ env.BUN_PIN }} | |
| - name: Pin package managers on PATH | |
| run: | # zizmor: ignore[adhoc-packages] versions pinned via workflow-level *_PIN env vars | |
| npm install -g "npm@${NPM_PIN}" "pnpm@${PNPM_PIN}" "yarn@${YARN_PIN}" | |
| echo "npm: $(npm --version)" | |
| echo "pnpm: $(pnpm --version)" | |
| echo "yarn: $(yarn --version)" | |
| echo "bun: $(bun --version)" | |
| - name: Build nub | |
| run: cargo build -p nub-cli | |
| - name: Drop-in round-trip (full fixture matrix, all PMs) | |
| run: tests/conformance/run.sh target/debug/nub | |
| conversion-nightly: | |
| name: cross-format conversion, full matrix (ubuntu) | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable # zizmor: ignore[impostor-commit,ref-version-mismatch] dtolnay force-pushes its version tags, so pinned SHAs go unreachable; commit verified genuine upstream | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 | |
| with: | |
| node-version: "24" | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version: ${{ env.BUN_PIN }} | |
| - name: Pin package managers on PATH | |
| run: | # zizmor: ignore[adhoc-packages] versions pinned via workflow-level *_PIN env vars | |
| npm install -g "npm@${NPM_PIN}" "pnpm@${PNPM_PIN}" "yarn@${YARN_PIN}" | |
| echo "npm: $(npm --version)" | |
| echo "pnpm: $(pnpm --version)" | |
| echo "yarn: $(yarn --version)" | |
| echo "bun: $(bun --version)" | |
| - name: Build nub | |
| run: cargo build -p nub-cli | |
| - name: Cross-format conversion matrix | |
| # run.sh reads NPM_PIN/PNPM_PIN/BUN_PIN (inherited from the workflow-level | |
| # env above) to pin the packageManager declaration nub writes — aligned | |
| # with the PATH-installed versions. | |
| run: tests/conversion/run.sh target/debug/nub | |
| # ── Nightly: lockfile MUTATION differential (write-path) ────────────────── | |
| # Heavier than a static round-trip (two installs + a mutation per leg), so it | |
| # is nightly/dispatch only — no per-PR gate. yarn is read-only in nub (no | |
| # write-path mutation), so this matrix is npm/pnpm/bun and skips the yarn pin. | |
| mutation-nightly: | |
| name: lockfile mutation differential, full matrix (ubuntu) | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable # zizmor: ignore[impostor-commit,ref-version-mismatch] dtolnay force-pushes its version tags, so pinned SHAs go unreachable; commit verified genuine upstream | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 | |
| with: | |
| node-version: "24" | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version: ${{ env.BUN_PIN }} | |
| - name: Pin package managers on PATH | |
| run: | # zizmor: ignore[adhoc-packages] versions pinned via workflow-level *_PIN env vars | |
| npm install -g "npm@${NPM_PIN}" "pnpm@${PNPM_PIN}" | |
| echo "npm: $(npm --version)" | |
| echo "pnpm: $(pnpm --version)" | |
| echo "bun: $(bun --version)" | |
| - name: Build nub | |
| run: cargo build -p nub-cli | |
| - name: Lockfile mutation differential (add / remove / update) | |
| run: tests/mutation/run-mutations.sh target/debug/nub |