Skip to content

Commit 78f0236

Browse files
soodokuclaude
andauthored
chore(ci): fix the daily CI failures — Node 22, vitest 4 config, Dependabot (#54)
* ci: run on Node 22 via .nvmrc instead of Node 18 The locked toolchain requires Node >= 20.19 (vite 8, rolldown 1.1, @vitejs/plugin-react 5, vitest 4, pdfjs-dist 4). On Node 18 `npm test` died at config load with: SyntaxError: The requested module 'node:util' does not provide an export named 'styleText' `styleText` does not exist in Node 18. This is the root cause of both the failing `test` job in ci.yml and the failing "Run tests after updates" step in the nightly dependency-updates job. Pin the version once in .nvmrc and read it via node-version-file in all seven setup-node steps, so local and CI can't drift. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: migrate vitest.config.ts to vitest 4, emit lcov coverage vitest 4 removed poolOptions entirely (Tinypool is gone); singleThread and maxThreads collapse into a top-level maxWorkers, and minThreads has no replacement. The stale block was a real `tsc --noEmit` error: vitest.config.ts(24,5): error TS2769: No overload matches this call. 'poolOptions' does not exist in type 'InlineConfig'. Keep isolate: true. The upstream migration note maps singleThread to "maxWorkers: 1, isolate: false", but that is a performance recipe, not a semantic equivalence -- the old config set singleThread AND isolate, and dropping isolation here would share src/test/setup.ts's non-configurable global `process` replacement across files and leak logger.test.ts's console spies (it never calls restoreAllMocks). Also set coverage.reporter to ['text', 'lcov']. vitest's default set is text/html/clover/json, so coverage/lcov.info never existed and the Codecov upload in ci.yml has always been a silent no-op. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * ci: drop the Vercel deploy and Lighthouse jobs deploy-preview, deploy-production, and performance-audit have never executed -- they sit behind `needs: [build]`, and build has been blocked by the failing test job. Fixing the tests would have made them run for the first time and go red. Nothing in this repo deploys to Vercel: the repo has zero secrets, zero variables, and zero environments; there is no vercel.json and no .vercel/; `gh api repos/gojiplus/reader/deployments` returns empty; and README.md, CLAUDE.md, and firebase.json all describe a Firebase project. Vercel appeared nowhere outside this file. performance-audit was broken independently: lighthouserc.json sets startServerReadyPattern to "ready on", which Next 15 never prints (it prints "Ready in ..."), so LHCI would block until its start-server timeout. lighthouserc.json is left in place for manual `npx lhci autorun`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * ci: bump actions to latest, fix codecov input, make type-check a real gate Action bumps (every `uses:` in both workflows): actions/checkout v4 -> v7 actions/setup-node v4 -> v7 actions/upload-artifact v4 -> v7 github/codeql-action/* v3 -> v4 (v3 deprecates Dec 2026) codecov/codecov-action v4 -> v7 peter-evans/create-pull-request v5 -> v8 aquasecurity/trivy-action master -> 0.36.0 This clears the "Node.js 20 is deprecated" annotation on every run, and pinning trivy-action off `master` closes an unpinned-ref supply-chain exposure. codecov-action v5 removed the `file` input in favour of `files`. Left unchanged, v7 would have failed on an unknown input. Verified against the action.yml at v7: there is no `file`. Remove continue-on-error from type-check. The only error it was masking was the vitest.config.ts poolOptions overload, fixed in the previous commit; `npx tsc --noEmit` is now clean. This matters because next.config.ts sets typescript.ignoreBuildErrors, so this job is the repo's only type gate. Exclude .next/cache from the build artifact. The build job has never run to completion, so `path: .next/` has never actually uploaded -- on a Next 15 build that is a few hundred MB of webpack cache for a 1-day retention artifact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * ci: collapse CodeQL matrix to a single javascript-typescript job GitHub annotated every run: CodeQL language 'javascript' is referenced by more than one entry in the 'language' matrix parameter for job 'codeql-analysis'. This may result in duplicate alerts. They are the same language. The two jobs each spent ~2m40s producing duplicate alerts. javascript-typescript is the canonical single value -- it is what this repo's own code-scanning API reports. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * ci: fix the nightly dependency-updates job, untrack outdated.json Three bugs in one job. 1. `npm outdated --json` prints `{}` when nothing is outdated, and `{}` is 3 bytes, so `[ -s outdated.json ]` was always true and updates_available was effectively hardcoded to true. 2. The job wrote outdated.json into the working tree and then used `git status --porcelain` over the whole tree to decide changes_made, so its own scratch file influenced the answer. 3. Because create-pull-request had no add-paths, that scratch file got swept into the commit. outdated.json is tracked in git today and this workflow has committed it to main five times (#28, #29, #47, ...). Scratch now goes to $RUNNER_TEMP, the {} case is handled, changes_made is scoped to package.json and package-lock.json, and add-paths pins the PR contents to those two files. Also allow workflow_dispatch. Under `if: github.event_name == 'schedule'` this job could not be tested without waiting for 2 AM UTC. `npx --yes` because the log shows npm-check-updates being resolved via an interactive install prompt, and the step is renamed to match what `--target patch` actually does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * ci: correct trivy tag and make the build artifact non-empty trivy-action tags are v-prefixed from 0.33.0 onward; @0.36.0 does not resolve and failed the Security Scan job at set-up. The build artifact uploaded nothing: ".next" is a dotfile directory and upload-artifact skips hidden paths unless include-hidden-files is set. This was pre-existing -- the build job had never run to completion, so it had never been observed. Verified the path patterns directly against @actions/glob (the library upload-artifact uses): with hidden files included, ".next/" matches 202 entries and the "!.next/cache/" exclusion brings that to 140. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * ci: replace the nightly updater with Dependabot, keep CodeQL weekly The "Security & Updates" workflow had three jobs and only one of them was pulling its weight. - audit-dependencies ran `npm audit` behind continue-on-error and uploaded a JSON report as a 30-day artifact. It could not fail and nothing consumed the artifact -- it just produced the "exit code 1" annotation on every nightly run. - dependency-updates hand-rolled `npm-check-updates` in bash to open a patch-bump PR. Dependabot is already active on this repo and does the same thing with rebasing and conflict handling. The bash version had no rebase story, and its own scratch file kept landing in main. - codeql-analysis is the one worth keeping, but daily is far more often than this repo changes. So: add .github/dependabot.yml covering npm weekly (grouped, so a week of bumps is one or two PRs) plus github-actions weekly -- the latter is what would have flagged the Node 20 deprecation on checkout/setup-node before it became an annotation on every run. Until now Dependabot was only doing security updates from repo settings, with no config file, which is why the bash updater existed at all. The workflow is now CodeQL-only and renamed to match, running Mondays. Its permissions drop to contents: read now that nothing pushes branches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent f4e5021 commit 78f0236

9 files changed

Lines changed: 125 additions & 492 deletions

File tree

.github/dependabot.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: 2
2+
3+
updates:
4+
- package-ecosystem: npm
5+
directory: '/'
6+
schedule:
7+
interval: weekly
8+
day: monday
9+
open-pull-requests-limit: 5
10+
# Grouped so a week of bumps is one or two PRs to review, not fifteen.
11+
# Major production bumps stay ungrouped and get their own PR.
12+
groups:
13+
radix-ui:
14+
patterns:
15+
- '@radix-ui/*'
16+
dev-dependencies:
17+
dependency-type: development
18+
production-minor-patch:
19+
dependency-type: production
20+
update-types:
21+
- minor
22+
- patch
23+
24+
# Workflow actions go stale silently; this is what would have caught the
25+
# Node 20 deprecation on checkout/setup-node before it became an annotation
26+
# on every run.
27+
- package-ecosystem: github-actions
28+
directory: '/'
29+
schedule:
30+
interval: weekly
31+
day: monday
32+
groups:
33+
actions:
34+
patterns:
35+
- '*'

.github/workflows/ci.yml

Lines changed: 24 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ jobs:
1717

1818
steps:
1919
- name: Checkout code
20-
uses: actions/checkout@v4
20+
uses: actions/checkout@v7
2121

2222
- name: Setup Node.js
23-
uses: actions/setup-node@v4
23+
uses: actions/setup-node@v7
2424
with:
25-
node-version: '18'
25+
node-version-file: '.nvmrc'
2626
cache: 'npm'
2727

2828
- name: Install dependencies
@@ -40,12 +40,12 @@ jobs:
4040

4141
steps:
4242
- name: Checkout code
43-
uses: actions/checkout@v4
43+
uses: actions/checkout@v7
4444

4545
- name: Setup Node.js
46-
uses: actions/setup-node@v4
46+
uses: actions/setup-node@v7
4747
with:
48-
node-version: '18'
48+
node-version-file: '.nvmrc'
4949
cache: 'npm'
5050

5151
- name: Install dependencies
@@ -55,9 +55,9 @@ jobs:
5555
run: npm test -- --coverage
5656

5757
- name: Upload coverage to Codecov
58-
uses: codecov/codecov-action@v4
58+
uses: codecov/codecov-action@v7
5959
with:
60-
file: ./coverage/lcov.info
60+
files: ./coverage/lcov.info
6161
fail_ci_if_error: false
6262

6363
type-check:
@@ -66,20 +66,19 @@ jobs:
6666

6767
steps:
6868
- name: Checkout code
69-
uses: actions/checkout@v4
69+
uses: actions/checkout@v7
7070

7171
- name: Setup Node.js
72-
uses: actions/setup-node@v4
72+
uses: actions/setup-node@v7
7373
with:
74-
node-version: '18'
74+
node-version-file: '.nvmrc'
7575
cache: 'npm'
7676

7777
- name: Install dependencies
7878
run: npm ci
7979

8080
- name: Run type check
8181
run: npm run typecheck
82-
continue-on-error: true # Allow to continue while we fix existing type issues
8382

8483
build:
8584
name: Build Application
@@ -88,12 +87,12 @@ jobs:
8887

8988
steps:
9089
- name: Checkout code
91-
uses: actions/checkout@v4
90+
uses: actions/checkout@v7
9291

9392
- name: Setup Node.js
94-
uses: actions/setup-node@v4
93+
uses: actions/setup-node@v7
9594
with:
96-
node-version: '18'
95+
node-version-file: '.nvmrc'
9796
cache: 'npm'
9897

9998
- name: Install dependencies
@@ -112,10 +111,15 @@ jobs:
112111
GOOGLE_GENAI_API_KEY: ${{ secrets.GOOGLE_GENAI_API_KEY || 'mock-genai-key' }}
113112

114113
- name: Upload build artifacts
115-
uses: actions/upload-artifact@v4
114+
uses: actions/upload-artifact@v7
116115
with:
117116
name: build-files
118-
path: .next/
117+
path: |
118+
.next/
119+
!.next/cache/
120+
# .next is a dotfile directory, and upload-artifact skips hidden
121+
# paths by default -- without this the artifact is empty.
122+
include-hidden-files: true
119123
retention-days: 1
120124

121125
security-scan:
@@ -124,74 +128,18 @@ jobs:
124128

125129
steps:
126130
- name: Checkout code
127-
uses: actions/checkout@v4
131+
uses: actions/checkout@v7
128132

129133
- name: Run Trivy vulnerability scanner
130-
uses: aquasecurity/trivy-action@master
134+
uses: aquasecurity/trivy-action@v0.36.0
131135
with:
132136
scan-type: 'fs'
133137
scan-ref: '.'
134138
format: 'sarif'
135139
output: 'trivy-results.sarif'
136140

137141
- name: Upload Trivy scan results to GitHub Security tab
138-
uses: github/codeql-action/upload-sarif@v3
142+
uses: github/codeql-action/upload-sarif@v4
139143
if: always()
140144
with:
141145
sarif_file: 'trivy-results.sarif'
142-
143-
deploy-preview:
144-
name: Deploy Preview (Vercel)
145-
runs-on: ubuntu-latest
146-
needs: [build]
147-
if: github.event_name == 'pull_request'
148-
149-
steps:
150-
- name: Checkout code
151-
uses: actions/checkout@v4
152-
153-
- name: Deploy to Vercel (Preview)
154-
uses: amondnet/vercel-action@v25
155-
with:
156-
vercel-token: ${{ secrets.VERCEL_TOKEN }}
157-
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
158-
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
159-
github-comment: true
160-
161-
deploy-production:
162-
name: Deploy to Production (Vercel)
163-
runs-on: ubuntu-latest
164-
needs: [build]
165-
if: github.ref == 'refs/heads/main'
166-
167-
steps:
168-
- name: Checkout code
169-
uses: actions/checkout@v4
170-
171-
- name: Deploy to Vercel (Production)
172-
uses: amondnet/vercel-action@v25
173-
with:
174-
vercel-token: ${{ secrets.VERCEL_TOKEN }}
175-
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
176-
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
177-
vercel-args: '--prod'
178-
github-comment: false
179-
180-
performance-audit:
181-
name: Performance Audit
182-
runs-on: ubuntu-latest
183-
needs: [deploy-preview]
184-
if: github.event_name == 'pull_request'
185-
186-
steps:
187-
- name: Checkout code
188-
uses: actions/checkout@v4
189-
190-
- name: Wait for deployment
191-
run: sleep 30
192-
193-
- name: Run Lighthouse CI
194-
uses: treosh/lighthouse-ci-action@v10
195-
with:
196-
uploadArtifacts: true
197-
temporaryPublicStorage: true

.github/workflows/codeql.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: CodeQL
2+
3+
on:
4+
schedule:
5+
# Mondays at 2 AM UTC
6+
- cron: '0 2 * * 1'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
security-events: write
12+
13+
jobs:
14+
codeql-analysis:
15+
name: CodeQL Security Analysis
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v7
21+
22+
- name: Initialize CodeQL
23+
uses: github/codeql-action/init@v4
24+
with:
25+
# CodeQL treats JS and TS as one language; listing both duplicated
26+
# every alert and doubled the runtime.
27+
languages: javascript-typescript
28+
29+
- name: Setup Node.js
30+
uses: actions/setup-node@v7
31+
with:
32+
node-version-file: '.nvmrc'
33+
cache: 'npm'
34+
35+
- name: Install dependencies
36+
run: npm ci
37+
38+
- name: Build for analysis
39+
run: npm run build
40+
env:
41+
NEXT_PUBLIC_FIREBASE_API_KEY: 'mock-api-key'
42+
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: 'mock.firebaseapp.com'
43+
NEXT_PUBLIC_FIREBASE_PROJECT_ID: 'mock-project'
44+
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: 'mock.appspot.com'
45+
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: '123456789'
46+
NEXT_PUBLIC_FIREBASE_APP_ID: 'mock-app-id'
47+
GOOGLE_GENAI_API_KEY: 'mock-genai-key'
48+
49+
- name: Perform CodeQL Analysis
50+
uses: github/codeql-action/analyze@v4

0 commit comments

Comments
 (0)