Skip to content

Commit a38a662

Browse files
authored
Merge pull request #2098 from Hack23/copilot/prepare-qualify-improvements
Implementing quality improvements for next release
2 parents 3eb34df + 9446ebf commit a38a662

20 files changed

Lines changed: 139 additions & 271 deletions

.github/workflows/README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ⚙️ `.github/workflows/` — GitHub Actions Catalog
22

3-
This directory holds **43 workflow files** (21 standard `.yml` + 11 agentic Markdown sources + 11 compiled `.lock.yml` siblings) that power Riksdagsmonitor's CI/CD, security, data pipeline, agentic news generation, and monitoring.
3+
This directory holds **44 workflow files** (22 standard `.yml` + 11 agentic Markdown sources + 11 compiled `.lock.yml` siblings) that power Riksdagsmonitor's CI/CD, security, data pipeline, agentic news generation, and monitoring.
44

55
> **Canonical long-form workflow reference:** [`WORKFLOWS.md`](../../WORKFLOWS.md) at the repository root — version matrices, Mermaid pipeline diagrams, ISMS control mapping, troubleshooting, and KPIs.
66
> **Agentic workflow contract (imports, analysis gate, 9/14 artifacts):** [`.github/prompts/README.md`](../prompts/README.md).
@@ -11,10 +11,10 @@ This directory holds **43 workflow files** (21 standard `.yml` + 11 agentic Mark
1111

1212
| File kind | Count | Notes |
1313
|-----------|------:|-------|
14-
| Standard GitHub Actions (`*.yml`, not `*.lock.yml`) | **21** | Run natively on the GitHub Actions runner |
15-
| Agentic workflow **sources** (`news-*.md`) | **12** | Authored in Markdown with gh-aw frontmatter + prompt imports |
16-
| Agentic workflow **compiled lock files** (`news-*.lock.yml`) | **12** | Auto-generated by `compile-agentic-workflows.yml` — these are what actually execute |
17-
| **Total** | **45** | Verify with `ls .github/workflows/ | wc -l` |
14+
| Standard GitHub Actions (`*.yml`, not `*.lock.yml`) | **22** | Run natively on the GitHub Actions runner |
15+
| Agentic workflow **sources** (`news-*.md`) | **11** | Authored in Markdown with gh-aw frontmatter + prompt imports |
16+
| Agentic workflow **compiled lock files** (`news-*.lock.yml`) | **11** | Auto-generated by `compile-agentic-workflows.yml` — these are what actually execute |
17+
| **Total** | **44** | Verify with `ls .github/workflows/ | wc -l` (excludes this `README.md`) |
1818

1919
**Only the compiled `.lock.yml` files run.** The `.md` sources are the source of truth and are reviewed in PRs; lock files are regenerated via the `gh aw compile` CLI.
2020

@@ -30,13 +30,14 @@ This directory holds **43 workflow files** (21 standard `.yml` + 11 agentic Mark
3030
| [`setup-labels.yml`](setup-labels.yml) | Manual dispatch | Repository label management (`.github/labeler.yml` source) |
3131
| [`labeler.yml`](labeler.yml) | Pull requests | Auto-label PRs from `.github/labeler.yml` patterns |
3232

33-
## 🧪 Testing & Validation (7)
33+
## 🧪 Testing & Validation (8)
3434

3535
| File | Trigger | Purpose |
3636
|------|---------|---------|
3737
| [`javascript-testing.yml`](javascript-testing.yml) | Push/PR on TS/JS/HTML/config | TypeScript type-check + Vitest (2 890 tests) + Vite build |
3838
| [`jsdoc-validation.yml`](jsdoc-validation.yml) | Manual dispatch | TypeDoc generation + coverage report |
3939
| [`quality-checks.yml`](quality-checks.yml) | Push/PR to `main` | ESLint + HTMLHint + linkinator (parallel jobs) |
40+
| [`knip.yml`](knip.yml) | Push/PR to `main` | Knip dead-code detector — blocks on unused files / dependencies / binaries / duplicate exports; reports unused exports & types informationally |
4041
| [`translation-validation.yml`](translation-validation.yml) | Push/PR on HTML | 14-language completeness + RTL + hreflang |
4142
| [`test-dashboard.yml`](test-dashboard.yml) | Push/PR on dashboards | Cypress E2E for dashboard pages |
4243
| [`test-homepage.yml`](test-homepage.yml) | Push/PR on homepage | Cypress E2E for the 14 `index*.html` homepages |
@@ -149,7 +150,7 @@ flowchart LR
149150
C9[Weekly → codeql + scorecards + lighthouse-ci]
150151
end
151152
subgraph "🔀 Event"
152-
E1[push/PR → quality-checks + javascript-testing + translation-validation + codeql + test-*]
153+
E1[push/PR → quality-checks + knip + javascript-testing + translation-validation + codeql + test-*]
153154
E2[Tag v*.*.* → release]
154155
E3[push main → deploy-s3]
155156
E4[PR → dependency-review + labeler]

.github/workflows/javascript-testing.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ jobs:
120120
run: npm ci
121121

122122
- name: Build with Vite
123+
# Vite/Rollup loads ~4200+ news/*.html entries (auto-discovered in
124+
# vite.config.js → discoverNewsArticles()), and at the
125+
# `rendering chunks` phase the default ~4 GB Node heap is no longer
126+
# enough — the build OOMs with
127+
# `FATAL ERROR: Ineffective mark-compacts near heap limit
128+
# Allocation failed - JavaScript heap out of memory` → exit 134.
129+
# GitHub-hosted ubuntu-latest runners ship with 16 GB RAM, so
130+
# raising the V8 old-space limit to 8 GB gives the build headroom
131+
# (matches deploy-s3.yml).
132+
env:
133+
NODE_OPTIONS: --max-old-space-size=8192
123134
run: npm run build
124135

125136
- name: Check build output

.github/workflows/knip.yml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Knip Dead Code Check
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
knip:
14+
name: Run Knip
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Harden Runner
18+
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
19+
with:
20+
egress-policy: block
21+
allowed-endpoints: >
22+
api.github.com:443
23+
codeload.github.com:443
24+
github.com:443
25+
nodejs.org:443
26+
objects.githubusercontent.com:443
27+
registry.npmjs.org:443
28+
29+
- name: Checkout repository
30+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31+
32+
- name: Setup Node.js
33+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
34+
with:
35+
node-version: '25'
36+
cache: 'npm'
37+
38+
- name: Install dependencies
39+
run: npm ci
40+
41+
- name: Run Knip (blocking — files, dependencies, duplicates)
42+
# Blocks the workflow on actionable findings: unused files, unused/unlisted/
43+
# unresolved dependencies, unused binaries, and duplicate exports. Unused
44+
# exports/types are intentionally informational only (see next step) — most
45+
# are barrel re-exports that form the public API of internal libraries.
46+
run: |
47+
echo "🔍 Running Knip dead-code detector (blocking subset)..."
48+
echo ""
49+
if npx knip --no-progress --include files,dependencies,unlisted,binaries,unresolved,duplicates > knip-blocking.txt 2>&1; then
50+
echo "✅ No actionable dead-code findings."
51+
cat knip-blocking.txt
52+
else
53+
echo "❌ Knip found actionable issues:"
54+
cat knip-blocking.txt
55+
echo ""
56+
echo "Triage options for each finding:"
57+
echo " a) Used but not detected → update knip.json (entry/ignoreDependencies)."
58+
echo " b) Should be used but isn't → wire it up in the consumer."
59+
echo " c) Truly unused → delete the file/dep/binary."
60+
exit 1
61+
fi
62+
63+
- name: Run Knip (informational — exports & types)
64+
# Non-blocking: surfaces unused exports/types so reviewers can spot drift
65+
# without forcing every barrel re-export to be hand-pruned. Failures here
66+
# do NOT fail the workflow.
67+
if: always()
68+
continue-on-error: true
69+
run: |
70+
echo "🔎 Running Knip (informational — unused exports / types)..."
71+
echo ""
72+
npx knip --no-progress --include exports,nsExports,types,nsTypes,enumMembers > knip-informational.txt 2>&1 || true
73+
cat knip-informational.txt
74+
75+
- name: Upload Knip Report
76+
if: always()
77+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
78+
with:
79+
name: knip-report
80+
path: |
81+
knip-blocking.txt
82+
knip-informational.txt
83+
retention-days: 30

WORKFLOWS.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
[![TypeScript & JavaScript Testing](https://github.com/Hack23/riksdagsmonitor/actions/workflows/javascript-testing.yml/badge.svg)](https://github.com/Hack23/riksdagsmonitor/actions/workflows/javascript-testing.yml)
4949
[![TypeDoc Validation](https://github.com/Hack23/riksdagsmonitor/actions/workflows/jsdoc-validation.yml/badge.svg)](https://github.com/Hack23/riksdagsmonitor/actions/workflows/jsdoc-validation.yml)
5050
[![Translation Validation](https://github.com/Hack23/riksdagsmonitor/actions/workflows/translation-validation.yml/badge.svg)](https://github.com/Hack23/riksdagsmonitor/actions/workflows/translation-validation.yml)
51+
[![Knip Dead Code Check](https://github.com/Hack23/riksdagsmonitor/actions/workflows/knip.yml/badge.svg)](https://github.com/Hack23/riksdagsmonitor/actions/workflows/knip.yml)
5152

5253
### Documentation & Release
5354

@@ -293,11 +294,12 @@ graph TB
293294
### Core CI/CD Workflows
294295

295296
1. **✅ Quality Checks** (`.github/workflows/quality-checks.yml`) — ESLint linting, HTML validation, link checking
296-
2. **🧪 TypeScript & JavaScript Testing** (`.github/workflows/javascript-testing.yml`) — Vitest unit tests, TypeScript type-checking, Cypress E2E
297-
3. **📖 TypeDoc Validation** (`.github/workflows/jsdoc-validation.yml`) — API documentation generation and coverage
298-
4. **🌐 Translation Validation** (`.github/workflows/translation-validation.yml`) — 14-language validation with RTL and hreflang
299-
5. **🚀 Release with Attestations** (`.github/workflows/release.yml`) — SLSA provenance, SBOM, dual deployment
300-
6. **☁️ Deploy to S3** (`.github/workflows/deploy-s3.yml`) — AWS S3/CloudFront deployment
297+
2. **🧹 Knip Dead Code Check** (`.github/workflows/knip.yml`) — Detects unused files, dependencies, binaries, and duplicate exports on every PR (informational pass also reports unused exports/types)
298+
3. **🧪 TypeScript & JavaScript Testing** (`.github/workflows/javascript-testing.yml`) — Vitest unit tests, TypeScript type-checking, Cypress E2E
299+
4. **📖 TypeDoc Validation** (`.github/workflows/jsdoc-validation.yml`) — API documentation generation and coverage
300+
5. **🌐 Translation Validation** (`.github/workflows/translation-validation.yml`) — 14-language validation with RTL and hreflang
301+
6. **🚀 Release with Attestations** (`.github/workflows/release.yml`) — SLSA provenance, SBOM, dual deployment
302+
7. **☁️ Deploy to S3** (`.github/workflows/deploy-s3.yml`) — AWS S3/CloudFront deployment
301303

302304
### Security Scanning Workflows
303305

@@ -425,6 +427,7 @@ flowchart TB
425427
| **ESLint** | Zero errors | quality-checks.yml | Required ✅ |
426428
| **HTMLHint Validation** | Zero errors | quality-checks.yml | Required ✅ |
427429
| **Link Integrity** | Zero broken internal links | quality-checks.yml | Required ✅ |
430+
| **Knip Dead Code (files/deps/dups)** | Zero unused files, deps, binaries, or duplicate exports | knip.yml | Required ✅ |
428431
| **Unit Test Pass Rate** | 100% (2890 tests) | javascript-testing.yml | Required ✅ |
429432
| **CodeQL SAST** | No critical/high | codeql.yml | Required ✅ |
430433
| **Dependency Vulnerabilities** | No critical/high | dependency-review.yml | Required ✅ |
@@ -1095,17 +1098,18 @@ flowchart LR
10951098
| 1.4 | 🏷️ Setup Labels | `setup-labels.yml` | Manual dispatch | A.5.37, PR.IP-1 |
10961099
| 1.5 | 🏷️ PR Labeler | `labeler.yml` | Pull requests | A.5.37, PR.IP-1 |
10971100

1098-
### 🧪 Testing & Validation (7 workflows)
1101+
### 🧪 Testing & Validation (8 workflows)
10991102

11001103
| # | Workflow | File | Trigger | Coverage |
11011104
| --- | --- | --- | --- | --- |
11021105
| 2.1 | 🧪 TypeScript & JS Testing | `javascript-testing.yml` | Push/PR (TS/JS/HTML) | TSC + Vitest + Cypress |
11031106
| 2.2 | 📖 TypeDoc Validation | `jsdoc-validation.yml` | Manual dispatch | TypeDoc generation + coverage |
11041107
| 2.3 | ✅ Quality Checks | `quality-checks.yml` | Push/PR to main | ESLint + HTMLHint + linkinator |
1105-
| 2.4 | 🌐 Translation Validation | `translation-validation.yml` | Push/PR (HTML) | 14-language + RTL + hreflang |
1106-
| 2.5 | 🖥️ Test Dashboard | `test-dashboard.yml` | Push/PR (src/browser) | Dashboard Cypress E2E |
1107-
| 2.6 | 🏠 Test Homepage | `test-homepage.yml` | Push/PR (src/browser) | Homepage Cypress E2E |
1108-
| 2.7 | 📰 Test News | `test-news.yml` | Push/PR (news) | News pages Cypress E2E |
1108+
| 2.4 | 🧹 Knip Dead Code Check | `knip.yml` | Push/PR to main | Unused files, deps, binaries, duplicate exports (blocking); unused exports/types (informational) |
1109+
| 2.5 | 🌐 Translation Validation | `translation-validation.yml` | Push/PR (HTML) | 14-language + RTL + hreflang |
1110+
| 2.6 | 🖥️ Test Dashboard | `test-dashboard.yml` | Push/PR (src/browser) | Dashboard Cypress E2E |
1111+
| 2.7 | 🏠 Test Homepage | `test-homepage.yml` | Push/PR (src/browser) | Homepage Cypress E2E |
1112+
| 2.8 | 📰 Test News | `test-news.yml` | Push/PR (news) | News pages Cypress E2E |
11091113

11101114
### 📊 CIA Data Pipeline (1 workflow)
11111115

knip.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
"entry": [
44
"src/browser/**/*.ts",
55
"js/*.js",
6-
"dashboard/*.js",
76
"scripts/*.ts",
8-
"scripts/news-types/*.ts",
7+
"scripts/audits/**/*.ts",
98
"scripts/committees-dashboard/*.ts",
109
"scripts/coalition-dashboard/*.ts",
1110
"tests/**/*.test.ts",
@@ -16,7 +15,6 @@
1615
"project": [
1716
"src/browser/**/*.ts",
1817
"js/**/*.js",
19-
"dashboard/**/*.js",
2018
"scripts/**/*.ts",
2119
"tests/**/*.ts",
2220
"tests/**/*.js",
@@ -27,7 +25,10 @@
2725
],
2826
"ignoreDependencies": [
2927
"htmlhint",
30-
"js-yaml"
28+
"js-yaml",
29+
"mermaid",
30+
"chartjs-plugin-annotation",
31+
"worldbank-mcp"
3132
],
3233
"ignoreBinaries": [
3334
"cypress",

package-lock.json

Lines changed: 3 additions & 67 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@
166166
"devDependencies": {
167167
"@eslint/js": "10.0.1",
168168
"@types/d3": "7.4.3",
169+
"@types/hast": "3.0.4",
169170
"@types/node": "25.6.0",
170171
"@types/papaparse": "5.5.2",
171172
"@vitest/coverage-v8": "4.1.5",
@@ -176,22 +177,21 @@
176177
"chartjs-plugin-annotation": "3.1.0",
177178
"d3": "7.9.0",
178179
"eslint": "10.2.1",
180+
"github-slugger": "^2.0.0",
179181
"globals": "17.5.0",
180182
"gray-matter": "^4.0.3",
181183
"happy-dom": "20.9.0",
184+
"hast-util-to-string": "3.0.1",
182185
"htmlhint": "1.9.2",
183186
"js-yaml": "4.1.1",
184187
"json-schema-to-typescript": "15.0.4",
185188
"jszip": "3.10.1",
186189
"knip": "6.9.0",
187190
"mermaid": "11.14.0",
188191
"papaparse": "5.5.3",
189-
"playwright": "1.59.1",
190192
"rehype-autolink-headings": "^7.1.0",
191193
"rehype-raw": "^7.0.0",
192194
"rehype-sanitize": "^6.0.0",
193-
"github-slugger": "^2.0.0",
194-
"rehype-slug": "^6.0.0",
195195
"rehype-stringify": "^10.0.1",
196196
"remark-gfm": "^4.0.1",
197197
"remark-parse": "^11.0.0",
@@ -203,6 +203,7 @@
203203
"typescript": "6.0.3",
204204
"typescript-eslint": "8.59.1",
205205
"unified": "^11.0.5",
206+
"unist-util-visit": "5.1.0",
206207
"vite": "8.0.10",
207208
"vite-plugin-sri-gen": "1.4.1",
208209
"vitest": "4.1.5",

0 commit comments

Comments
 (0)