Skip to content
This repository was archived by the owner on Jun 3, 2026. It is now read-only.

Commit 37862e2

Browse files
committed
Bring back global setup
1 parent 3f94a3a commit 37862e2

5 files changed

Lines changed: 60 additions & 27 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ jobs:
2626
- name: Install dependencies
2727
run: npm install
2828

29-
- name: Sync content
30-
run: npx astro sync
31-
3229
- name: Build
3330
run: npm run cms:build
3431

AGENTS.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ Pre-commit hooks automatically run:
116116

117117
All checks must pass before commit is allowed.
118118

119-
**Test prerequisite:** Tests use `astro:content` via a mock that reads `.astro/data-store.json`. This file is generated by `npm run build` or `npx astro dev`. If it doesn't exist yet, run one of those first.
120-
121119
## Coding Patterns and Best Practices
122120

123121
### Code Style Guidelines (for Typescript)

SITE-ARCHITECTURE.md

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -903,25 +903,3 @@ This package is pinned to an exact version (`1.0.6`) rather than using a semver
903903
**Known bug:** The upstream plugin does not account for Astro's `base` path configuration, causing it to incorrectly flag all internal links as broken when the site is deployed under a sub-path. See [imazen/astro-broken-link-checker#16](https://github.com/imazen/astro-broken-link-checker/issues/16).
904904

905905
**Local fix:** Rather than waiting for an upstream fix, the plugin source has been inlined into `scripts/astro-broken-links-checker-index.js` and `scripts/astro-broken-links-checker-check-links.js`. The fix captures `config.base` in the `astro:config:setup` hook and strips the base prefix from internal links before resolving them against the `dist/` directory. `astro.config.mjs` imports from the local copy instead of the npm package.
906-
907-
## Testing
908-
909-
Tests run with [Vitest](https://vitest.dev/) via `npm test`. Because many tests call `getCollection()` from `astro:content`, and that virtual module only exists inside Astro's Vite pipeline, we alias it to a lightweight mock.
910-
911-
### `astro:content` Mock (`test/__mocks__/astro-content.ts`)
912-
913-
The mock reads `.astro/data-store.json` directly at module init time using `devalue.unflatten` — the same serialization format Astro uses internally. It implements `getCollection` and `getEntry` against that in-memory map, bypassing the `astro:data-layer-content` virtual module entirely.
914-
915-
The alias is registered in `vitest.config.ts`:
916-
917-
```typescript
918-
alias: {
919-
'astro:content': resolve('./test/__mocks__/astro-content.ts'),
920-
}
921-
```
922-
923-
**Prerequisite:** `.astro/data-store.json` must exist and be populated before running tests. Run `npm run build` or `npx astro dev` once to generate it. If the file is missing, `readFileSync` will throw with a clear error.
924-
925-
### Why not use the real `astro:content`?
926-
927-
`astro:content` is a Vite virtual module resolved by Astro's `vite-plugin-content-virtual-mod` plugin. It works fine during `astro build` / `astro dev`, but vitest's module resolution can't satisfy the `astro:data-layer-content` dynamic import that the real runtime depends on — even with `getViteConfig` from `astro/config` wiring up Astro's plugins. The mock sidesteps this by reading the pre-built data store directly.

test/global-setup.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { existsSync, readFileSync } from 'node:fs'
2+
import { spawn } from 'node:child_process'
3+
4+
const DATA_STORE_PATH = '.astro/data-store.json'
5+
const TIMEOUT_MS = 60_000
6+
const SYNCED_MARKER = 'Synced content'
7+
8+
function isDataStorePopulated(): boolean {
9+
if (!existsSync(DATA_STORE_PATH)) return false
10+
try {
11+
return readFileSync(DATA_STORE_PATH, 'utf-8').trim().length > 100
12+
} catch {
13+
return false
14+
}
15+
}
16+
17+
export async function setup() {
18+
if (isDataStorePopulated()) return
19+
20+
console.log('[global-setup] Data store not populated — starting astro dev temporarily...')
21+
22+
const server = spawn('npx', ['astro', 'dev'], {
23+
stdio: ['ignore', 'pipe', 'pipe'],
24+
detached: true,
25+
})
26+
27+
try {
28+
await new Promise<void>((resolve, reject) => {
29+
const timer = setTimeout(() => reject(new Error('Timed out waiting for "Synced content"')), TIMEOUT_MS)
30+
31+
const onData = (chunk: Buffer) => {
32+
process.stdout.write(chunk)
33+
if (chunk.toString().includes(SYNCED_MARKER)) {
34+
clearTimeout(timer)
35+
resolve()
36+
}
37+
}
38+
39+
server.stdout.on('data', onData)
40+
server.stderr.on('data', onData)
41+
server.on('error', (err) => {
42+
clearTimeout(timer)
43+
reject(err)
44+
})
45+
server.on('close', (code) => {
46+
if (code !== null) {
47+
clearTimeout(timer)
48+
reject(new Error(`Astro dev server exited with code ${code}`))
49+
}
50+
})
51+
})
52+
} finally {
53+
if (server.pid != null) {
54+
process.kill(-server.pid, 'SIGTERM')
55+
}
56+
}
57+
58+
console.log('[global-setup] Data store ready.')
59+
}

vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { resolve } from 'node:path'
44
export default getViteConfig({
55
test: {
66
include: ['test/**/*.test.ts'],
7+
globalSetup: ['test/global-setup.ts'],
78
alias: {
89
'astro:content': resolve('./test/__mocks__/astro-content.ts'),
910
},

0 commit comments

Comments
 (0)