Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 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
9a52c6b
chore(merge): merge origin/main into feat/astro-migration
sinduri-g Jul 28, 2026
58c385e
fix: restore ConsentBanner to prod parity and fix all audit findings
sinduri-g Jul 28, 2026
9bb92e4
test: add Vitest unit test suite covering lib, stores, and Vue compon…
sinduri-g Jul 28, 2026
248ea8a
chore(icons): replace astro-icon and lucide-vue-next with unplugin-icons
sinduri-g Jul 28, 2026
a9066ac
chore(icons): migrate all component and page icon references
sinduri-g Jul 28, 2026
11a533c
fix(community): restore challenge-rockstars section on about and cont…
sinduri-g Jul 28, 2026
c7ef475
fix(test): update challenges filter smoke test for radio role
sinduri-g Jul 28, 2026
f859999
refactor: post-migration audit fixes and test improvements
sinduri-g Jul 28, 2026
0911bcd
fix(a11y): add focus ring to nudge link and raise dismiss button to 32px
sinduri-g Jul 28, 2026
2dd1a32
fix(a11y): prevent verification command pre from overflowing at 200% …
sinduri-g Jul 28, 2026
89f2129
docs(claude): fix stale Reka UI reference and Phase 1 comment
sinduri-g Jul 28, 2026
2fe229e
feat(markdown): add Shiki dual-theme syntax highlighting for code blocks
sinduri-g Jul 28, 2026
1680563
docs(claude): mark Shiki highlighting done in known follow-ups
sinduri-g Jul 28, 2026
6b7d5a9
docs(styleguide): rewrite for Astro + Vue — full component API reference
sinduri-g Jul 28, 2026
bcac121
fix(test): add missing dead-reckoning detail route; drop stale comments
sinduri-g Jul 28, 2026
744563f
chore: exhaustive audit fixes across 20 files
sinduri-g Jul 28, 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
2 changes: 2 additions & 0 deletions .github/workflows/a11y-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:

- run: npm ci

- run: npm run sync

- run: npm run build

- uses: actions/cache@v6
Expand Down
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
18 changes: 14 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,27 @@ jobs:
node-version-file: .nvmrc
cache: npm

- run: npm ci
- uses: actions/cache@v6
id: npm-cache
with:
path: node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }}

- run: npm run build
- if: steps.npm-cache.outputs.cache-hit != 'true'
run: npm ci

- run: cp dist/client/404/index.html dist/client/404.html
- run: npm run sync
- run: npm run lint

# 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
50 changes: 19 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 @@ -91,8 +92,8 @@ jobs:

- 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,15 @@ 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"
env:
PR_NUMBER: ${{ github.event.number }}
run: VITE_BASE_PATH=/pr-preview/pr-${PR_NUMBER}/ npm run build

- uses: rossjrw/pr-preview-action@v1
with:
source-dir: dist/client/pr-preview/pr-${{ github.event.number }}/
source-dir: dist/
62 changes: 23 additions & 39 deletions .github/workflows/sync-adventure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
inputs:
adventure_url:
description: >
GitHub URL of the adventure folder in the challenges repo any branch works.
GitHub URL of the adventure folder in the challenges repo (any branch works).
main: https://github.com/off-on-dev/open-source-challenges/tree/main/adventures/05-lex-imperfecta
PR branch: https://github.com/off-on-dev/open-source-challenges/tree/feat/my-branch/adventures/05-lex-imperfecta
required: true
Expand Down Expand Up @@ -73,7 +73,7 @@ jobs:
if git show "origin/$BRANCH:${YAML_PATH}" > /tmp/pr-adventure.yaml 2>/dev/null && [ -s /tmp/pr-adventure.yaml ]; then
mkdir -p "src/data/adventures/${SLUG}"
cp /tmp/pr-adventure.yaml "$YAML_PATH"
echo "Restored adventure.yaml from PR branch ${BRANCH} manual edits (discussion_url, topics, architecture_diagram, diagram_alt, deadline) will be preserved by sync-adventure.mjs"
echo "Restored adventure.yaml from PR branch ${BRANCH}; manual edits (discussion_url, topics, architecture_diagram, diagram_alt, deadline) will be preserved by sync-adventure.mjs"
else
echo "PR branch ${BRANCH} exists but has no adventure.yaml yet — starting fresh from main"
fi
Expand All @@ -88,14 +88,15 @@ 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: |
set -euo pipefail
SLUG=$(cat /tmp/adventure-slug)
NAME=$(cat /tmp/adventure-name)
LEVELS=$(cat /tmp/adventure-levels)
Expand All @@ -112,27 +113,21 @@ 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
# avoids the "stale info" failure mode of --force-with-lease without a ref.
git push --force origin "$BRANCH"

if [ "$MODE" = "update" ]; then
PR_TITLE="feat(adventure): add levels to ${NAME} ${LEVELS}"
PR_TITLE="feat(adventure): add levels to ${NAME}: ${LEVELS}"
else
PR_TITLE="feat(adventure): add ${NAME}"
fi
Expand All @@ -157,23 +152,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 @@ -198,32 +188,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