-
Notifications
You must be signed in to change notification settings - Fork 0
176 lines (168 loc) · 7.52 KB
/
Copy pathci.yml
File metadata and controls
176 lines (168 loc) · 7.52 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# CI — runs on every PR and push to the default branch.
#
# Fully hermetic: the build + E2E suites use the vendored docs-example fixture
# (tests/fixtures/docs-example.dist.tar.gz) via apps.json `prebuilt` entries, so
# no GITHUB_TOKEN, network, or sibling repo is required.
#
# Jobs:
# typecheck — astro check (TypeScript / Astro type errors)
# build — headless build from the vendored fixture; uploads dist/
# e2e — Playwright: embedded web-fragment harness + standalone layer
# audit — npm dependency vulnerability gate
name: CI
on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
# Least privilege: jobs only read the repo. Override per-job if more is needed.
permissions:
contents: read
jobs:
# ── 1. TypeScript / Astro type-check ───────────────────────────────────────
# Non-blocking: `astro check` is memory-hungry and can OOM on standard runners
# (tracked separately). The `build` job below is the hard compile gate — a real
# type/template error fails `astro build`. This job surfaces strict diagnostics
# without wedging CI on an OOM.
typecheck:
name: Type-check (non-blocking)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
cache: npm
- run: npm ci
- name: Astro type-check
run: npx astro check
env:
NODE_OPTIONS: --max-old-space-size=6144
# ── 2. Build (headless, hermetic) ──────────────────────────────────────────
build:
name: Build (headless)
runs-on: ubuntu-latest
needs: typecheck
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
cache: npm
- run: npm ci
# Builds from the committed apps.json (vendored fixture) — no token/network.
- name: Build (headless)
run: npm run build:headless
- name: Upload dist artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: dist
path: dist/
retention-days: 7
# ── 3. Playwright E2E ──────────────────────────────────────────────────────
#
# Two layers, both hermetic (each webServer rebuilds from the fixture):
# • embedded (playwright.config.js) — full web-fragment harness: host
# gateway proxies/embeds the fragment, shadow-DOM isolation, SPA routing,
# cross-app nav, asset 404s, history limitation.
# • standalone (playwright.config.ci.js) — fragment server only: HTTP header
# safety, headless contract, CSS-link stability (#297), asset routing.
e2e:
name: E2E (Playwright)
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
cache: npm
- run: npm ci
- name: Install Playwright browser
run: npx playwright install --with-deps chromium
- name: Embedded web-fragment tests
run: npm test
- name: Standalone fragment tests
run: npx playwright test --config=playwright.config.ci.js
- name: Upload Playwright report
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: playwright-report
path: playwright-report/
retention-days: 7
# ── 4. publish-single-page-docs action self-test ───────────────────────────
#
# actions/publish-single-page-docs/ ships its own pinned dependency tree, so it is not
# covered by the root `npm ci` or by the Playwright suites (which stay hermetic
# and must not depend on the action's node_modules). This job renders a sample
# markdown file through the real pipeline and pins the validation messages —
# they are the action's user interface for onboarding repos.
publish-single-page-docs:
name: publish-single-page-docs action self-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# Matches the node-version the composite action pins in action.yml.
node-version: '20'
cache: npm
cache-dependency-path: actions/publish-single-page-docs/package-lock.json
- run: npm ci
working-directory: actions/publish-single-page-docs
# Action manifests are only parsed by *consuming* repositories' runners, so
# a syntax error here ships green and breaks every downstream workflow at
# "Set up job" (#39). Parse them with the same pinned `yaml` package the
# action already depends on, so this needs no extra tooling.
- name: Validate action manifests
working-directory: actions/publish-single-page-docs
run: |
node -e '
const fs = require("node:fs");
const path = require("node:path");
const YAML = require("yaml");
const root = path.resolve("../..");
const files = [];
(function walk(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (entry.name === "node_modules") continue;
const full = path.join(dir, entry.name);
if (entry.isDirectory()) walk(full);
else if (/\.ya?ml$/.test(entry.name)) files.push(full);
}
})(path.join(root, "actions"));
if (files.length === 0) {
console.error("no action manifests found under actions/ — check this glob");
process.exit(1);
}
let failed = 0;
for (const file of files) {
const name = path.relative(root, file);
try {
YAML.parse(fs.readFileSync(file, "utf8"));
console.log("ok " + name);
} catch (error) {
failed += 1;
console.error("FAILED " + name + ": " + error.message);
}
}
process.exit(failed === 0 ? 0 : 1);
'
- run: npm run selftest
working-directory: actions/publish-single-page-docs
# ── 5. Dependency audit ────────────────────────────────────────────────────
audit:
name: npm audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
cache: npm
- run: npm ci
# Fail only on production-dependency vulnerabilities (high or above).
- name: Audit production dependencies
run: npm audit --omit=dev --audit-level=high