Skip to content

fix(sync): carry contributors from challenges repo, warn on long meta… - #242

Merged
sinduri-g merged 3 commits into
mainfrom
fix/sync-contributor-and-meta-description
Sep 7, 2026
Merged

fix(sync): carry contributors from challenges repo, warn on long meta…#242
sinduri-g merged 3 commits into
mainfrom
fix/sync-contributor-and-meta-description

Conversation

@sinduri-g

@sinduri-g sinduri-g commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

… descriptions

The Sync Adventure workflow failed on adventure-accessibility-nightmare with two unrelated schema errors. Both are fixed here.

meta_description length no longer fails the build

  • Dropped .max(160) from the adventure and level schemas
  • warnIfMetaDescriptionLong logs the over-run instead, called from renderLevel and the adventure transform
  • Search engines truncate a long description rather than reject it, so this was never worth failing a whole sync run over

Contributors now sync from the challenges repo

  • The adventure designer is read from contributor: in docs/index.yaml. The sync previously kept only one already hand-written into the website YAML, so a freshly synced adventure got none
  • The challenge builder already flowed through from the level YAML, but unfiltered. pickContributor now keeps only the four fields the strict content schema accepts, on both paths
  • A contributor already credited on the website wins over the upstream value at both levels, and mergeLevels warns when the two diverge rather than dropping the divergence silently

The missing designer alongside levels naming their own builder is what tripped creditIntegrityError and produced the second error.

  • Tests: pickContributor, buildLevel and mergeLevels credit rules
  • Docs: ADVENTURES.md field and preservation tables, sync PR checklist
  • Corrected two comments claiming the sync deliberately omits contributor

Type of change

  • feat new feature
  • fix bug fix
  • refactor no behavior change
  • docs / chore / config / perf / style / security

Manual checks

  • Screen reader tested (UI changes only)
  • New routes added to e2e/a11y.spec.ts, e2e/smoke.spec.ts, sitemap.xml.ts, and README (routes only; sitemap is auto-generated from getStaticPaths, so only static pages need manual entries)
  • UI verified at 375px, 768px, and 1280px against the production build (npm run build && npm run preview) (UI changes only)
  • Re-read every changed file; checked all call sites of any modified exports (all changes)
  • Per-level discussion JSON exists with correct discussionUrl (adventure/level changes only)

… descriptions

The Sync Adventure workflow failed on adventure-accessibility-nightmare with two
unrelated schema errors. Both are fixed here.

**meta_description length no longer fails the build**

- Dropped `.max(160)` from the adventure and level schemas
- `warnIfMetaDescriptionLong` logs the over-run instead, called from
  `renderLevel` and the adventure transform
- Search engines truncate a long description rather than reject it, so this was
  never worth failing a whole sync run over

**Contributors now sync from the challenges repo**

- The adventure designer is read from `contributor:` in `docs/index.yaml`. The
  sync previously kept only one already hand-written into the website YAML, so a
  freshly synced adventure got none
- The challenge builder already flowed through from the level YAML, but
  unfiltered. `pickContributor` now keeps only the four fields the strict content
  schema accepts, on both paths
- A contributor already credited on the website wins over the upstream value at
  both levels, and `mergeLevels` warns when the two diverge rather than dropping
  the divergence silently

The missing designer alongside levels naming their own builder is what tripped
`creditIntegrityError` and produced the second error.

- Tests: `pickContributor`, `buildLevel` and `mergeLevels` credit rules
- Docs: ADVENTURES.md field and preservation tables, sync PR checklist
- Corrected two comments claiming the sync deliberately omits `contributor`

Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-07 10:35 UTC

Follow-up to the review of the previous commit, plus the route-coverage failure
on PR #243.

**Contributor data is now validated, not copied verbatim**

- `contributor.url` is `z.url()` in the content schema, which rejects a bare
  domain like `ksick.dev`. An unvalidated copy failed `npm run sync` in the next
  workflow step, which runs before PR creation, so the run went red with no
  branch to hand-fix. The url is dropped with a warning and the name kept
- `new URL()` is the gate, verified to match `z.url()` on every sample tested
- A present-but-unusable block (no `name`, not an object) now warns instead of
  returning null in silence, which had reported "No contributor found" as fact
  and re-credited the level to the designer via the fallback
- `pickContributor` takes a `where` label so each warning names its source file

**Two failures moved to where they are actionable**

- No designer upstream plus a level naming its own builder tripped
  `creditIntegrityError` during "Validate adventure YAML", before the PR existed.
  `missingDesignerError` now fails the sync early, naming `docs/index.yaml` in
  the challenges repo. A parity test holds it in step with the schema rule
- A designer changed upstream was discarded with neither log branch firing; it
  now warns, matching the level builder

**Challenge tag routes now come from the adventure tags**

- `/challenges/<tag>/` routes are built from adventure `tags`, but the sync
  derived them from level `topics`. Narrowing a level's topics to a subset, which
  the PR checklist invites, left those tags building unregistered routes
- This is what failed route-coverage.spec.ts on #243 for
  `/challenges/accessibility/` and `/challenges/guidepup-virtual-screen-reader/`
- `challengeTagsOf` unions adventure tags with level topics; `tagToSlug` has a
  parity test against `src/lib/challenges.ts`

- Tests: 49 in the sync spec, including three parity guards against the
  TypeScript rules this script has to restate
- Docs: ADVENTURES.md contributor url, early designer failure, routes step

Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
A /challenges/<tag>/ page listed every challenge in any adventure carrying that
tag, including challenges that never touch the tech. `getChallengeData` gave each
entry `adventureTags: a.tags`, and `level.topics` was declared on the type but
never read.

**Three routes were affected, two of them live**

- `/challenges/guidepup-virtual-screen-reader/` (PR #243) showed the beginner
  challenge; Guidepup belongs to the intermediate level, which is not live yet
- `/challenges/python/` and `/challenges/terraform/` had the same defect already

**The fix**

- `ChallengeEntry.adventureTags` becomes `topics`, taken from the level, falling
  back to adventure tags only for a level carrying none
- The tag set is derived from the entries, so a tag exists exactly when some
  challenge teaches it. A tag no live level carries builds no route rather than
  an empty or misleading one, and appears when that level ships
- `challengeTagsOf` in the sync now mirrors this, deriving from level topics.
  Registering an adventure tag would list a route the build never emits and trip
  the drift gate from the other side

**Data**

- Python added to all three the-ai-observatory level topics. It is genuinely
  taught there (6-8 mentions per level) and was simply missing, so the route
  stays and is now correct
- Terraform removed from building-cloudhaven tags. That adventure teaches
  OpenTofu; "Terraform" appeared once, inside an OpenTofu help link. No redirect,
  so the slug stays free for a future adventure that does teach Terraform
- `/challenges/terraform/` dropped from ROUTES_WITHOUT_FULL_COVERAGE

Verified against the built output: /challenges/prometheus/ now shows 1 challenge
rather than all three ai-observatory levels, and every visible card carries the
filtered tag.

Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
@sinduri-g
sinduri-g merged commit 113fd61 into main Sep 7, 2026
10 checks passed
@sinduri-g
sinduri-g deleted the fix/sync-contributor-and-meta-description branch September 7, 2026 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant