-
Notifications
You must be signed in to change notification settings - Fork 487
149 lines (127 loc) · 5.88 KB
/
Copy pathci.yml
File metadata and controls
149 lines (127 loc) · 5.88 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
# Cancel superseded runs on a PR (a new push obsoletes the in-flight one).
# Pushes to main are never canceled in-flight — though GitHub keeps only the
# newest PENDING run per group, so rapid pushes can skip an intermediate
# commit's run.
concurrency:
# Keyed by PR number (not head_ref): two different fork PRs can share a
# head branch name (most commonly `main`), and a name-keyed group would let
# one contributor's push cancel or queue behind another's unrelated run.
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
# Turbo Remote Cache: first-party PRs can read shared artifacts, but only
# trusted push runs can write them. Fork PRs use the local cache only.
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_CACHE: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && 'local:rw,remote:r' || github.event_name == 'pull_request' && 'local:rw' || 'local:rw,remote:rw' }}
jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 20
# Fold the Node version AND the OS into turbo's `test` task hash
# (turbo.json) so a cached result from one matrix leg is never replayed for
# another — turbo does not hash the platform by default, so without the OS
# dimension the Windows/macOS legs (same Node as an ubuntu leg) would hit
# the remote cache and replay ubuntu's test logs instead of running.
env:
MATRIX_NODE_VERSION: ${{ matrix.node-version }}
MATRIX_OS: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node-version: ["20.19.0", "22.18.0", "24", "25", "26"]
include:
- os: windows-latest
node-version: "22.18.0"
- os: blacksmith-6vcpu-macos-latest
node-version: "22.18.0"
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node-version }}
cache: pnpm
- run: pnpm install --frozen-lockfile --prefer-offline
- name: Run tests
if: ${{ matrix.os != 'windows-latest' && matrix.node-version != '20.19.0' }}
run: pnpm test
- name: Run Node 20 tests serially
if: ${{ matrix.node-version == '20.19.0' }}
run: pnpm test --concurrency=1
- name: Run Windows tests serially
if: ${{ matrix.os == 'windows-latest' }}
run: pnpm test --concurrency=1
# lint + typecheck run as dedicated jobs in code-quality.yml; don't pay for
# them again here.
- name: Check formatting
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node-version == '22.18.0' }}
shell: bash
run: |
format_output_file="$(mktemp)"
set +e
pnpm format:check 2>&1 | tee "$format_output_file"
format_status=${PIPESTATUS[0]}
set -e
if [ "$format_status" -ne 0 ]; then
while IFS= read -r format_line; do
format_file="${format_line%% (*}"
if [ "$format_file" = "$format_line" ] || [ ! -f "$format_file" ]; then
continue
fi
format_annotation_file="${format_file//'%'/'%25'}"
format_annotation_file="${format_annotation_file//$'\r'/'%0D'}"
format_annotation_file="${format_annotation_file//$'\n'/'%0A'}"
format_annotation_file="${format_annotation_file//':'/'%3A'}"
format_annotation_file="${format_annotation_file//','/'%2C'}"
echo "::error file=$format_annotation_file::File is not formatted. Run pnpm format."
done < "$format_output_file"
fi
rm -f "$format_output_file"
exit "$format_status"
- name: Smoke test built CLI
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node-version == '22.18.0' }}
run: |
cd packages/react-doctor
pnpm build
BUILT_VERSION=$(node bin/react-doctor.js --version)
echo "Built CLI reports version: $BUILT_VERSION"
if [ -z "$BUILT_VERSION" ] || [ "$BUILT_VERSION" = "0.0.0" ]; then
echo "Built CLI version is missing or 0.0.0; build env did not inject VERSION"
exit 1
fi
- name: Smoke test JSON report shape
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node-version == '22.18.0' }}
run: pnpm smoke:json-report
# Regression guard for #629: a published package's built output must not
# import a package that isn't in its `dependencies` (such phantom imports
# only resolve when a sibling dependency happens to supply them, and crash
# consumers on strict installs). Builds every package, then audits dist.
- name: Check published packages declare their runtime dependencies
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node-version == '22.18.0' }}
run: |
pnpm build
pnpm check:published-deps
- name: Smoke test packed CLI install
if: ${{ matrix.node-version == '22.18.0' && (matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest') }}
run: |
pnpm build
pnpm smoke:packed-cli-install
# Allocates a real pseudo-terminal (`pty.openpty()`) so the CLI sees an
# interactive TTY and renders the multiselect prompt, then asserts the
# process stays alive waiting for input instead of exiting by itself
# (regression guard for #576: unref'd stdin killed interactive prompts).
- name: Smoke test interactive TTY prompt
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node-version == '22.18.0' }}
run: pnpm smoke:tty-prompt