Skip to content

v4.6.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 16:34
0a56ecc

Added

  • Yarn Berry support in the cold path. styleproof-ci pinned yarn 1 for any
    yarn.lock; on a Yarn 2+ repo that either refuses (the packageManager
    field) or cannot parse the lockfile, so every base-miss run failed. A
    .yarnrc.yml or a packageManager: "yarn@2+" pin now routes installs
    through corepack (corepack yarn install --immutable), which provisions the
    repo's own pinned release.
  • styleproof.config.json warns on unknown keys. A typo'd dirtyallow or
    cache_branch was silently dropped — exactly the "config the user wrote must
    never be silently dropped" failure the validator forbids. Unknown top-level
    and affected keys now produce a loud stderr warning listing the known keys
    (a warning, not an error, so a newer release's key doesn't brick older CLIs
    during version skew). styleproof-map --help also now documents that
    dirtyAllow accumulates across config + env + flags instead of being
    overridden.

Fixed

  • styleproof-ci reads project config from the HEAD checkout, and each side
    resolves its own spec.
    Config was loaded before the flow pinned the
    consumer to --head — in the generated workflow that pre-checkout tree is
    the PR merge commit — so a head that moved the spec via
    styleproof.config.json ran with the stale path and failed exit 2 with the
    cause invisible. Config now loads after the head checkout, and when --spec
    is not explicit, base-side probes and captures resolve the spec from the
    BASE checkout's own config while head-side ones use the head's — a
    config-only spec move now works end to end.

  • styleproof-ci failure taxonomy tightened. A required upload's
    map-store/network fault exited 2 — the code reserved for usage errors — so
    exit-code triage retried the wrong thing; store faults now exit 5 (the same
    retryable class as restore faults) while consumer-state preconditions (dirty
    tree, missing manifest) keep 2, since retrying those can never succeed. A
    failed styleproof-map --restore spawn (ENOENT) now prints the underlying
    error instead of "fault (exit null), re-run the job". Worktree residue from
    hard kills is reclaimed: every session start runs git worktree prune, and
    SIGINT/SIGTERM now dispose live worktrees before exiting.

  • styleproof-affected --root works from a monorepo. git diff prints
    repo-root-relative paths, which the CLI resolved against --root and matched
    against a package-relative graph — every changed file was unplaceable, so
    every monorepo invocation degraded to 'all'. The --root prefix is now
    stripped when resolving git paths into the graph (files outside the package
    still fail closed), and styleproof.config.json, --graph, and
    --surfaces now load relative to --root instead of the invoking cwd.

  • REPORT_PUBLICATION_FAILED now names its actual failure domain. The
    Action's terminal trust step treated any non-success publish outcome —
    including a merely skipped step — as a publication failure, and conversely a
    failed PR-comment or commit-status delivery after a successful publish
    reported the diff verdict as if the reviewer had seen it. The trust state now
    distinguishes publish failure (→ REPORT_PUBLICATION_FAILED), publish
    skipped/cancelled (→ the diff verdict, CERTIFICATION_FAILED when absent),
    and delivery failure after a successful publish (→
    REPORT_PUBLICATION_FAILED). The verdict's DEGRADED_BASELINE check also
    accepts base-capture-failed case-insensitively, matching the downstream
    GitHub-expression gate.

  • --tolerate-surface-failures no longer promotes unledgered failures. A
    nonzero Playwright exit with maps on disk but NOTHING in the surface-failure
    ledger (a self-check, nondeterminism, or harness failure) used to publish as
    a "partial baseline"; promotion now requires at least one ledgered surface
    failure, and anything else keeps the failing exit. Ledger filenames also
    gained a content digest so two surface keys that sanitize to the same
    filename can no longer clobber each other's entries.

  • styleproof-ci discards base-capture debris instead of keeping it as a
    baseline.
    With ledgered failures now exiting 0, a nonzero base capture
    exit means an UNtolerated failure — any maps left on disk have no
    publishable manifest, and keeping them reported real regressions as
    approvable "new surfaces". The base dir is cleared and the run proceeds as a
    bare baseline with base-capture-failed=true (DEGRADED_BASELINE).

  • styleproof-init --check/--upgrade now treat both generated workflows as
    marker-owned.
    The CI and approval workflow templates carry an ownership
    marker (like the pre-push hook already did), so a consumer-authored
    workflow at the same path reports unmanaged and is never overwritten by
    --upgrade, instead of being flagged stale and clobbered.

  • The generated pre-push hook no longer bakes the default spec path. With
    the default spec, the hook execs bare styleproof-prepush, which resolves
    the spec at run time (flag > env > styleproof.config.json > built-in) — so
    moving the spec via config alone can't strand a stale baked --spec. A
    non-default --dir is still baked explicitly.

  • Cold-base captures resolve Playwright from the base worktree's own install.
    styleproof-ci built PATH once from the consumer head's node_modules/.bin,
    so the base capture ran the head's Playwright CLI against the worktree's
    @playwright/test library — a version-mixing failure ("did not expect test()
    to be called here") on exactly the PRs that bump rendering dependencies,
    silently degrading them to a bare baseline. Base-side spawns now prepend the
    cold-base worktree's own node_modules/.bin; head-side spawns keep the
    consumer's.

  • Symbolic --spec-ref values resolve in the consumer checkout. Inside the
    detached base worktree HEAD is --base (so --spec-ref HEAD silently
    overlaid the base's own spec — a no-op defeating the flag) and
    FETCH_HEAD/MERGE_HEAD are per-worktree pseudo-refs that don't resolve
    there at all. The ref is now resolved to a commit SHA in the consumer
    checkout before any worktree is entered, and an unresolvable ref fails loudly
    up front even when the base restore would have hit.

  • A derived-only change now renders as reviewable evidence instead of failing
    closed with none.
    When a surface's only differences are size/position
    longhands (width, inline-size, transform-origin, offsets…) — typically
    content-length drift widening a text span, or a pure sizing rule change — the
    noise-cleaning strip removed every finding, so 4.5.3's consistency guard
    correctly refused to claim "identical" but classified the run
    CERTIFICATION_FAILED with nothing for the reviewer to look at. Cleaning now
    keeps a surface's findings when stripping would silence a gating change
    (cleanFindingsForDisplay), titles them "size/position only, no styling
    property changed (often content-length drift…)", and the truth contract counts
    them reviewable — so the verdict is VISUAL_APPROVAL_REQUIRED with rendered
    evidence
    . The raw-only CERTIFICATION_FAILED backstop remains for shapes
    that truly cannot render (state-strip-only deltas). Reflow casualties next to
    a real driver fold exactly as before; exit codes are unchanged.

  • Cached-map diffs now see the baseline's tolerated-failure ledger. The
    no-arg/<baseRef> forms read the base manifest AFTER cached-restore cleanup
    had deleted the directory, so surfaceCaptureFailures always read empty and a
    PARTIAL_BASELINE run silently degraded into approvable greenfield "new
    surfaces" (exit 3). The manifest is now read while the restored dirs exist,
    matching every other ledger read.

  • A surface captured only on base renders as REMOVED surface 🗑️, not "new
    surface 🆕".
    The report/summary previously framed a disappearing surface as
    an addition with approve-forward guidance; removals now get their own heading,
    summary line ("approving accepts the disappearance"), and isRemoved in
    report.json.

  • A fresh capture clears any stale surface-capture-failures ledger in the
    reused output dir (same hazard class as the browser-build sidecar): a failure
    recorded by a prior run no longer stamps a phantom "partial baseline" into a
    healthy recapture's manifest.

  • "gateInventoryRemovals": false now reaches the verdict. The opt-out
    previously only skipped the job-fail step while the classification and commit
    status stayed an unclearable red; removals now downgrade to ordinary
    approval-required changes when opted out.

  • styleproof-diff and styleproof-report read styleproof.config.json
    (spec, cacheBranch, remote) like every other CLI — without it, a repo
    whose config moved the spec or store branch computed a different compatibility
    key on the compare side than the capture side, and the no-arg diff (including
    the pre-push advisory diff) always missed.