This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
121 lines (106 loc) · 5.4 KB
/
Copy pathpublished-dist-gate.yml
File metadata and controls
121 lines (106 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
name: Published Dist Gate
# The artifact-level half of objectui#4846: no published package's `dist/` may
# contain tooling material (`__tests__/`, `__mocks__/`, `__benchmarks__/`,
# `*.test.*`, `*.spec.*`, `*.bench.*`, `*.stories.*`). The gate itself, and the
# reason a cheap static criterion is NOT usable, are documented at length in
# scripts/check-published-dist-tooling.mjs.
#
# ── Why this is a scheduled workflow and NOT a pull-request job ──────────────
#
# The only criterion that does not produce false reds is a criterion over the
# BUILT ARTIFACT, so the gate has to build all 39 published packages. This
# repository deliberately has no per-PR full-repo build — `ci.yml`'s `Build &
# E2E` builds `@object-ui/console` alone, and its `Type Check` gets only the
# DEPENDENCY CLOSURE out of turbo's `dependsOn: ["^build"]`, which is why leaf
# packages such as `@object-ui/plugin-designer` (one of the four that shipped
# tooling material in objectui#4836) are never built there.
#
# The 2026-08-16 ruling on objectui#4846 (comment 5307574139) placed the gate on
# the RELEASE path — `pnpm changeset:publish` runs it before a single tarball
# reaches npm, so a red gate cancels the publish — and allowed this nightly run
# in addition, so a regression surfaces the night it lands instead of waiting
# for the next release. ⛔ Do not add `pull_request` here: that is precisely the
# per-PR full-repo build the ruling rejected.
# `scripts/__tests__/check-published-dist-tooling.test.ts` fails if the gate is
# ever wired into a workflow that carries a `pull_request` trigger.
#
# This workflow is therefore an ALARM, not a merge blocker: it cannot make
# anyone's pull request red, so a slow or flaky run costs a second look and
# nothing else. The blocking copy is the one on the publish path.
on:
workflow_dispatch:
# Nightly at 03:41 UTC. Off the top of the hour because GitHub's scheduled
# queue is most congested — and most delayed — at :00, the same reasoning
# `check-links.yml` records for its weekly sweep.
schedule:
- cron: '41 3 * * *'
# Changes to the gate itself get a real run, because the gate's own unit tests
# (which DO run per-PR, inside the ordinary vitest suite) exercise its
# verdicts over synthetic file lists and cannot exercise a real build. Scoped
# by `paths` to the gate and its wiring, so this stays off every other pull
# request.
push:
branches: [main]
paths:
- 'scripts/check-published-dist-tooling.mjs'
- '.github/workflows/published-dist-gate.yml'
concurrency:
group: published-dist-gate-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
published-dist:
name: Published Dist Tooling Scan
runs-on: ubuntu-latest
# A full build of 39 published packages plus one `npm pack --dry-run` per
# package. Generous, because a timeout here reads as a gate failure and this
# workflow blocks nobody.
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
submodules: true
- name: Enable Corepack and download the pinned pnpm
run: bash scripts/ci-setup-pnpm.sh
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '22.x'
cache: 'pnpm'
# objectui#12957: every @objectstack/* package resolves to the build of the
# commit `.objectstack-sha` pins, read from node_modules/.cache/objectstack, so
# it must be there before pnpm resolves anything. Restored by the pin and built
# only on a miss (scripts/objectstack-pin.mjs); the save is this job's last step.
- name: Restore the pinned @objectstack build
id: objectstack-pin
uses: actions/cache/restore@v6
with:
path: node_modules/.cache/objectstack
key: objectstack-pin-${{ runner.os }}-${{ hashFiles('.objectstack-sha', 'scripts/objectstack-pin.mjs') }}
- name: Build @objectstack at the pin (skips a restored build)
id: objectstack-build
run: node scripts/objectstack-pin.mjs build
- name: Install dependencies
run: pnpm install --frozen-lockfile
# No `pnpm build` step before this one, on purpose. The gate runs the
# build ITSELF and fails when it cannot, so that "there were no artifacts,
# therefore nothing was wrong" can never be this workflow's verdict — the
# vacuous shape objectui#4846 rejected by name. A published package that
# contributes no build output is reported as `no-build-output`, not
# skipped.
- name: Build every published package and scan its tarball
run: pnpm check:published-dist
# The pinned @objectstack build, saved only when this job built it (a cache
# miss) and whatever the verdict above was -- it does not depend on it.
# Bookkeeping: bounded and non-fatal (objectui#6577, objectui#7048). The bound
# is not yet derived from a measured save; re-derive it from this step's runs.
- name: Save the pinned @objectstack build
if: ${{ !cancelled() && steps.objectstack-build.outcome == 'success' && steps.objectstack-pin.outputs.cache-hit != 'true' }}
continue-on-error: true
timeout-minutes: 2
uses: actions/cache/save@v6
with:
path: node_modules/.cache/objectstack
key: objectstack-pin-${{ runner.os }}-${{ hashFiles('.objectstack-sha', 'scripts/objectstack-pin.mjs') }}