Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
178 commits
Select commit Hold shift + click to select a range
44d7079
fix(sitemap): guard catalog-only rebuilds from wiping /tutorials/ URLs
jung-thomas Sep 3, 2026
62e870a
Merge pull request #2126 from sap-tutorials/fix/sitemap-tutorials-guard
jung-thomas Sep 3, 2026
5e62fab
fix(tutorials): support no-step + commented-out-step validation tutor…
jung-thomas Sep 3, 2026
6ff4d01
Merge pull request #2128 from sap-tutorials/worktree-issue-2127-no-st…
jung-thomas Sep 3, 2026
c919eda
fix(api-docs): sap-devs CLI install no longer on npm (#2123)
jung-thomas Sep 3, 2026
6a5b455
Merge pull request #2129 from sap-tutorials/worktree-fix-2123-sap-dev…
jung-thomas Sep 3, 2026
ce4a537
chore(scavenger-hunt): update Ajay + Shilpa clue captions (#2130)
jung-thomas Sep 4, 2026
9262c49
Merge pull request #2132 from sap-tutorials/worktree-issue-2130-scave…
jung-thomas Sep 4, 2026
608bc76
feat(homepage): Devtoberfest banner with live countdown (#2131)
jung-thomas Sep 4, 2026
3e3d9d5
Merge pull request #2134 from sap-tutorials/feat/2131-devtoberfest-ba…
jung-thomas Sep 4, 2026
17a1531
feat(events): per-event name, description & logo on event-display + a…
jung-thomas Sep 4, 2026
4a567b7
Merge pull request #2135 from sap-tutorials/feat/2133-event-page-cust…
jung-thomas Sep 4, 2026
a707180
docs(mcp): use prod client_id sb-tutorials-prod in OAuth quickstart
jung-thomas Sep 4, 2026
480a02f
docs(mcp): pin --host localhost in OAuth quickstart to match redirect…
jung-thomas Sep 4, 2026
63a5811
fix(mcp-oauth): advertise approuter as authorization server (self-iss…
jung-thomas Sep 4, 2026
6f1707a
Merge pull request #2137 from sap-tutorials/fix/mcp-oauth-as-self-issuer
jung-thomas Sep 4, 2026
0c6b0c1
Merge pull request #2136 from sap-tutorials/worktree-mcp-quickstart-p…
jung-thomas Sep 4, 2026
69b5ba1
docs(2138): design spec for standard Reporting-folder reports
jung-thomas Sep 4, 2026
6d69b7f
docs(#2138): implementation plan for standard reports
jung-thomas Sep 4, 2026
f796284
feat(#2138): add TutorialEngagementBase + AuthorTutorialParents repor…
jung-thomas Sep 4, 2026
c15b363
feat(#2138): add AuthorTutorialEngagement view with distinct-user com…
jung-thomas Sep 4, 2026
84402a3
feat(#2138): add AuthorTutorialCompletions row-per-completion view
jung-thomas Sep 4, 2026
a4843b3
feat(#2138): add AuthorSurveyDistribution unpivot view (7 dimensions)
jung-thomas Sep 4, 2026
b92ab9a
feat(#2138): project reporting views on AuthorService + AnalyticsService
jung-thomas Sep 4, 2026
672ad5d
feat(#2138): FE analytical annotations for engagement + completions r…
jung-thomas Sep 4, 2026
b86f711
fix(puzzles): sort admin clue lists by number, not grid position (#2140)
jung-thomas Sep 4, 2026
016d259
fix(#2138): coalesce nullable titles in AuthorTutorialParents parentKey
jung-thomas Sep 4, 2026
88592bb
feat(#2138): Tutorial Engagement FE Analytical List Page component
jung-thomas Sep 4, 2026
602e37c
feat(#2138): Tutorial Completions FE List Report component
jung-thomas Sep 4, 2026
5deab48
feat(#2138): register engagement + completions components in admin shell
jung-thomas Sep 4, 2026
4ee1929
feat(#2138): add three Reporting-folder leaves + FE route/title maps
jung-thomas Sep 4, 2026
8292d24
feat(#2138): survey data access + pure distribution aggregation
jung-thomas Sep 4, 2026
90b6b4d
Merge pull request #2141 from sap-tutorials/worktree-fix-2140-down-cl…
jung-thomas Sep 4, 2026
5685012
feat(#2138): Tutorial Survey Vue report (7 histograms + comments)
jung-thomas Sep 4, 2026
2fc3ad3
docs(channels): design spec for external SAP channels site integration
jung-thomas Sep 4, 2026
71ca301
docs(channels): P1 foundation implementation plan
jung-thomas Sep 4, 2026
81cbf5c
feat(channels): add Channels source-of-truth entity + persistence jou…
jung-thomas Sep 4, 2026
16d6613
fix(channels): add @assert.range to enum columns + assert relatedUrls…
jung-thomas Sep 4, 2026
0dca7c8
feat(channels): normalize module + idempotent re-ingestable seed CLI
jung-thomas Sep 4, 2026
b0cb80b
feat(channels): /build/channels read feed (published, non-broken, par…
jung-thomas Sep 4, 2026
ff4202e
feat(channels): bake /build/channels into hugo/data/channels.json
jung-thomas Sep 4, 2026
44a4ef5
feat(channels): /channels directory page + Vue facet/search island
jung-thomas Sep 4, 2026
d1c93c5
fix(channels): safeJS data-island + combination/exclusion filter tests
jung-thomas Sep 4, 2026
533d8e7
feat(channels): promote featured channels into HomepageShelves (verb-…
jung-thomas Sep 4, 2026
ae1d9b7
fix(channels): uppercase FOCUS_TO_VERB to match HomepageVerb enum
jung-thomas Sep 4, 2026
bffde8f
feat(channels): admin CRUD app + AdminService.Channels projection + s…
jung-thomas Sep 4, 2026
4628297
docs(channels): document channels subsystem + gotcha pointer
jung-thomas Sep 4, 2026
aae1c35
chore(channels): stage regenerated CDS build artifacts
jung-thomas Sep 4, 2026
c28aa67
Merge pull request #2142 from sap-tutorials/channels-integration-p1
jung-thomas Sep 4, 2026
867f3a7
fix(docs): register channels reference page in sidebar
jung-thomas Sep 4, 2026
b44e5e1
Merge pull request #2143 from sap-tutorials/fix/docs-sidebar-channels
jung-thomas Sep 4, 2026
bf0ce3a
feat(devtoberfest): embed promo video in content gap (#2144)
jung-thomas Sep 4, 2026
3e27650
feat(channels): P1 follow-ups — facets, owner badges, feed hardening
jung-thomas Sep 4, 2026
427fa9c
Merge pull request #2145 from sap-tutorials/feat/2144-devtoberfest-pr…
jung-thomas Sep 4, 2026
2018c95
Merge pull request #2147 from sap-tutorials/channels-p1-followups
jung-thomas Sep 4, 2026
c8b8ca8
feat(me): show partial completions in Recent Activity (#2146)
jung-thomas Sep 4, 2026
41136cc
Merge pull request #2148 from sap-tutorials/feat/partial-completions-…
jung-thomas Sep 4, 2026
022ab07
feat(channels): add ChannelCollections + ChannelCollectionItems model…
jung-thomas Sep 4, 2026
707726c
docs(mcp): add Joule Work Desktop MCP connection instructions
jung-thomas Sep 4, 2026
c5e40d7
feat(channels): add /build/channel-collections public feed (P2)
jung-thomas Sep 4, 2026
7306c64
Merge pull request #2149 from sap-tutorials/docs/joule-studio-mcp-qui…
jung-thomas Sep 4, 2026
d7b0a7e
feat(channels): expose ChannelCollections in AdminService (P2)
jung-thomas Sep 4, 2026
40c73f7
feat(channels): add Channel Collections admin app + shell registratio…
jung-thomas Sep 4, 2026
6908fd3
feat(channels): LLM seed pass for editorial collections (P2)
jung-thomas Sep 4, 2026
4f4946f
feat(channels): collections lead the /channels directory landing (P2)
jung-thomas Sep 4, 2026
77e7719
test(channels): e2e nudge for /channels collections (P2)
jung-thomas Sep 4, 2026
c7963f1
fix(#2138): split-grain engagement/completions to stop cross-parent o…
jung-thomas Sep 4, 2026
644deaa
fix(channels): correct Hugo data key for collections + review nits (P2)
jung-thomas Sep 4, 2026
a83bd1d
chore(#2138): remove accidentally-committed SDD scratch report
jung-thomas Sep 4, 2026
1150ca7
Merge pull request #2150 from sap-tutorials/feat/2138-reporting
jung-thomas Sep 4, 2026
0d94f19
Merge pull request #2151 from sap-tutorials/channels-p2-collections
jung-thomas Sep 4, 2026
6516c58
feat(channels): ChannelTopicMap crosswalk model (P3)
jung-thomas Sep 4, 2026
b7176d0
fix(channels): mark canonical slug lookup in seed-collections to unbr…
jung-thomas Sep 4, 2026
18f5303
feat(channels): AdminService ChannelTopicMap projection (P3)
jung-thomas Sep 4, 2026
8d9d4ae
Merge pull request #2152 from sap-tutorials/fix/slug-guard-channels-c…
jung-thomas Sep 4, 2026
3f245a8
feat(channels): Channel Topic Map admin app + shell registration (P3)
jung-thomas Sep 4, 2026
c93547d
feat(channels): LLM seed pass for the topic crosswalk (P3)
jung-thomas Sep 4, 2026
0db1458
feat(channels): related-channels crosswalk in topic payload (P3)
jung-thomas Sep 4, 2026
5b52ec0
feat(channels): render related-channels band on topic pages (P3)
jung-thomas Sep 4, 2026
4e3710e
test(channels): e2e nudge for topic related-channels band (P3)
jung-thomas Sep 4, 2026
b2415df
docs(channels): P3 topic-bands implementation plan
jung-thomas Sep 4, 2026
4040232
Merge pull request #2153 from sap-tutorials/channels-p3-topics
jung-thomas Sep 4, 2026
0c01e31
fix(homepage): Joule purple→pink brand gradient on Devtoberfest banne…
jung-thomas Sep 4, 2026
a1cbb8e
feat(channels): P4 ChannelSubmissions model + persistence journal + m…
jung-thomas Sep 4, 2026
da48777
Merge pull request #2154 from sap-tutorials/feat/2131-joule-gradient
jung-thomas Sep 4, 2026
f4a7562
fix(devtoberfest): unblock promo video (CSP host) + side-by-side layo…
jung-thomas Sep 4, 2026
35bf353
Merge pull request #2155 from sap-tutorials/fix/2144-promo-video-csp-…
jung-thomas Sep 4, 2026
e324e59
feat(channels): P4 login-required ChannelSubmissionService (insert-on…
jung-thomas Sep 4, 2026
3557fe0
feat(channels): P4 AdminService ChannelSubmissions projection + appro…
jung-thomas Sep 4, 2026
0e46e31
fix(#2138): value help + labels on report filters, legible survey charts
jung-thomas Sep 4, 2026
c9c5fea
Merge pull request #2156 from sap-tutorials/fix/2138-report-filters-s…
jung-thomas Sep 4, 2026
ef15b86
feat(channels): P4 admin approve/reject applies proposals to Channels…
jung-thomas Sep 4, 2026
fcd2381
test(channels): P4 add 404 + reject-400 + reviewerId coverage; defens…
jung-thomas Sep 4, 2026
c5db3cf
feat(channels): P4 approuter xsuaa route for /channel-submissions
jung-thomas Sep 4, 2026
6dd97e5
feat(channels): P4 login-gated channel-submit island (csrfFetch + aut…
jung-thomas Sep 4, 2026
7a86b9f
feat(channels): P4 admin moderation-queue FE app + shell registration
jung-thomas Sep 4, 2026
c78f269
test(channels): P4 assert admin-shell registration for channel-submis…
jung-thomas Sep 4, 2026
adf70f6
test(channels): P4 e2e submit-form nudge (self-skips without SMOKE_BA…
jung-thomas Sep 4, 2026
0cba1c3
docs(channels): P4 community-submission implementation plan
jung-thomas Sep 4, 2026
1646abb
Merge pull request #2157 from sap-tutorials/channels-p4-submissions
jung-thomas Sep 4, 2026
6092b75
polish(channels): tighten P4 submit-service contract (405 READ + EDIT…
jung-thomas Sep 4, 2026
e70a3c3
Merge pull request #2158 from sap-tutorials/channels-p4-polish
jung-thomas Sep 4, 2026
6cc7f5d
fix(channels): make seed runnable — normalize.cjs, approx-count coerc…
jung-thomas Sep 5, 2026
57089a5
Merge pull request #2159 from sap-tutorials/fix/channels-seed-normali…
jung-thomas Sep 5, 2026
0bb5f73
feat(nav+channels): shared nav data, two-level menu, palette wiring, …
jung-thomas Sep 5, 2026
e48af47
Merge pull request #2160 from sap-tutorials/feat/channels-admin-and-nav
jung-thomas Sep 5, 2026
2f59f46
feat(nav): add 'About the Knowledge Graph' (/explore/about/) menu item
jung-thomas Sep 5, 2026
c213bf7
Merge pull request #2161 from sap-tutorials/feat/nav-explore-about
jung-thomas Sep 5, 2026
a84c7b1
fix(nav): remember open accordion group, Tutorial Navigator first, fi…
jung-thomas Sep 5, 2026
a5fad92
Merge pull request #2162 from sap-tutorials/feat/nav-menu-improvements
jung-thomas Sep 5, 2026
3de4563
fix(admin): enable list→object navigation for Channels admin components
jung-thomas Sep 5, 2026
6bf4534
Merge pull request #2163 from sap-tutorials/fix/channels-admin-edit-nav
jung-thomas Sep 5, 2026
173e361
fix(admin-ui): restore FE list->object navigation in headless shell
jung-thomas Sep 5, 2026
45bc052
Merge pull request #2164 from sap-tutorials/fix/admin-shell-fe-inner-…
jung-thomas Sep 5, 2026
eb3abf4
docs(channels): design spec for channels hub + 4 data surfaces
jung-thomas Sep 5, 2026
f131509
docs(channels-hub): add phased implementation plans (0-3)
jung-thomas Sep 5, 2026
f23665a
feat(schema): add Channels.slug + feedUrl nullable columns
jung-thomas Sep 5, 2026
7808df8
feat(ingest): add slug+feedUrl fields to Channels normalize + seed loop
jung-thomas Sep 5, 2026
83348e7
chore(deploy): add channels/normalize.cjs to srv-qa cp-list
jung-thomas Sep 5, 2026
b94bfbe
chore(migration): regenerate CHANNELS hdbmigrationtable for slug + fe…
jung-thomas Sep 5, 2026
d009be5
fix(migration): regenerate CHANNELS hdbmigrationtable to version=3 wi…
jung-thomas Sep 5, 2026
c7bca62
fix(channels): keep channel slug stable across re-ingest; null-guard …
jung-thomas Sep 5, 2026
8a700b3
Merge pull request #2165 from sap-tutorials/feat/channels-hub
jung-thomas Sep 5, 2026
7fb0ea9
feat(channels): add hub band with four navigation cards to /channels/…
jung-thomas Sep 5, 2026
f69d6fb
feat(channels): add /build/channels-stats endpoint, fetch script, and…
jung-thomas Sep 5, 2026
5f8a00c
chore(channels): untrack fetched channels-stats.json build artifact
jung-thomas Sep 5, 2026
04732b7
feat(channels): add Hugo health page content and layout
jung-thomas Sep 5, 2026
d1551b9
feat(channels): add channels-health Vue island and register in Vite
jung-thomas Sep 5, 2026
c67c6ae
feat(channels): add Hugo media-diet page content and layout
jung-thomas Sep 5, 2026
51bffb5
feat(channels): add media-diet Vue island and register in Vite
jung-thomas Sep 5, 2026
8d8c40e
test(channels): un-vacuous media-diet 12-cap test + repair /build rou…
jung-thomas Sep 5, 2026
75f8f1c
Merge pull request #2166 from sap-tutorials/feat/channels-hub-phase1
jung-thomas Sep 5, 2026
141d8da
fix(channels): health stats data key — write channels_stats.json (und…
jung-thomas Sep 6, 2026
ef7242e
Merge pull request #2167 from sap-tutorials/fix/channels-stats-data-key
jung-thomas Sep 6, 2026
c30c754
test(crosswalk): pin Direction-1 dark-code regression net for related…
jung-thomas Sep 6, 2026
230913f
feat(crosswalk): add buildChannelDetailPayload for per-channel BLOB p…
jung-thomas Sep 6, 2026
c3c6c00
fix(channels): human labels + clean 404 on infra error in channel-detail
jung-thomas Sep 6, 2026
14c37ea
feat(crosswalk): add renderChannelDetail HTML body renderer for chann…
jung-thomas Sep 6, 2026
bee50f5
fix(channels): reject non-http url schemes in channel-detail render
jung-thomas Sep 6, 2026
07f60e9
feat(crosswalk): add renderChannelsIntoSession publisher for channel …
jung-thomas Sep 6, 2026
3e4d8b4
fix(crosswalk): add 'channel' kind to chrome-shell canonical + breadc…
jung-thomas Sep 6, 2026
03824d0
feat(crosswalk): wire channel-detail build/serve/publish routes in sr…
jung-thomas Sep 6, 2026
a563f96
feat(crosswalk): wire renderChannelsPhase in publish-client and publi…
jung-thomas Sep 6, 2026
b5823a8
feat(crosswalk): add channel-detail catch-all (lookahead-guarded) and…
jung-thomas Sep 6, 2026
e57ede7
chore(srv-qa): add build-channel-detail, channel-detail-render, publi…
jung-thomas Sep 6, 2026
d46bd68
fix(srv-qa): correct cp destinations for channel-detail libs + add to…
jung-thomas Sep 6, 2026
3a47049
feat(media-diet): add signed-in my-picks endpoint with completion→cha…
jung-thomas Sep 6, 2026
d67e31a
feat(media-diet): add OPML/bookmarks/json export endpoint
jung-thomas Sep 6, 2026
7b666e0
chore(phase2): full test pass confirmed; CSS polish for channel-topic…
jung-thomas Sep 6, 2026
ca8667e
fix(channels-hub): canonical topic-link slugs on channel pages; hoist…
jung-thomas Sep 6, 2026
e242b9e
Merge pull request #2168 from sap-tutorials/feat/channels-hub-phase2-…
jung-thomas Sep 6, 2026
42ddc88
feat(channels-atlas): add buildAtlasChannels pure transformation
jung-thomas Sep 6, 2026
b4f877a
feat(channels-atlas): add /build/channel-atlas endpoint + xs-app.json…
jung-thomas Sep 6, 2026
3540a46
feat(channels-atlas): add pure graph functions (sizeChannel, ownerTyp…
jung-thomas Sep 6, 2026
122ff24
feat(channels-atlas): scaffold SPA (package.json, vite, tsconfig, typ…
jung-thomas Sep 6, 2026
c00f479
feat(channels-atlas): add useAtlasData composable (inline JSON + fetc…
jung-thomas Sep 6, 2026
05267ac
feat(channels-atlas): add AtlasGraph.vue (Sigma + graphology + ForceA…
jung-thomas Sep 6, 2026
4e192e6
feat(channels-atlas): add App.vue, OwnerTypeFilter, ChannelDetailPane…
jung-thomas Sep 6, 2026
8648644
fix(channel-atlas): render topicTags, keep filter visible in empty st…
jung-thomas Sep 6, 2026
8cf6fcb
feat(channels-atlas): add build-channel-atlas-manifest + fetch-channe…
jung-thomas Sep 6, 2026
f6cd30d
feat(channels-atlas): add Hugo layout + content for /channels/atlas/
jung-thomas Sep 6, 2026
7fa7c60
feat(channels-atlas): wire MTA, package.json scripts, build:all, vite…
jung-thomas Sep 6, 2026
10f5113
fix(channels-atlas): surface build-time payload error instead of empt…
jung-thomas Sep 6, 2026
d955014
fix(ci): install app/channel-atlas deps in unit-tests setup
jung-thomas Sep 6, 2026
91e3df5
Merge pull request #2169 from sap-tutorials/feat/channels-hub-phase3-…
jung-thomas Sep 6, 2026
0d3a51f
fix(ci): allowlist GET /content/channel-detail/:slug as srv-only route
jung-thomas Sep 6, 2026
a7ebcf6
Merge pull request #2170 from sap-tutorials/worktree-fix-channel-deta…
jung-thomas Sep 6, 2026
18c37d5
fix(channels): chunk ChannelTopicMap AI seed to avoid token-cap zero-…
jung-thomas Sep 6, 2026
3b31afe
Merge pull request #2171 from sap-tutorials/fix/channels-topic-map-se…
jung-thomas Sep 6, 2026
f86a09a
fix(ci): mark pre-canonicalized slug lookup in build-channel-detail
jung-thomas Sep 6, 2026
d0c5c92
fix(channels): hub UX — drop dead crosswalk card, rework media diet, …
jung-thomas Sep 6, 2026
5ec80e1
Merge pull request #2172 from sap-tutorials/fix/slug-guard-channel-de…
jung-thomas Sep 6, 2026
9b965a7
Merge pull request #2173 from sap-tutorials/feat/channels-hub-ux
jung-thomas Sep 6, 2026
e990758
fix(channel-atlas): recover from double-encoded inline payload (#2174)
jung-thomas Sep 6, 2026
b0cb989
fix(channel-atlas): consume site theme vars for dark-mode legibility
jung-thomas Sep 6, 2026
187d255
Merge pull request #2175 from sap-tutorials/fix/atlas-dark-mode-theming
jung-thomas Sep 6, 2026
d724871
chore(deploy): bump MTA version to 1.21.1 for atlas dark-mode fix
jung-thomas Sep 6, 2026
1780760
chore(release): update What's New digest + bump MTA version to 1.22.0
jung-thomas Sep 6, 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: 11 additions & 3 deletions .deploy/mta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ID: tutorials-ims
# Bump this on each release you deploy — it's the version shown by `cf mtas`
# and in the mtar filename (tutorials-ims_<version>.mtar). Deploy is manual:
# `cd .deploy && mbt build && cf deploy mta_archives/tutorials-ims_<version>.mtar -e ../deploy/<env>.mtaext -f`.
version: 1.21.0
version: 1.22.0

# Top-level parameters (overridable per-env via deploy/<env>.mtaext).
parameters:
Expand Down Expand Up @@ -55,6 +55,12 @@ build-parameters:
- bash -c "cd .. && npm --prefix app/explore install --no-audit --no-fund"
- bash -c "cd .. && npm --prefix app/explore run build"
- bash -c "cd .. && npx tsx scripts/build-explore-manifest.ts app/explore/dist hugo/data/explore_bundle.json"
# Build app/channel-atlas + emit the bundle manifest into hugo/data/.
# Hugo reads site.Data.channel_atlas_bundle in
# hugo/layouts/channels/atlas.html to inject hashed JS/CSS filenames.
- bash -c "cd .. && npm --prefix app/channel-atlas install --no-audit --no-fund"
- bash -c "cd .. && npm --prefix app/channel-atlas run build"
- bash -c "cd .. && npx tsx scripts/build-channel-atlas-manifest.ts app/channel-atlas/dist hugo/data/channel_atlas_bundle.json"
- cp ../xs-security.json .
# Prod-only XSUAA descriptor: distinct xsappname (tutorials-prod) +
# ' (Prod)'-suffixed role-collection names so the prod xsuaa can coexist
Expand Down Expand Up @@ -172,7 +178,7 @@ modules:
- cp -r ../../hugo/assets ./hugo/assets
- cp -r ../../hugo/data ./hugo/data
- cp -r ../../hugo/i18n ./hugo/i18n
- bash -c "mkdir -p srv/jobs && mkdir -p srv/handlers && mkdir -p srv/lib/branch && mkdir -p srv/lib/runtime-config && mkdir -p srv/lib/prompts && mkdir -p srv/lib/kg && mkdir -p srv/mcp/prompts && cp ../../srv/lib/branch/condition.js ../../srv/lib/branch/engine.js ../../srv/lib/branch/ranker.js ../../srv/lib/branch/user-state.js ../../srv/lib/branch/loaders.js ../../srv/lib/branch/mission-detail.js ../../srv/lib/branch/slug-key.js ../../srv/lib/branch/decide.js ../../srv/lib/branch/joule-tool.js ../../srv/lib/branch/branch-telemetry.js ../../srv/lib/branch/group-by-alt.js ../../srv/lib/branch/profile-fields.js ../../srv/lib/branch/profile-override.js srv/lib/branch/ && cp ../../srv/lib/runtime-config/kg-settings.js ../../srv/lib/runtime-config/ui-events-settings.js ../../srv/lib/runtime-config/search-settings.js ../../srv/lib/runtime-config/navigator-settings.js ../../srv/lib/runtime-config/display-settings.js ../../srv/lib/runtime-config/tenant-settings.js ../../srv/lib/runtime-config/alert-settings.js srv/lib/runtime-config/ && cp ../../srv/lib/kg/on-demand-enqueue.js ../../srv/lib/kg/on-demand-cosine-rank.js srv/lib/kg/ && cp ../../srv/lib/credstore.js ../../srv/lib/secret-resolver.js ../../srv/lib/content-store.js ../../srv/lib/content-delta-flags.js ../../srv/lib/content-cache-coherence.js ../../srv/lib/edge-cache-headers.js ../../srv/lib/content-publish-session.js ../../srv/lib/resolve-tutorial-author.js ../../srv/lib/_tutorials-table.js ../../srv/lib/catalog-renderer.js ../../srv/lib/catalog-data.js ../../srv/lib/catalog-mission-hierarchy.js ../../srv/lib/chrome-shell.js ../../srv/lib/pipeline-log.js ../../srv/lib/legacy-id.js ../../srv/lib/embedding-pipeline.js ../../srv/lib/step-text-extractor.js ../../srv/lib/embedding-client.js ../../srv/lib/step-vectors.js ../../srv/lib/user-progress.js ../../srv/lib/co-completion.js ../../srv/lib/tutorial-centroid.js ../../srv/lib/tag-label-map.js ../../srv/lib/code-check-tool.js ../../srv/lib/code-check-prompt.js ../../srv/lib/code-check-handler.js ../../srv/lib/code-check-llm.js ../../srv/lib/code-check-step-loader.js ../../srv/lib/code-check-spec-publish.js ../../srv/lib/validate-answer-spec-publish.js ../../srv/lib/category-classifier.js ../../srv/lib/category-classifier-llm.js ../../srv/lib/category-seed-embeddings.js ../../srv/lib/build-catalog-categories.js ../../srv/lib/chat-settings-resolver.js ../../srv/lib/kg-extract.js ../../srv/lib/kg-queries.js ../../srv/lib/kg-projection.js ../../srv/lib/kg-similarity.js ../../srv/lib/kg-cycles.js ../../srv/lib/kg-graph-rebuild.js ../../srv/lib/kg-sparql-client.js ../../srv/lib/kg-merge-pair.js ../../srv/lib/kg-concept-loader.js ../../srv/lib/kg-neighborhood-cache.js ../../srv/lib/kg-neighborhood-merge.js ../../srv/lib/kg-neighborhood-full-helpers.js ../../srv/lib/kg-other-resources-loader.js ../../srv/lib/kg-stamp-meta-text.js ../../srv/lib/kg-tutorial-teaches-map.js ../../srv/lib/kg-resource-type-config.js ../../srv/lib/kg-meta-formatters.js ../../srv/lib/discovery-mission-categories.js ../../srv/lib/external-content-ttl.js ../../srv/lib/recompute-tutorial-progress-bulk-sql.js ../../srv/lib/youtube-fetcher.js ../../srv/lib/homepage-events-merger.js ../../srv/lib/homepage-rss-fetcher.js ../../srv/lib/rss-parse.js ../../srv/lib/community-blogs-fetcher.js ../../srv/lib/community-blog-source-defaults.js ../../srv/lib/community-blogs-classifier.js ../../srv/lib/safe-fetch.js ../../srv/lib/curl-transport.js ../../srv/lib/khoros-transport.js ../../srv/lib/explainer-generator.js ../../srv/lib/_token-cost.js ../../srv/lib/metrics.js ../../srv/lib/alerting.js ../../srv/lib/relevance-classifier.js ../../srv/lib/relevance-seed-embeddings.js ../../srv/lib/relevance-keyword-rules.js ../../srv/lib/canonicalize-link.js ../../srv/lib/detect-language-en.js ../../srv/lib/kg-community-coverage.js ../../srv/lib/page-key-map.js ../../srv/lib/page-fallback.js ../../srv/lib/task-record-submission-id.js ../../srv/lib/image-store.cjs ../../srv/lib/image-ingest.cjs ../../srv/lib/image-source-handler.js ../../srv/lib/img-cdn-fetch.cjs ../../srv/lib/img-cdn-retry.cjs ../../srv/lib/image-warm-utils.js ../../srv/lib/attachment-store.cjs ../../srv/lib/attachment-ingest.cjs ../../srv/lib/attachment-mime.cjs ../../srv/lib/attachment-warm-utils.js ../../srv/lib/attachment-source-handler.js ../../srv/lib/attachment-ingest-handler.js ../../srv/lib/contributors-publish.js ../../srv/lib/validation-rules-publish.js ../../srv/lib/island-manifest.json srv/lib/ && mkdir -p srv/lib/feature-flags && cp ../../srv/lib/feature-flags/db-flags.js ../../srv/lib/feature-flags/registry.js srv/lib/feature-flags/ && cp ../../srv/handlers/categories-after-hooks.js ../../srv/handlers/completion-path-items-altgroup.js srv/handlers/ && mkdir -p srv && cp ../../srv/content-moderation-service.js srv/ && cp ../../srv/jobs/consolidate-concepts-job.js ../../srv/jobs/extract-concepts-job.js ../../srv/jobs/job-lock.js ../../srv/jobs/secret-expiry-check.js ../../srv/jobs/homepage-link-health.js ../../srv/jobs/kg-ondemand-job.js ../../srv/jobs/community-blogs-fetch-job.js ../../srv/jobs/community-blogs-classify-job.js ../../srv/jobs/fetch-news-job.js srv/jobs/ && cp ../../srv/lib/prompts/explainer-verb.md ../../srv/lib/prompts/explainer-shelf.md ../../srv/lib/prompts/explainer-shelf-entry.md ../../srv/lib/prompts/community-blogs-classifier.md srv/lib/prompts/ && cp ../../srv/mcp/prompts/summarize_mission_for_beginner.md ../../srv/mcp/prompts/generate_lab_exercise.md ../../srv/mcp/prompts/explain_concept.md ../../srv/mcp/prompts/suggest_learning_path.md srv/mcp/prompts/"
- bash -c "mkdir -p srv/jobs && mkdir -p srv/handlers && mkdir -p srv/lib/branch && mkdir -p srv/lib/runtime-config && mkdir -p srv/lib/prompts && mkdir -p srv/lib/kg && mkdir -p srv/mcp/prompts && cp ../../srv/lib/branch/condition.js ../../srv/lib/branch/engine.js ../../srv/lib/branch/ranker.js ../../srv/lib/branch/user-state.js ../../srv/lib/branch/loaders.js ../../srv/lib/branch/mission-detail.js ../../srv/lib/branch/slug-key.js ../../srv/lib/branch/decide.js ../../srv/lib/branch/joule-tool.js ../../srv/lib/branch/branch-telemetry.js ../../srv/lib/branch/group-by-alt.js ../../srv/lib/branch/profile-fields.js ../../srv/lib/branch/profile-override.js srv/lib/branch/ && cp ../../srv/lib/runtime-config/kg-settings.js ../../srv/lib/runtime-config/ui-events-settings.js ../../srv/lib/runtime-config/search-settings.js ../../srv/lib/runtime-config/navigator-settings.js ../../srv/lib/runtime-config/display-settings.js ../../srv/lib/runtime-config/tenant-settings.js ../../srv/lib/runtime-config/alert-settings.js srv/lib/runtime-config/ && cp ../../srv/lib/kg/on-demand-enqueue.js ../../srv/lib/kg/on-demand-cosine-rank.js srv/lib/kg/ && cp ../../srv/lib/credstore.js ../../srv/lib/secret-resolver.js ../../srv/lib/content-store.js ../../srv/lib/content-delta-flags.js ../../srv/lib/content-cache-coherence.js ../../srv/lib/edge-cache-headers.js ../../srv/lib/content-publish-session.js ../../srv/lib/resolve-tutorial-author.js ../../srv/lib/_tutorials-table.js ../../srv/lib/catalog-renderer.js ../../srv/lib/catalog-data.js ../../srv/lib/catalog-mission-hierarchy.js ../../srv/lib/chrome-shell.js ../../srv/lib/pipeline-log.js ../../srv/lib/legacy-id.js ../../srv/lib/embedding-pipeline.js ../../srv/lib/step-text-extractor.js ../../srv/lib/embedding-client.js ../../srv/lib/step-vectors.js ../../srv/lib/user-progress.js ../../srv/lib/co-completion.js ../../srv/lib/tutorial-centroid.js ../../srv/lib/tag-label-map.js ../../srv/lib/code-check-tool.js ../../srv/lib/code-check-prompt.js ../../srv/lib/code-check-handler.js ../../srv/lib/code-check-llm.js ../../srv/lib/code-check-step-loader.js ../../srv/lib/code-check-spec-publish.js ../../srv/lib/validate-answer-spec-publish.js ../../srv/lib/category-classifier.js ../../srv/lib/category-classifier-llm.js ../../srv/lib/category-seed-embeddings.js ../../srv/lib/build-catalog-categories.js ../../srv/lib/chat-settings-resolver.js ../../srv/lib/kg-extract.js ../../srv/lib/kg-queries.js ../../srv/lib/kg-projection.js ../../srv/lib/kg-similarity.js ../../srv/lib/kg-cycles.js ../../srv/lib/kg-graph-rebuild.js ../../srv/lib/kg-sparql-client.js ../../srv/lib/kg-merge-pair.js ../../srv/lib/kg-concept-loader.js ../../srv/lib/kg-neighborhood-cache.js ../../srv/lib/kg-neighborhood-merge.js ../../srv/lib/kg-neighborhood-full-helpers.js ../../srv/lib/kg-other-resources-loader.js ../../srv/lib/kg-stamp-meta-text.js ../../srv/lib/kg-tutorial-teaches-map.js ../../srv/lib/kg-resource-type-config.js ../../srv/lib/kg-meta-formatters.js ../../srv/lib/discovery-mission-categories.js ../../srv/lib/external-content-ttl.js ../../srv/lib/recompute-tutorial-progress-bulk-sql.js ../../srv/lib/youtube-fetcher.js ../../srv/lib/homepage-events-merger.js ../../srv/lib/homepage-rss-fetcher.js ../../srv/lib/rss-parse.js ../../srv/lib/community-blogs-fetcher.js ../../srv/lib/community-blog-source-defaults.js ../../srv/lib/community-blogs-classifier.js ../../srv/lib/safe-fetch.js ../../srv/lib/curl-transport.js ../../srv/lib/khoros-transport.js ../../srv/lib/explainer-generator.js ../../srv/lib/_token-cost.js ../../srv/lib/metrics.js ../../srv/lib/alerting.js ../../srv/lib/relevance-classifier.js ../../srv/lib/relevance-seed-embeddings.js ../../srv/lib/relevance-keyword-rules.js ../../srv/lib/canonicalize-link.js ../../srv/lib/detect-language-en.js ../../srv/lib/kg-community-coverage.js ../../srv/lib/page-key-map.js ../../srv/lib/page-fallback.js ../../srv/lib/task-record-submission-id.js ../../srv/lib/image-store.cjs ../../srv/lib/image-ingest.cjs ../../srv/lib/image-source-handler.js ../../srv/lib/img-cdn-fetch.cjs ../../srv/lib/img-cdn-retry.cjs ../../srv/lib/image-warm-utils.js ../../srv/lib/attachment-store.cjs ../../srv/lib/attachment-ingest.cjs ../../srv/lib/attachment-mime.cjs ../../srv/lib/attachment-warm-utils.js ../../srv/lib/attachment-source-handler.js ../../srv/lib/attachment-ingest-handler.js ../../srv/lib/contributors-publish.js ../../srv/lib/validation-rules-publish.js ../../srv/lib/topics-query.js ../../srv/lib/topic-slug.js ../../srv/lib/tag-md-format.js ../../srv/lib/publish-channels.js ../../srv/lib/media-diet-picks.js ../../srv/lib/media-diet-export.js ../../srv/lib/build-channel-detail.js ../../srv/lib/channel-detail-render.js ../../srv/lib/build-channel-atlas.js ../../srv/lib/island-manifest.json srv/lib/ && mkdir -p srv/lib/channels && cp ../../srv/lib/channels/normalize.cjs srv/lib/channels/ && mkdir -p srv/lib/feature-flags && cp ../../srv/lib/feature-flags/db-flags.js ../../srv/lib/feature-flags/registry.js srv/lib/feature-flags/ && cp ../../srv/handlers/categories-after-hooks.js ../../srv/handlers/completion-path-items-altgroup.js srv/handlers/ && mkdir -p srv && cp ../../srv/content-moderation-service.js srv/ && cp ../../srv/jobs/consolidate-concepts-job.js ../../srv/jobs/extract-concepts-job.js ../../srv/jobs/job-lock.js ../../srv/jobs/secret-expiry-check.js ../../srv/jobs/homepage-link-health.js ../../srv/jobs/kg-ondemand-job.js ../../srv/jobs/community-blogs-fetch-job.js ../../srv/jobs/community-blogs-classify-job.js ../../srv/jobs/fetch-news-job.js srv/jobs/ && cp ../../srv/lib/prompts/explainer-verb.md ../../srv/lib/prompts/explainer-shelf.md ../../srv/lib/prompts/explainer-shelf-entry.md ../../srv/lib/prompts/community-blogs-classifier.md srv/lib/prompts/ && cp ../../srv/mcp/prompts/summarize_mission_for_beginner.md ../../srv/mcp/prompts/generate_lab_exercise.md ../../srv/mcp/prompts/explain_concept.md ../../srv/mcp/prompts/suggest_learning_path.md srv/mcp/prompts/"
- bash -c "node -e \"const p=require('./package.json'); p.dependencies=Object.assign(p.dependencies||{},{cheerio:'^1.2.0','@sap-ai-sdk/foundation-models':'^2.10.0'}); require('fs').writeFileSync('./package.json', JSON.stringify(p,null,2));\""
properties:
EXPOSE_CAP_UI: false
Expand Down Expand Up @@ -205,7 +211,7 @@ modules:
# Wipe each static dir BEFORE cp'ing fresh content. Hugo public, qa, admin-ui,
# analytics-ui, scanner-ui all need this; everything not under static/ here
# (e.g. node_modules, package.json) is preserved.
- rm -rf static/admin-ui static/analytics-ui static/scanner-ui static/explore-ui static/data-inspector-ui static/qa
- rm -rf static/admin-ui static/analytics-ui static/scanner-ui static/explore-ui static/channel-atlas-ui static/data-inspector-ui static/qa
# CAP-sourced Hugo sections (concepts, developer-advocates, browse) are
# generated at build time from /build/* endpoints. Because `cp -r` is
# union (see comment above), a build against a backend with FEWER rows
Expand All @@ -230,6 +236,8 @@ modules:
- cp -r ../app/analytics-explorer/dist/. static/analytics-ui/
- mkdir -p static/explore-ui
- cp -r ../app/explore/dist/. static/explore-ui/
- mkdir -p static/channel-atlas-ui
- cp -r ../app/channel-atlas/dist/. static/channel-atlas-ui/
- cp -r ../app/scanner/webapp static/scanner-ui
# Display App (event-monitor dashboard) — Vue 3 + Vite, base '/display-app/'.
# Served from static/display-app via the /display-app/ approuter route. This
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/rebuild-content.yml
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,36 @@ jobs:
- name: Build Hugo site
run: /tmp/hugo --source hugo --minify

# Preserve /sitemap.xml across catalog-only rebuilds (same wipe class as
# /browse/ + /authors/ above; reported 2026-09-03 by the Intelligent Search
# Data Crawling team). /sitemap.xml is served from the HANA `page-sitemap.xml`
# blob and publish-content.ts republishes it on every non-slug rebuild.
# catalog-only skips "Fetch tutorials", so the Hugo build just above bakes a
# sitemap with NO /tutorials/ URLs — publishing that would wipe the live
# sitemap to ~180 links. The sitemap can't be regenerated here (it needs the
# ~1.4k tutorial pages the skipped GitHub fetch provides), so — UNLIKE the
# browse/author preserve steps, which re-hydrate build INPUTS before the
# build — this runs AFTER the build and overwrites the freshly-baked sitemap
# with the one the approuter is CURRENTLY serving. Fails the run (non-zero)
# rather than ship a wiped sitemap if the deployed one is unreadable or names
# zero tutorials. Not needed in `full` (regenerates it) or `slug-targeted`
# (page-sitemap.xml is not republished).
- name: Preserve sitemap.xml for catalog-only rebuild
if: ${{ steps.mode.outputs.effective_mode == 'catalog-only' }}
env:
APPROUTER_URL: ${{ steps.url.outputs.approuter_url }}
run: npx tsx scripts/seed-sitemap-from-deployed.ts

# Fail-closed net for the sitemap wipe class. Runs in the modes that
# republish the page-sitemap.xml blob (full + catalog-only; slug-targeted
# does not touch it). Fails BEFORE the HANA publish if the sitemap about to
# be published names zero /tutorials/ URLs — whatever the cause (broken
# preserve step, a future fetch-skipping mode, a bad Hugo build). A red run
# is recoverable (re-run mode=full); a silently wiped sitemap is the incident.
- name: Guard - sitemap includes tutorial URLs
if: ${{ steps.mode.outputs.effective_mode != 'slug-targeted' }}
run: node scripts/check-sitemap-tutorials.cjs --hugo-dir hugo/public

# [#1657] Restore CDS syntax highlighting to the runtime-push path. Hugo's
# render-codeblock.html maps ```cds → the Chroma SQL lexer as a PLACEHOLDER
# (Chroma has no CDS lexer) and tags the wrapper `data-lang=cds`; the SQL
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ on:
# never lands unnoticed. Closes the PR-gate half of #961.
#
# The vitest `unit` project uses in-memory SQLite and does not need a HANA
# binding or CF login. `npm run setup` installs the nested `hugo-apps` and
# `app/explore` workspaces and rebuilds `better-sqlite3` — both are required
# by the unit suite and are otherwise silently skipped by the org-wide
# `npm config ignore-scripts=true` policy.
# binding or CF login. `npm run setup` installs the nested `hugo-apps`,
# `app/explore`, and `app/channel-atlas` workspaces and rebuilds
# `better-sqlite3` — all are required by the unit suite and are otherwise
# silently skipped by the org-wide `npm config ignore-scripts=true` policy.

jobs:
unit:
Expand Down Expand Up @@ -42,7 +42,7 @@ jobs:
run: npm ci --no-audit --no-fund
env:
NODE_AUTH_TOKEN: ${{ secrets.PACKAGES_READ_TOKEN || secrets.GITHUB_TOKEN }}
- name: Setup nested workspaces (hugo-apps, app/explore) + rebuild native bindings
- name: Setup nested workspaces (hugo-apps, app/explore, app/channel-atlas) + rebuild native bindings
run: npm run setup
- name: Run unit tests
run: npm test
Expand Down
Loading
Loading