Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 1 deletion .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.41.1
version: 1.41.2

# Top-level parameters (overridable per-env via deploy/<env>.mtaext).
parameters:
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/rebuild-content-qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,22 @@ jobs:
- name: Build island fingerprint manifest
run: npm run build:island-manifest

# Generated CSS (#2896 follow-up, mirrors rebuild-content.yml). Commit
# ac6b7e39f stopped committing sap-fundamental.css (build:css, postcss)
# and fundamental-styles-icon.css (build:icon-subset) — both are now
# .gitignored build outputs. head.html does `resources.Get | minify` on
# the icon subset, so on a clean CI checkout where the file is absent the
# QA Hugo build fails at head.html:27 ("wrong type ...; got
# resource.Resource"). This workflow drives /tmp/hugo directly rather than
# `npm run build:all`, so — like the feed fetchers above — it must
# regenerate them BEFORE the Hugo build. build:css + build:icon-subset
# produce byte-identical output to the deploy's build:all, so QA and prod
# agree on the fingerprint. (QA regression #2912.)
- name: Build fingerprinted CSS (sap-fundamental + icon subset)
run: |
npm run build:icon-subset
npm run build:css

- name: Build QA Hugo site
# Hugo was downloaded to /tmp/hugo (line 44). The build:qa npm script
# invokes 'hugo' (bare binary name) — works locally where hugo is
Expand Down
17 changes: 17 additions & 0 deletions docs/developers/operations/mta-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,3 +627,20 @@ the static first rather than swapping. Override the derived idle URL with
`IDLE_APPROUTER_URL` if the `-idle` naming ever changes. CI mirrors this as a
non-gating post-deploy step in the `smoke-test` job (CI prod uses
`--skip-testing-phase`, so it probes the live approuter after the auto-swap).

### The two rebuild-content workflows must stay in parity on build-output steps (2026-10-25 QA-head break)

Hugo's `resources.Get` in [`hugo/layouts/partials/head.html`](../../../hugo/layouts/partials/head.html) reads CSS that is **generated, not committed** — several build outputs under `hugo/assets/css/` are `.gitignored`, so a clean checkout does not have them until a build step produces them. The two content-rebuild workflows each drive `/tmp/hugo` **directly** (not `npm run build:all`, which would chain every generator), so each workflow must list the generator steps explicitly — and the two lists must match.

They drifted: `rebuild-content.yml` (PROD) had a **"Build fingerprinted CSS (sap-fundamental + icon subset)"** step (`npm run build:icon-subset` → `fundamental-styles-icon.css`; `npm run build:css` → `sap-fundamental.css`) ahead of its Hugo build, but `rebuild-content-qa.yml` (QA) was never given it. A clean QA checkout therefore had no `fundamental-styles-icon.css`, and the QA Hugo build died at `head.html:27` (`resources.Get "css/fundamental-styles-icon.css"` → nil). PROD was unaffected because its workflow generated the file first.

**Why:** `npm run build:all` chains `build:island-manifest`, `build:icon-subset`, `build:css`, `build:highlight`, etc. The rebuild workflows bypass that chain for speed/control, so every gitignored build output the Hugo layouts reference has to be regenerated by an explicit named step in **both** workflows. Omit one in one workflow and only that channel breaks — invisibly, because the other channel still works.

**How to apply:**

- **Mirror build-output steps across both workflows.** Any step that generates a gitignored Hugo build input added to `rebuild-content.yml` MUST be added to `rebuild-content-qa.yml` (and vice-versa), in the same position relative to the Hugo build. The QA Hugo build runs against `dataDir=data-qa` (hugo.qa.toml) which **replaces** the data root, so island-manifest/CSS outputs must be present before `build:qa` just as they are before PROD's Hugo build.
- **Gitignored Hugo build inputs that need an explicit generator step** (grep `.gitignore` for the authoritative list; as of 2026-10-25):
- `hugo/assets/css/fundamental-styles-icon.css` → `npm run build:icon-subset`
- `hugo/assets/css/sap-fundamental.css` → `npm run build:css`
- `hugo/data/island_manifest.json` → `npm run build:island-manifest` (+ `npm --prefix hugo-apps run build` for the Vite bundles)
- **Local/operator deploys are covered already:** `npm run deploy` runs `npm run build:deploy` → `build:all`, which chains all generators, and `deploy-mta.cjs` Steps 2.5/2.7/3.6 guard the island-manifest + QA navigator outputs. The drift only bites the **CI rebuild workflows**, which don't call `build:all`. There is no guard that cross-checks the two workflows' step lists, so parity is a review-time discipline — diff the two files' Hugo-build preamble when touching either.
41 changes: 40 additions & 1 deletion hugo/data/whats_new.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"generatedAt": "2026-10-25T11:43:41.582Z",
"generatedAt": "2026-10-25T12:04:13.836Z",
"repos": [
{
"key": "tutorials-ims",
Expand All @@ -8,6 +8,45 @@
}
],
"entries": [
{
"id": "tutorials-ims#2918",
"repo": "tutorials-ims",
"label": "Developer Portal",
"number": 2918,
"title": "docs: record QA/PROD rebuild-workflow parity rule (follow-up to #2917)",
"summary": "Documented the parity rule that keeps the QA and production content-rebuild pipelines generating identical CSS, preventing a class of build break.",
"category": "Maintenance",
"mergedAt": "2026-10-25T11:59:44Z",
"week": "2026-W43",
"weekStart": "2026-10-19",
"url": "https://github.com/sap-tutorials/tutorials-ims/pull/2918"
},
{
"id": "tutorials-ims#2917",
"repo": "tutorials-ims",
"label": "Developer Portal",
"number": 2917,
"title": "QA tutorial previews build and style correctly again",
"summary": "The QA author-preview channel now regenerates its icon and base CSS before building, so author previews render with full styling instead of failing the build.",
"category": "Fix",
"mergedAt": "2026-10-25T11:53:50Z",
"week": "2026-W43",
"weekStart": "2026-10-19",
"url": "https://github.com/sap-tutorials/tutorials-ims/pull/2917"
},
{
"id": "tutorials-ims#2916",
"repo": "tutorials-ims",
"label": "Developer Portal",
"number": 2916,
"title": "release v1.41.1 DEV to main promotion",
"summary": "Release 1.41.1 promoted the prior window of fixes from DEV to the production branch.",
"category": "Maintenance",
"mergedAt": "2026-10-25T11:44:57Z",
"week": "2026-W43",
"weekStart": "2026-10-19",
"url": "https://github.com/sap-tutorials/tutorials-ims/pull/2916"
},
{
"id": "tutorials-ims#2915",
"repo": "tutorials-ims",
Expand Down
2 changes: 1 addition & 1 deletion mta-mcp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ _schema-version: 3.3.0
# This file lives at repo root → path: gen/srv-mcp (root-relative, no ../).
# before-all runs from ROOT (no cd ..) — mbt uses the descriptor's directory as cwd.
ID: tutorials-mcp
version: 1.1.1
version: 1.1.2

# Destinations are subaccount-level, so DEV and PROD (sharing one subaccount)
# need DISTINCT destination names. `dest-main-srv` defaults to the PROD name;
Expand Down
Loading