diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 926dd2b..04fddef 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -17,6 +17,7 @@ concurrency: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -61,6 +62,7 @@ jobs: deploy: needs: build runs-on: ubuntu-latest + timeout-minutes: 15 environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/docs/.verify-refs-ignore b/docs/.verify-refs-ignore index c9d2a68..3a61d4d 100644 --- a/docs/.verify-refs-ignore +++ b/docs/.verify-refs-ignore @@ -28,3 +28,10 @@ ClassName # literal placeholder in the URL-parameter description z2ui5_cl_xml_view # upstream's retired view builder — replaced here by z2ui5_cl_ui5_view_builder z2ui5_cl_xml_view_cc # its custom-control decorator, retired with it z2ui5_cl_pop_bal # one of upstream's frozen built-in popups, superseded by the popups add-on + +# --- release numbers that are NOT the pinned framework release -------------- +# The pin itself (1.142.0 today) is read from the checkout and never listed +# here — listing it would keep the old number green after a pin move, which +# is the one defect the release check exists to catch. +1.143.0 # the upstream release where _bind/_bind_edit merged — history, stays true whatever the pin says +1.113.0 # the OpenUI5 release served locally — a UI5 number, not a framework release diff --git a/docs/guide/samples.md b/docs/guide/samples.md index 2dfdc59..3e4929f 100644 --- a/docs/guide/samples.md +++ b/docs/guide/samples.md @@ -3,7 +3,7 @@ # Sample Catalogue -The framework ships 104 sample apps in `core/srv/app/samples/` — the abap2UI5 demo collection, transpiled to JavaScript. 97 of them are listed in the built-in gallery, and this page is that gallery's own table: it is generated from `z2ui5_cl_smp_app_000`, the sample browser the framework itself renders, so it cannot drift from what the playground offers. +The framework ships 105 sample apps in `core/srv/app/samples/` — the abap2UI5 demo collection, transpiled to JavaScript. 98 of them are listed in the built-in gallery, and this page is that gallery's own table: it is generated from `z2ui5_cl_smp_app_000`, the sample browser the framework itself renders, so it cannot drift from what the playground offers. Every title links into the [browser playground](./playground) — no install, no server. The same apps run on your own CAP server under the same names: `?app_start=`, or `client.nav_app_call()` from an app of your own. @@ -29,6 +29,7 @@ Two markers are carried over from the upstream gallery: **(A)** marks a sample t | Sample | Class | Topics | |---|---|---| +| [A View Built From RTTI, No Field Named](https://cap2ui5.github.io/web-cap2UI5-build/?app_start=z2ui5_cl_smp_app_497) | [`z2ui5_cl_smp_app_497`](https://github.com/cap2UI5/cap2UI5/blob/main/core/srv/app/samples/z2ui5_cl_smp_app_497.js) | rtti generic view runtime columns get_components describe_by_data no field name itab structure column cell binding | | [Currency Amounts (sap.ui.model.type.Currency)](https://cap2ui5.github.io/web-cap2UI5-build/?app_start=z2ui5_cl_smp_app_067) | [`z2ui5_cl_smp_app_067`](https://github.com/cap2UI5/cap2UI5/blob/main/core/srv/app/samples/z2ui5_cl_smp_app_067.js) | amount decimals leading zeros number format | | [Dynamic Table Typed at Runtime (RTTI)](https://cap2ui5.github.io/web-cap2UI5-build/?app_start=z2ui5_cl_smp_app_061) | [`z2ui5_cl_smp_app_061`](https://github.com/cap2UI5/cap2UI5/blob/main/core/srv/app/samples/z2ui5_cl_smp_app_061.js) | generic data reference create data ddic dynamic itab | | [Expression Binding, Types and Composite Parts](https://cap2ui5.github.io/web-cap2UI5-build/?app_start=z2ui5_cl_smp_app_027) | [`z2ui5_cl_smp_app_027`](https://github.com/cap2UI5/cap2UI5/blob/main/core/srv/app/samples/z2ui5_cl_smp_app_027.js) | formatter parts conditional regexp visible enabled syntax | diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index b449443..5337900 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -25,12 +25,12 @@ This page shows in detail **how a roundtrip flows through the system** — from └────────────┬────────────────┘ │ ▼ -┌──── z2ui5_cl_ui5_http_handler ──┐ +┌─ z2ui5_cl_ui5_http_handler ─┐ │ unwrap req.data.value │ └────────────┬────────────────┘ │ ▼ -┌──── z2ui5_cl_ui5_handler ──┐ +┌──── z2ui5_cl_ui5_handler ───┐ │ 1. action.factory_main │── ▶ DB.loadApp(id) │ 2. validate │ │ 3. apply XX delta │ diff --git a/package.json b/package.json index 8702b21..b76a3e4 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "docs:preview": "vitepress preview docs", "verify": "node scripts/verify-refs.mjs", "check": "npm run verify && npm run docs:build", - "check:ci": "node scripts/verify-refs.mjs --require-checkout && npm run docs:build", + "check:ci": "node scripts/verify-refs.mjs --require-checkout && node scripts/gen-samples.mjs --check && npm run docs:build", "gen:samples": "node scripts/gen-samples.mjs" }, "devDependencies": { diff --git a/scripts/verify-refs.mjs b/scripts/verify-refs.mjs index 4e64bec..7931836 100644 --- a/scripts/verify-refs.mjs +++ b/scripts/verify-refs.mjs @@ -25,6 +25,9 @@ * 3. every z2ui5 class named in backticks exists somewhere in the app * 4. every `require("abap2UI5/…")` in a FENCED CODE BLOCK resolves through * the exports map of core/package.json, and onto a file that exists + * 5. every three-part release number (1.x.y) the docs mention is the + * framework release the checkout actually pins (`static version` on + * z2ui5_if_app), or an allowlisted historical/UI5 number * * Check 4 exists because the first three did not see the largest defect this * site ever had. Fenced blocks were skipped wholesale as "examples, not @@ -154,6 +157,27 @@ const add = (file, line, msg) => const PATH_ROOTS = ["core/", "srv/", "db/", "app/", "test/"]; const PATH_RE = /`([A-Za-z0-9_@./-]+\/[A-Za-z0-9_@./-]+)`/g; const APP_START_RE = /app_start=([a-z0-9_]+)/gi; +/* Check 5: release numbers. The site names the pinned framework release in + * NINE places across four pages ("Here, on 1.142.0", "cap2UI5 pins abap2UI5 + * **1.142.0**"), and the day the port moves its pin, every one of them goes + * stale at once - the exact defect class checks 1-4 exist for, one level up. + * The ground truth is the same place the prose itself points at: `static + * version` on z2ui5_if_app in the checkout. Every three-part 1.x.y the docs + * mention must be that version, or an entry in .verify-refs-ignore with a + * reason - which is where the HISTORICAL numbers live (1.143.0, the upstream + * release where the bindings merged, stays true whatever the pin says) and + * the UI5 ones (1.113.0 is an OpenUI5 release, not a framework release). + * Two-part floors like 1.71 are UI5 talk and deliberately not matched. */ +const RELEASE_RE = /\b1\.\d{2,3}\.\d+\b/g; +const VERSION_SOURCE = "core/srv/z2ui5/02/z2ui5_if_app.js"; +const PINNED_RELEASE = (() => { + try { + return fs.readFileSync(path.join(APP, VERSION_SOURCE), "utf8") + .match(/static version = `(\d+\.\d+\.\d+)`/)?.[1] ?? null; + } catch { + return null; + } +})(); // A backticked span that STARTS with a z2ui5 class name. It deliberately does // not require the closing backtick to follow the identifier: the docs write // `z2ui5_cl_xml_view.js`, `z2ui5_cl_util.register_app_dir(dir)` and @@ -202,6 +226,16 @@ for (const file of markdownFiles(DOCS)) { if (/^\s*```/.test(line)) { inFence = !inFence; return; } const n = i + 1; + // release numbers are claims wherever they stand, prose or example + if (PINNED_RELEASE) { + for (const m of line.matchAll(RELEASE_RE)) { + if (m[0] === PINNED_RELEASE || IGNORE.has(m[0])) continue; + add(file, n, `names release ${m[0]}, but the checkout pins ${PINNED_RELEASE} ` + + `(static version in ${VERSION_SOURCE}) - update the prose, or add the number ` + + `to .verify-refs-ignore with the reason it stays`); + } + } + if (inFence) { for (const m of line.matchAll(REQUIRE_RE)) { const sub = m[1] || ``;