Skip to content

feat(alerts): integrate SAP Alert Notification via cds-alert-notification plugin (dark) - #1457

Merged
jung-thomas merged 20 commits into
mainfrom
worktree-ans-integration-spec
Aug 3, 2026
Merged

feat(alerts): integrate SAP Alert Notification via cds-alert-notification plugin (dark)#1457
jung-thomas merged 20 commits into
mainfrom
worktree-ans-integration-spec

Conversation

@jung-thomas

Copy link
Copy Markdown
Contributor

Summary

Wires the reusable @sap-devrel/cds-alert-notification plugin (v1.0.0) into tutorials-ims to push email alerts on three operational failures that today are pull-only (metrics/logs/PipelineLog — nobody is told). Ships dark behind ALERTS_ENABLED (default off); no behavior change until an operator provisions + flips it.

What's alerted

eventType Where Trigger
PublishRejected content-publish-session.js commitSession content publish soft-reject (no-revert guard)
ScheduledJobFailed scheduler.js runWithLock every scheduled job failure (one chokepoint; per-job dedup via resourceName)
RebuildDispatchFailed rebuild-trigger.js dispatch catch GitHub rebuild dispatch failure

How it's built

  • srv/lib/alerting.js — a fail-open raise() helper mirroring metrics.js (namespace import, never throws, ALERTS_ENABLED kill-switch). Each hook is a non-blocking void alerting.raise({...}) sitting beside the existing signal — never replacing it, never able to break the path it watches (doubly fail-open: helper try/catch + the plugin itself never throws).
  • package.json — plugin git-dep, cds.requires.alerts block (email channel, ERROR-severity routing, 5-min dedup), engines.node tightened to >=22.12 (plugin floor).
  • .deploy/mta.yamlalert-notification managed-service resource + tutorials-srv binding + alerting.js added to the srv-qa cp-list (it's transitively imported via content-publish-session.js) + minor bump 1.9.01.10.0.
  • srv/lib/feature-flags/registry.jsALERTS_ENABLED descriptor (true-enables, default false) to satisfy the repo's flag-drift test; polarity preserves the dark-launch default.

Tests

7 new unit tests (test/unit/alerting.test.js), all green: helper no-op-when-disabled, routes-when-enabled, fail-open on both raise- and connect-throw, plus an envelope-shape assertion per hook. Full suite: 7259 passed, no new failures (the 9 failing suites are a pre-existing fresh-worktree parsers.bundle.mjs build-artifact issue, unrelated to this change).

Not proven here (operator post-merge checklist — see docs/developers/architecture/observability.md)

This PR ships the integration dark and safe. It does not deploy, flip the flag, or bind the email address. The operator checklist covers: (1) regenerate package-lock.json in a git-dep-capable env (the plugin isn't on npm; allow-git:none blocked it on the authoring workstation — CI npm ci jobs will fail until this is done); (2) deploy MTA to provision the instance; (3) bind the email action to the real devrel-oncall address in the ANS cockpit; (4) ALERTS_ENABLED=true + restart; (5) live-verify one alert end-to-end — the plugin's cds.outboxed() + real-ANS-POST path is unproven against a live CAP runtime and MUST be verified here; (6) confirm the deploy runtime is Node ≥22.12.

Scope notes

Design spec + implementation plan under docs/superpowers/.

🤖 Generated with Claude Code

…js (#task-6)

Add static `import * as alerting from './alerting.js'` alongside existing
imports (ESM file). In the dispatch catch block, after the existing
console.error, add a non-blocking `void alerting.raise(...)` with the
RebuildDispatchFailed envelope (eventType, severity ERROR, category ALERT,
resource rebuild-dispatch/service). Existing no-rethrow semantics unchanged.

Append envelope-shape test (7th) to test/unit/alerting.test.js.
- Add tutorials-alert-notification managed-service resource (alert-notification/standard)
- Bind to tutorials-srv requires list
- srv-qa cp-list: alerting.js added (reachable via content-publish-session.js import graph per Task 3 audit)
- Version bump 1.9.0 → 1.10.0 (minor: new feature)
Adds "Alerting (SAP Alert Notification)" section to observability.md:
three wired failure paths (PublishRejected/ScheduledJobFailed/
RebuildDispatchFailed), the ALERTS_ENABLED flag, plugin/config block,
and a 6-step operator post-merge checklist covering plugin-install
caveat, MTA deploy, email-action binding, flag enable, live-verify,
and Node floor confirmation.

Also registers ALERTS_ENABLED in the feature-flags registry
(srv/lib/feature-flags/registry.js) to satisfy the drift test that
scans for any _ENABLED env var reads in srv/ without a matching entry.
@jung-thomas

Copy link
Copy Markdown
Contributor Author

⚠️ CI red — known blocker: cross-host dependency (decision deferred)

All four failing checks (check, check-cp-list, unit, validate) fail for one root cause, at the npm ci step, before any test/check logic runs:

npm error command git ls-remote https://github.tools.sap/developer-relations/cds-alert-notification.git
npm error remote: Password authentication is not available for Git operations.

tutorials-ims CI runs on public github.com and cannot authenticate to the SAP-internal github.tools.sap, where the plugin's git-dependency lives (package.jsongit+https://github.tools.sap/developer-relations/cds-alert-notification.git#v1.0.0). This is NOT a stale-lockfile issue — regenerating package-lock.json would not help, because npm ci still has to reach the internal host to fetch the dep.

This is an architectural seam between the plugin's git-dep distribution (internal) and this consumer's public CI. It requires a distribution decision, deferred by the author. Options on the table:

  1. Auth CI to github.tools.sap — enterprise PAT as a CI secret + git insteadOf/extraheader (or scoped .npmrc) in the workflows.
  2. Publish to a registry — plugin to an internal npm registry (or bring the sap-samples publish forward), depend by version instead of git URL. Cleanest long-term.
  3. Vendor locally — commit the plugin into tutorials-ims (file:/local path). Fast, but forks the plugin.

Until one is chosen, CI will remain red on dep-install. The code of this PR is otherwise complete and reviewed (7 alerting unit tests green locally; no new suite failures). Green CI is coupled to the same dep-distribution decision + the deploy prerequisites in docs/developers/architecture/observability.md.

…git-dep

- package.json dep: git+github.tools.sap URL → @sap-tutorials/cds-alert-notification ^1.0.0
- cds.requires.alerts.impl → @sap-tutorials scope
- add root .npmrc: @sap-tutorials scope → GitHub Packages + NODE_AUTH_TOKEN
- observability doc: rewrite dependency section + operator checklist for
  GH Packages auth (App token/PACKAGES_READ_TOKEN), drop stale git-dep/allow-git narrative
@jung-thomas

Copy link
Copy Markdown
Contributor Author

Update: relocated plugin to sap-tutorials + private GitHub Packages

The cross-host CI blocker is resolved by relocating the plugin off github.tools.sap (which public-github.com CI can't reach) to a private repo + GitHub Packages under this org — avoiding the OSPO public-release gate.

Plugin side (sap-tutorials/cds-alert-notification PR #1): renamed @sap-devrel@sap-tutorials/cds-alert-notification (GH Packages requires scope=org), added publishConfig + a publish.yml release workflow (private).

This PR (updated):

  • dep: git-URL → "@sap-tutorials/cds-alert-notification": "^1.0.0"
  • root .npmrc mapping the scope to GitHub Packages
  • the 4 failing npm ci jobs (unit, check, check-cp-list, validate) now mint the repo's existing GitHub App token (fallback PACKAGES_READ_TOKEN) and export NODE_AUTH_TOKEN, with permissions: packages: read
  • observability doc + operator checklist rewritten for the new dep source

CI will stay red until two out-of-band prerequisites are done (see checklist steps 1-3 in observability.md):

  1. Merge plugin PR feat: implement Admin UI (Fiori Elements + freestyle SAPUI5) #1 and cut a v1.0.0 release so the package publishes to GitHub Packages.
  2. Ensure the GitHub App installation grants packages: read (or set PACKAGES_READ_TOKEN).
  3. Regenerate package-lock.json in an env with a read:packages token (still can't be done on the authoring workstation).

Once the package is published + the token is in place, re-run these checks.

…read); drop App-token step

The 4 npm-ci check jobs auth to the private @sap-tutorials package with the
built-in GITHUB_TOKEN — the principal the package's repo-access grant covers
(the App installation token was refused: 'installation not allowed to read
organization package'). App-token step removed from these 4 only; content-drift
/rebuild/deploy workflows keep their App token for org tutorial-fetch.
github-actions Bot and others added 3 commits August 3, 2026 21:23
api-docs-drift (the 'check' job), e2e-coverage-nudge, schema-drift-check all
root-npm-ci the alerts dep but lacked packages:read + NODE_AUTH_TOKEN. Same
built-in-GITHUB_TOKEN pattern as the other 4 check jobs. (Deploy + nightly
workflows that npm ci deferred to a separate pass.)
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