The "Showcase: Docs Sync" workflow has been failing with
`fatal: pathspec 'showcase/shell/src/content/' did not match any files`
since the shell platform restructure (#4109, #4112) split the monolithic
`showcase/shell/` package into `showcase/shell-docs/`,
`showcase/shell-dashboard/`, and `showcase/shell-dojo/`.
The sync-docs-from-main.ts script already writes to
`showcase/shell-docs/src/content/` and maintains the sync marker at
`showcase/shell-docs/.docs-sync-sha`. Update the "Create PR for docs
sync" step to stage from the new location so the workflow can commit
synced content again.
Fixes 3 HIGH findings from R1 review on #3988:
1. pr_url empty was used as a proxy for "no PR opened because clean-transform
was empty", but it's also empty on every error path (bot-token failure, gh
pr create failure, push failure). Replace with an explicit pr_opened=true/
false output from the push step — true only after the PR URL is captured,
false only on the deliberate CHANGED=0 path. Error paths leave it unset so
alerts fall through to the failure() handler.
2. review_items_json was string-interpolated raw into a JSON payload inside
triple-backticks. Any filename containing ", \\, or a control character
would break the payload. Moved to a jq-based payload-file-path pattern:
a dedicated Build Slack payloads step writes each payload to disk with jq
--arg, so all values are safely JSON-escaped regardless of content. Slack
steps consume the tmpfiles via payload-file-path.
3. If a notify-* step itself fails (webhook 5xx, rate limit, malformed JSON),
the review-needed alert was silently lost — the existing failure() alert
was gated on pr_url == '' and would not fire. Added an unconditional
fallback step that posts a plain-text "alert machinery failed" message via
curl when any notify-* step's outcome is failure, so we never lose a
review-needed or failure notification.
The "files needing manual review" Slack warning listed files but
didn't link the auto-opened PR, forcing reviewers to hunt for it
in GitHub. Capture the PR URL from the create/merge step output
(already exposed as steps.push.outputs.pr_url) and include it as
a "Review:" line in the payload.
Split the alert into two variants:
- PR opened (normal case): includes the PR link
- No PR opened (edge case where clean-transform portion was empty):
posts review items without a link
Auto-sync and merge-failed alerts already linked the PR — this
brings the review-needed alert to parity.
The warning notification for files needing manual review was sending
'see workflow run for details' with no actionable information.
- Read review-items.txt and include file list in the Slack message
- Use jq for proper JSON escaping (handles newlines, quotes, special chars)
- Guard against missing review-items.txt with fallback and ::warning::
- Review-needed notification fires independently of push/merge outcome
The v1 action uses SubtleCrypto.importKey() which fails with 'Invalid keyData'
on certain PEM key formats. v2 handles this more robustly.
Also adds step-level failure info to the Slack notification so we know
WHICH step failed instead of just 'workflow failed'.