Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
37888db
feat: scaffold Astro + Vue migration (phases 0-1)
sinduri-g Jul 21, 2026
b619d94
config: keep CI green for the nested astro/ migration app
sinduri-g Jul 21, 2026
71f7bcb
feat(astro): content collection with verified markdown pipeline (phas…
sinduri-g Jul 21, 2026
e7a3ba0
feat(astro): meta-description synthesis and services step injection (…
sinduri-g Jul 21, 2026
0eb3c2f
feat(astro): SEO component and adventure routes (phase 3 increment 1)
sinduri-g Jul 21, 2026
4d0b700
feat(astro): level detail route with static discussion and leaderboar…
sinduri-g Jul 21, 2026
eed19d8
feat(astro): challenges filter with first Vue island (phase 3 increme…
sinduri-g Jul 21, 2026
d3aa11d
feat(astro): site chrome, theme-toggle island, and home page (phase 3…
sinduri-g Jul 21, 2026
f38bcd1
feat(astro): consent banner island with GA4 gated load (phase 3 incre…
sinduri-g Jul 21, 2026
09573d4
feat(astro): design pass — real Hero and adventure cards (phase 3 inc…
sinduri-g Jul 21, 2026
b57b6e7
feat(astro): design pass — challenge card layout in the filter island…
sinduri-g Jul 21, 2026
75fb237
feat(astro): adventure detail page design (phase 3 increment 8)
sinduri-g Jul 21, 2026
6090a32
feat(astro): 404 page (phase 3)
sinduri-g Jul 21, 2026
72da682
feat(astro): static pages — privacy, accessibility, contribute, handb…
sinduri-g Jul 22, 2026
8e3b336
feat(astro): remaining static pages and redirects (phase 3)
sinduri-g Jul 22, 2026
676b8ea
feat(astro): challenge detail page design with architecture diagrams …
sinduri-g Jul 24, 2026
2d13df8
feat(astro): solution walkthrough route via alias bridge (phase 3)
sinduri-g Jul 24, 2026
ae01085
test(astro): accessibility e2e suite (axe + a11y checks) and fixes (p…
sinduri-g Jul 24, 2026
9e85ea0
test(astro): SEO + smoke + hydration e2e (phase 5)
sinduri-g Jul 24, 2026
d3e499f
ci(astro): rewrite deploy and preview workflows for astro-at-root (cu…
sinduri-g Jul 24, 2026
5c70dd9
refactor(astro): self-contain the app's data ahead of the cutover mov…
sinduri-g Jul 24, 2026
0cf49e7
feat(astro)!: cut over — Astro + Vue app becomes the root project (st…
sinduri-g Jul 24, 2026
6373f70
ci(astro): rewrite validate-adventures for the content collection (cu…
sinduri-g Jul 24, 2026
47cedc6
ci(astro): decouple sync-adventure and add-discussion-url from the ge…
sinduri-g Jul 24, 2026
b31d372
docs(claude): rewrite CLAUDE.md for the Astro + Vue stack (cutover fo…
sinduri-g Jul 24, 2026
e9acf45
docs(astro): rewrite README and prune stale REUSE entries (cutover fo…
sinduri-g Jul 24, 2026
1261fbc
docs(astro): update ADVENTURES, PERFORMANCE, styleguide for the migra…
sinduri-g Jul 24, 2026
df575e7
chore(astro): add ESLint for astro + vue + ts, wire into CI (cutover …
sinduri-g Jul 24, 2026
9812da1
feat(astro): generate sitemap.xml from the content collection (cutove…
sinduri-g Jul 24, 2026
86d6c15
docs(claude): mark lint + sitemap endpoint done, add lint to checks
sinduri-g Jul 24, 2026
4b2d201
test(astro): consent state-machine runtime regression tests (cutover …
sinduri-g Jul 24, 2026
505a37f
docs(claude): mark consent runtime tests done
sinduri-g Jul 24, 2026
0a91f2d
feat(astro): gated GA4 click-event tracking (cutover follow-up)
sinduri-g Jul 24, 2026
229d7dc
docs(claude): mark click-event tracking done
sinduri-g Jul 24, 2026
23482ca
feat(astro): absorb dead-reckoning expert level + abbr expansions fro…
sinduri-g Jul 24, 2026
59f99ce
feat(astro): restore navbar + footer chrome to production parity
sinduri-g Jul 24, 2026
058da35
feat(astro): rebuild home page sections to production parity
sinduri-g Jul 24, 2026
2354b5b
feat(astro): rebuild Adventures index page to production parity
sinduri-g Jul 24, 2026
c788bed
feat(astro): rebuild challenges filter UI + interactive home/challeng…
sinduri-g Jul 24, 2026
a69be42
fix(astro): restore adventure-detail + level + 404 regressions
sinduri-g Jul 24, 2026
8f986a8
feat(astro): restore code-block language-label header + Copy button
sinduri-g Jul 24, 2026
c11ad14
docs: add current Astro/Vue component inventory to styleguide
sinduri-g Jul 24, 2026
29f637b
fix(astro): address code-review findings on the parity work
sinduri-g Jul 24, 2026
d96dab6
refactor(astro): extract shared adventure sort + live check to lib/ch…
sinduri-g Jul 24, 2026
18a1407
Merge origin/main into feat/astro-migration
sinduri-g Jul 25, 2026
17941dc
fix(a11y): JS abbreviation tooltips (fix mobile overflow + cutoff)
sinduri-g Jul 25, 2026
2034610
docs(claude): mark abbr JS tooltip + parity restoration done in follo…
sinduri-g Jul 25, 2026
4eb56df
chore(reuse): restore CC0-1.0 annotation for scraped community data
sinduri-g Jul 25, 2026
18ec147
perf(astro): defer/scope island hydration + trim filter payload
sinduri-g Jul 27, 2026
52a2279
refactor(astro): render code-block header + Copy button at build time
sinduri-g Jul 27, 2026
6577bbe
fix(astro): address 28 review issues across stability, perf, a11y, SE…
sinduri-g Jul 27, 2026
ba3f0ba
fix(astro): audit fixes — bugs, types, a11y, dead code, CI
sinduri-g Jul 27, 2026
e98551f
fix(astro): apply full branch audit — CI, a11y, bugs, cleanup
sinduri-g Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .github/workflows/a11y-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,20 @@ jobs:

- run: npm ci

- run: npm run sync

- run: npm run build

- run: npx playwright install --with-deps chromium
- uses: actions/cache@v6
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}

- if: steps.playwright-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps chromium

- if: steps.playwright-cache.outputs.cache-hit == 'true'
run: npx playwright install-deps chromium

- run: npm run test:e2e
9 changes: 3 additions & 6 deletions .github/workflows/add-discussion-url.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ jobs:
DISCUSSION_URL: ${{ inputs.discussion_url }}
run: node scripts/set-discussion-url.mjs

- name: Regenerate TypeScript
run: node scripts/generate-adventures.mjs
- name: Validate adventure YAML (Zod content schema)
run: npm run sync

- name: Create pull request
env:
Expand All @@ -125,9 +125,6 @@ jobs:
git add \
"src/data/adventures/${ADVENTURE_ID}/adventure.yaml" \
"src/data/adventures/${ADVENTURE_ID}/${LEVEL_ID}-posts.json" \
"src/data/adventures/${ADVENTURE_ID}.generated.ts" \
"src/data/adventures/index.ts" \
"src/data/adventures/summaries.ts" \
"scripts/refresh-leaderboard.mjs"

HAS_CHANGES=false
Expand All @@ -154,8 +151,8 @@ jobs:

- \`adventure.yaml\` — \`community_url\` set on the \`${LEVEL_ID}\` level; \`community_category_id\` set at adventure root if it was missing
- \`${LEVEL_ID}-posts.json\` — \`discussionUrl\` set and initial posts fetched from Discourse
- Generated TypeScript updated (\`${ADVENTURE_ID}.generated.ts\`, \`index.ts\`, \`summaries.ts\`)
- \`scripts/refresh-leaderboard.mjs\` — \`ADVENTURE_CATEGORIES\` patched with the resolved category ID
- (Astro reads the YAML directly — no generated TypeScript to update)

### Before merging

Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,18 @@ jobs:

- run: npm ci

- run: npm run build
- run: npm run sync
- run: npm run lint

- run: cp dist/client/404/index.html dist/client/404.html
# Astro static build → dist/ (not dist/client/). Astro emits dist/404.html
# natively, so the old `cp .../404/index.html 404.html` step is gone.
- run: npm run build

- name: Deploy to gh-pages
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: dist/client
folder: dist
force: false
clean: true
clean-exclude: |
Expand Down
48 changes: 17 additions & 31 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
lint:
check:
if: github.event.action != 'closed'
runs-on: ubuntu-latest
steps:
Expand All @@ -32,6 +32,9 @@ jobs:
- if: steps.node-cache.outputs.cache-hit != 'true'
run: npm ci

# Content validation gate: astro sync runs the Zod collection schema and
# fails on invalid adventure YAML.
- run: npm run sync
- run: npm run lint

build:
Expand All @@ -56,12 +59,10 @@ jobs:

- run: npm run build

- run: npm test

- uses: actions/upload-artifact@v7
with:
name: dist-client
path: dist/client/
name: dist
path: dist/
retention-days: 1

e2e:
Expand Down Expand Up @@ -89,10 +90,10 @@ jobs:
- if: steps.node-cache.outputs.cache-hit != 'true'
run: npm ci

- uses: actions/download-artifact@v8
- uses: actions/download-artifact@v7
with:
name: dist-client
path: dist/client/
name: dist
path: dist/

- uses: actions/cache@v6
id: playwright-cache
Expand All @@ -106,13 +107,12 @@ jobs:
- if: steps.playwright-cache.outputs.cache-hit == 'true'
run: npx playwright install-deps chromium

# playwright.config webServer runs `astro preview` (serves dist/) itself.
- run: npm run test:e2e -- --shard=${{ matrix.shard }}/3

preview:
needs: [lint, e2e]
# Run when both passed (normal PR update), or when build was skipped (PR closed, cleanup).
# Never run when tests failed.
if: always() && ((needs.lint.result == 'success' && needs.e2e.result == 'success') || needs.lint.result == 'skipped')
needs: [check, e2e]
if: always() && ((needs.check.result == 'success' && needs.e2e.result == 'success') || needs.check.result == 'skipped')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand All @@ -132,27 +132,13 @@ jobs:
- if: github.event.action != 'closed' && steps.node-cache.outputs.cache-hit != 'true'
run: npm ci

# Astro's `base` (from VITE_BASE_PATH) prefixes every asset/link, and public/
# assets are copied into dist/ automatically — so the whole dist/ deploys as
# the preview with no per-directory asset-copy step. Layout.astro marks
# /pr-preview/ builds noindex.
- if: github.event.action != 'closed'
run: VITE_BASE_PATH=/pr-preview/pr-${{ github.event.number }}/ npm run build

- if: github.event.action != 'closed'
run: |
PREVIEW_DIR="dist/client/pr-preview/pr-${{ github.event.number }}"
cp -r dist/client/assets "${PREVIEW_DIR}/"
cp -r dist/client/fonts "${PREVIEW_DIR}/"
cp -r dist/client/reveal "${PREVIEW_DIR}/"
cp -r dist/client/team "${PREVIEW_DIR}/"
cp -r dist/client/speakers "${PREVIEW_DIR}/"
cp -r dist/client/brand "${PREVIEW_DIR}/"
cp -r dist/client/solutions "${PREVIEW_DIR}/"
cp -r dist/client/qr "${PREVIEW_DIR}/"
cp -r dist/client/downloads "${PREVIEW_DIR}/"
cp -r dist/client/screenshots "${PREVIEW_DIR}/"
cp -r dist/client/deck "${PREVIEW_DIR}/"
cp -r dist/client/deck-template "${PREVIEW_DIR}/"
find dist/client -maxdepth 1 -type f \( -name "*.svg" -o -name "*.png" -o -name "*.ico" -o -name "*.webmanifest" -o -name "*.webp" \) -exec cp {} "${PREVIEW_DIR}/" \;
cp "${PREVIEW_DIR}/index.html" "${PREVIEW_DIR}/404.html"

- uses: rossjrw/pr-preview-action@v1
with:
source-dir: dist/client/pr-preview/pr-${{ github.event.number }}/
source-dir: dist/
58 changes: 21 additions & 37 deletions .github/workflows/sync-adventure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,20 @@ jobs:
LEVELS_TO_SYNC: ${{ inputs.levels }}
run: node scripts/sync-adventure.mjs

- name: Validate and regenerate TypeScript
run: node scripts/generate-adventures.mjs
- name: Validate adventure YAML (Zod content schema)
run: npm run sync

- name: Create pull request
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
ADVENTURE_URL: ${{ inputs.adventure_url }}
run: |
SLUG=$(cat /tmp/adventure-slug)
NAME=$(cat /tmp/adventure-name)
LEVELS=$(cat /tmp/adventure-levels)
MODE=$(cat /tmp/adventure-mode)
BRANCH="feat/adventure-${SLUG}"
SOURCE_URL="${{ inputs.adventure_url }}"
SOURCE_URL="$ADVENTURE_URL"

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
Expand All @@ -111,19 +112,13 @@ jobs:
git fetch origin "$BRANCH" 2>/dev/null || true

git checkout -b "$BRANCH" 2>/dev/null || git checkout "$BRANCH"
# Astro reads the YAML directly (Zod content collection) — no generated
# TS, prerender array, or sitemap region to commit. Routes come from
# getStaticPaths at build time.
git add \
src/data/adventures/${SLUG}/ \
src/data/adventures/${SLUG}.generated.ts \
src/data/adventures/index.ts \
src/data/adventures/summaries.ts \
src/data/adventures/types.ts \
src/assets/diagrams/ \
public/sitemap.xml \
react-router.config.ts \
scripts/refresh-leaderboard.mjs \
e2e/smoke.spec.ts \
src/test/seo.test.ts \
src/test/prerender.test.ts
scripts/refresh-leaderboard.mjs
git commit -m "feat: sync adventure ${SLUG} from challenges repo (${MODE})"

# The branch is owned by this workflow, so a plain --force is safe here and
Expand Down Expand Up @@ -156,23 +151,18 @@ jobs:

### Manual steps (only if needed)

- [ ] If a level's \`architecture_diagram\` SVG was not auto-fetched (check the sync logs for a warning), add the SVG manually to \`src/assets/diagrams/\` and add \`architecture_diagram: <file>.svg\` to that level in \`adventure.yaml\`, then run \`npm run generate\`
- [ ] If a level has an \`architecture_diagram\` but no \`diagram_alt\`, add \`diagram_alt:\` to that level in \`adventure.yaml\` with a one-sentence description of the diagram, then run \`npm run generate\`
- [ ] Run \`node scripts/refresh-discussions.mjs\` after \`discussionUrl\` values are set
- [ ] If a level's \`architecture_diagram\` SVG was not auto-fetched (check the sync logs for a warning), add the SVG manually to \`src/assets/diagrams/\` and add \`architecture_diagram: <file>.svg\` to that level in \`adventure.yaml\` - [ ] If a level has an \`architecture_diagram\` but no \`diagram_alt\`, add \`diagram_alt:\` to that level in \`adventure.yaml\` with a one-sentence description of the diagram - [ ] Run \`node scripts/refresh-discussions.mjs\` after \`discussionUrl\` values are set

### Auto-generated (do not edit by hand)
### Routes & sitemap

The following are kept in sync with \`adventure.yaml\` by \`npm run generate\` (prebuild hook):
- \`public/sitemap.xml\` (GENERATED:adventures region)
- \`react-router.config.ts\` prerender (GENERATED:adventures region)
- \`e2e/smoke.spec.ts\` and \`src/test/seo.test.ts\` route arrays
- \`src/test/prerender.test.ts\` pages array
- \`scripts/refresh-leaderboard.mjs\` ADVENTURE_CATEGORIES
Routes are generated from \`adventure.yaml\` by the Astro content collection
at build time (\`getStaticPaths\`) — there is nothing to regenerate or commit.
Only \`scripts/refresh-leaderboard.mjs\` ADVENTURE_CATEGORIES is hand-maintained.

### Checks

\`\`\`sh
npm run lint && npm test && npm run build && npm run test:e2e
npm run sync && npm run build && npm run test:e2e
\`\`\`
EOF
else
Expand All @@ -197,32 +187,26 @@ jobs:
about: "One sentence bio."
\`\`\`
- [ ] Confirm \`month:\` is correct for the planned release
- [ ] Set \`community_category_id:\` in \`src/data/adventures/${SLUG}/adventure.yaml\` (look up at https://community.offon.dev/categories.json), then run \`npm run generate\`
- [ ] Update \`rewards.deadline:\` from \`TODO\` to ISO 8601 (e.g. \`2026-07-01T23:59:00+01:00\`)
- [ ] Set \`community_category_id:\` in \`src/data/adventures/${SLUG}/adventure.yaml\` (look up at https://community.offon.dev/categories.json) - [ ] Update \`rewards.deadline:\` from \`TODO\` to ISO 8601 (e.g. \`2026-07-01T23:59:00+01:00\`)
- [ ] Review \`topics:\` on each level, auto-set to all adventure tags, refine to level-specific subset if needed
- [ ] Update \`discussion_url:\` in each level once the Discourse threads are created
- [ ] Update \`discussionUrl\` in each \`*-posts.json\` stub

### Manual steps (only if needed)

- [ ] If a level's \`architecture_diagram\` SVG was not auto-fetched (check the sync logs for a warning), add the SVG manually to \`src/assets/diagrams/\` and add \`architecture_diagram: <file>.svg\` to that level in \`adventure.yaml\`, then run \`npm run generate\`
- [ ] If a level has an \`architecture_diagram\` but no \`diagram_alt\`, add \`diagram_alt:\` to that level in \`adventure.yaml\` with a one-sentence description of the diagram, then run \`npm run generate\`
- [ ] Run \`node scripts/refresh-leaderboard.mjs\` after \`community_category_id\` is set
- [ ] If a level's \`architecture_diagram\` SVG was not auto-fetched (check the sync logs for a warning), add the SVG manually to \`src/assets/diagrams/\` and add \`architecture_diagram: <file>.svg\` to that level in \`adventure.yaml\` - [ ] If a level has an \`architecture_diagram\` but no \`diagram_alt\`, add \`diagram_alt:\` to that level in \`adventure.yaml\` with a one-sentence description of the diagram - [ ] Run \`node scripts/refresh-leaderboard.mjs\` after \`community_category_id\` is set
- [ ] Run \`node scripts/refresh-discussions.mjs\` after \`discussionUrl\` values are set

### Auto-generated (do not edit by hand)
### Routes & sitemap

The following are kept in sync with \`adventure.yaml\` by \`npm run generate\` (prebuild hook):
- \`public/sitemap.xml\` (GENERATED:adventures region)
- \`react-router.config.ts\` prerender (GENERATED:adventures region)
- \`e2e/smoke.spec.ts\` and \`src/test/seo.test.ts\` route arrays
- \`src/test/prerender.test.ts\` pages array
- \`scripts/refresh-leaderboard.mjs\` ADVENTURE_CATEGORIES
Routes are generated from \`adventure.yaml\` by the Astro content collection
at build time (\`getStaticPaths\`) — there is nothing to regenerate or commit.
Only \`scripts/refresh-leaderboard.mjs\` ADVENTURE_CATEGORIES is hand-maintained.

### Checks

\`\`\`sh
npm run lint && npm test && npm run build && npm run test:e2e
npm run sync && npm run build && npm run test:e2e
\`\`\`
EOF
fi
Expand Down
Loading
Loading