Skip to content

Add release-driven support.mdx workflow + pr-docs-check fixes (drafted-PR link, SME reviewer)#16778

Merged
IEvangelist merged 3 commits into
microsoft:mainfrom
IEvangelist:dapine/aw-release-support-mdx
May 7, 2026
Merged

Add release-driven support.mdx workflow + pr-docs-check fixes (drafted-PR link, SME reviewer)#16778
IEvangelist merged 3 commits into
microsoft:mainfrom
IEvangelist:dapine/aw-release-support-mdx

Conversation

@IEvangelist
Copy link
Copy Markdown
Member

@IEvangelist IEvangelist commented May 5, 2026

Summary

Two related gh aw agentic workflow updates, originally reviewed as #16778 (this PR) + #16780 and now combined into a single PR to avoid duplicate actions-lock.json additions.

Part 1 — New release-update-support-mdx workflow

Adds a new agentic workflow that, when a stable release is published in microsoft/aspire, drafts a pull request in microsoft/aspire.dev updating the support policy page (src/frontend/src/content/docs/support.mdx).

The workflow handles three distinct release shapes — verified against the historical edits at microsoft/aspire.dev a98bc81 (13.2.3 patch), 1115320 (13.2.2 patch), and 6f0d51c (13.2 minor):

Shape Trigger example Edit
Patch on supported version v13.2.4 while supported = 13.2 Update the Supported row's Latest patch version + Patch release date + the date badge.
Major or minor bump v13.3.0 while supported = 13.2 Move the previously-supported row to the top of the Out of support table (preserve its patch info, set End of support = new release date), replace the Supported row, update the badge.
Backport servicing patch v13.1.4 while supported = 13.2 Update the matching Out of support row's Latest patch version + Patch release date, update the badge.

Design

Modeled on the existing pr-docs-check.md workflow:

  • Same aspire-bot GitHub App auth
  • microsoft/aspire.dev checked out as the current workspace, mirrored at _repos/aspire.dev for safe-outputs
  • safe-outputs.create-pull-request with target-repo: microsoft/aspire.dev, draft: true

Hardening (from rubber-duck design pass)

  • if: guarded on github.repository == 'microsoft/aspire' and explicit prerelease == false && draft == false (skips prereleases automatically).
  • workflow_dispatch.tag_name is required so manual runs always carry the data the agent needs; tag format validated against ^v\d+\.\d+\.\d+$.
  • concurrency: { group: release-update-support-mdx, cancel-in-progress: false } serializes near-simultaneous releases.
  • The agent prompt does stale-state reconciliation: searches for an open [support] PR before editing — no-op if it already reflects the new release, fail-closed if it represents a different earlier release.
  • Fail-closed structural validation of support.mdx headers and tables before any edit.
  • UTC en-US Month DD, YYYY date policy codified, called out in the PR body.
  • Idempotency check after applying the diff: no-op if the workspace diff is empty.
  • allowed-base-branches: [main] only.
  • fallback-as-issue: false to keep failures off aspire.dev's issue tracker.
  • Reviewer set to IEvangelist per maintainer preference.
  • Label is docs-from-code.

Part 2 — pr-docs-check updates (drafted PR link + SME reviewer)

Updates the existing pr-docs-check.md workflow so that:

  1. The status comment posted on the merged source microsoft/aspire PR includes a working link to the drafted documentation PR on microsoft/aspire.dev. Previously the agent crafted the comment from a separate add-comment safe output and could not reliably reference the freshly-created PR (the gh-aw temporary-id substitution requires camelCase number/repo fields that create_pull_request does not emit), so the link was either missing or invalid.
  2. The drafted aspire.dev PR is reviewed by the subject-matter expert from the source PR (the most recent approver), not the original PR author. The previous static reviewers expression always pointed at github.event.pull_request.user.login, which is the wrong human in almost every case.
  3. When the source PR was authored by GitHub Copilot Coding Agent, the SME is the human who initiated the Copilot session — not the bot, and not whoever happened to approve the bot's output. The originator is recorded in pull_request.assignees[] alongside the Copilot bot. Step 2 of the agent prompt now short-circuits on user.type == "Bot" + Copilot-identity logins, picks the first non-bot assignee, and only falls through to the review-collapse algorithm for human-authored PRs (or as a fallback if no human assignee is present).

Implementation

  • Removed the framework safe-outputs.add-comment block.
  • Removed the static reviewers field from safe-outputs.create-pull-request.
  • Added a custom safe-outputs.jobs.notify-source-pr job declaring needs: [safe_outputs] so it runs after the safe_outputs job and can read needs.safe_outputs.outputs.created_pr_url / created_pr_number. The job:
    • Mints two aspire-bot tokens (one scoped to microsoft/aspire, one scoped to microsoft/aspire.dev).
    • Posts a status comment on the source PR with the real drafted PR URL. Three states are handled: drafted+URL → success message linking the docs PR; drafted+no URL → ⚠️ failure surface (links to the workflow run); skipped → ✅ no docs needed. Older comments carrying the marker <!-- pr-docs-check:notify-source-pr --> are minimised via GraphQL minimizeComment for clean re-runs.
    • Best-effort calls pulls.requestReviewers on the drafted PR with the agent-discovered SME login. Wrapped in try/catch so a 422 (user not assignable) does not break the comment-posting step.
  • Added a new agent step (Step 2) that walks PR reviews, collapses by reviewer, prefers the most recent APPROVED reviewer, with fallbacks to a CHANGES_REQUESTED reviewer and CODEOWNERS as a hint. For Copilot-authored source PRs, the step instead reads pull_request.assignees[] and picks the first non-bot human (the session originator). The agent emits a single notify_source_pr safe-output item carrying source_pr_number, result, sme_login, target_branch, and a length-bounded summary.
  • The agent is explicitly forbidden from composing the drafted PR URL itself or calling add_comment.

Security review

Both workflows share the same secrets and pinned actions. All entries below already match SHAs in the existing pr-docs-check.lock.yml.

Secrets:

  • ASPIRE_BOT_APP_ID
  • ASPIRE_BOT_PRIVATE_KEY

Actions (all SHA-pinned):

  • actions/checkout@v6.0.2
  • actions/create-github-app-token@v3.1.1
  • actions/download-artifact@v8.0.1
  • actions/github-script@v9
  • actions/setup-node@v6.4.0
  • actions/upload-artifact@v7.0.1
  • github/gh-aw-actions/setup@v0.71.1

No new external network destinations are introduced beyond the defaults and github ecosystems already permitted.

Validation

  • gh aw compile release-update-support-mdx --strict --validate0 error(s), 0 warning(s).
  • gh aw compile pr-docs-check --strict --validate0 error(s), 0 warning(s).

Manual testing plan

After merge, a maintainer can validate the release workflow via workflow_dispatch against the most recent release tag (e.g. v13.2.4) — the agent should detect the file already reflects that release and no-op via the idempotency check.

The pr-docs-check updates take effect automatically on the next merged PR matching the workflow's trigger.

Copilot AI review requested due to automatic review settings May 5, 2026 15:13
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16778

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16778"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new GitHub Agentic Workflow that reacts to stable Aspire releases and drafts an aspire.dev PR updating support.mdx to reflect the new release (including patch/minor-major/backport cases), using the existing aspire-bot GitHub App + safe-outputs PR creation pattern.

Changes:

  • Introduces release-update-support-mdx gh-aw workflow to classify releases and draft an aspire.dev support policy update PR.
  • Adds the compiled lock workflow and updates the repo’s actions lock to include any newly referenced pinned actions.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
.github/workflows/release-update-support-mdx.md New gh-aw workflow source prompt + configuration for drafting aspire.dev support.mdx PRs on stable releases.
.github/workflows/release-update-support-mdx.lock.yml Compiled workflow output for the new gh-aw workflow.
.github/aw/actions-lock.json Adds pinned action entries needed by the new compiled workflow.

Comment thread .github/workflows/release-update-support-mdx.md
@IEvangelist IEvangelist changed the title Add gh aw workflow to draft aspire.dev support.mdx PR on each release Add release-driven support.mdx workflow + pr-docs-check fixes (drafted-PR link, SME reviewer) May 5, 2026
IEvangelist and others added 3 commits May 7, 2026 13:29
When a stable Aspire release publishes in microsoft/aspire, this workflow
drafts a pull request in microsoft/aspire.dev that updates the support
policy page (src/frontend/src/content/docs/support.mdx). It handles three
release shapes:

- Patch on the currently supported version: update the Supported row's
  Latest patch version, Patch release date, and the date badge.
- Major or minor bump: demote the previously supported row to the top of
  the Out of support versions table (preserving its patch info, setting
  End of support to the new release date), replace the Supported row with
  the new version, and update the badge.
- Backport servicing patch on an out-of-support version: update the
  matching Out of support row's Latest patch version and Patch release
  date, and update the badge.

Modeled on pr-docs-check.md: same aspire-bot GitHub App, mirrored
microsoft/aspire.dev checkout, and safe-outputs.create-pull-request flow.

Hardening (from rubber-duck design pass):

- Strict github.repository == 'microsoft/aspire' guard plus prerelease /
  draft filtering for release events.
- workflow_dispatch.tag_name is required so manual runs always carry the
  data the agent needs.
- Concurrency group serializes near-simultaneous releases.
- Agent prompt instructs a stale-state reconciliation step against any
  open [support] PR (no-op if it already matches; fail-closed otherwise).
- Fail-closed structural validation of support.mdx headers and tables
  before any edit; UTC date policy codified.
- Idempotency check (no-op if the workspace diff is empty after the edit).
- allowed-base-branches locked to [main]; fallback-as-issue disabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s reviewer

Updates the pr-docs-check gh-aw workflow so that:

1. The status comment posted on the merged microsoft/aspire PR includes a
   working link to the drafted documentation PR on microsoft/aspire.dev.
   Previously the agent crafted the comment from a separate add-comment safe
   output and could not reliably reference the freshly created PR (the gh-aw
   temporary-id substitution requires camelCase number/repo fields that
   create_pull_request does not emit), so the link was either missing or
   invalid.

2. The drafted aspire.dev PR is reviewed by the subject-matter expert from the
   source PR (the most recent approver), not the original PR author. The
   previous static reviewers expression always pointed at github.event.pull_request.user.login,
   which is the wrong human in almost every case.

Implementation:

- Removed the framework safe-outputs.add-comment block.
- Removed the static reviewers field from create-pull-request.
- Added a custom safe-outputs.jobs.notify-source-pr job declaring
  needs: [safe_outputs] so it runs after the safe_outputs job and can read
  needs.safe_outputs.outputs.created_pr_url and created_pr_number. The job:
    * Mints two aspire-bot tokens (microsoft/aspire and microsoft/aspire.dev).
    * Posts a status comment on the source PR with the real drafted PR URL,
      handling three states: drafted+URL (success), drafted+no URL (failure
      surfaced explicitly), and skipped (no docs needed). Older comments
      carrying our marker are minimised via GraphQL minimizeComment for clean
      re-runs.
    * Best-effort calls pulls.requestReviewers on the drafted PR with the
      agent-discovered SME login. Wrapped in try/catch so a 422 (user not
      assignable) does not break the comment-posting step.
- Added a new agent step (Step 2) that walks PR reviews, collapses by
  reviewer, prefers the most recent APPROVED reviewer, with fallbacks to a
  CHANGES_REQUESTED reviewer and CODEOWNERS as a hint. The agent emits a
  single notify_source_pr safe-output item carrying source_pr_number, result,
  sme_login, target_branch, and a length-bounded summary. The agent is
  explicitly forbidden from composing the drafted PR URL itself or calling
  add_comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the source microsoft/aspire PR was authored by GitHub Copilot Coding
Agent (user.type == 'Bot' and login matches 'Copilot' / 'copilot-swe-agent'),
the SME for the drafted aspire.dev PR is the human who initiated the Copilot
session, not whoever happened to approve the bot's output. That originator
is recorded in pull_request.assignees[] alongside the Copilot bot itself.

Step 2 of the agent prompt is restructured into:
- Step 2a: Copilot-author short-circuit. Filter assignees[] for non-bot logins
  and pick the human originator. If multiple humans, prefer the approver,
  fall back to assignee order.
- Step 2b: Existing review-collapse algorithm, used for human-authored PRs and
  as a fallback when Step 2a finds no human.

No lock-file or actions-lock.json change: gh-aw only re-emits the lock when
the frontmatter hash changes, and this is a prompt-body-only edit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist force-pushed the dapine/aw-release-support-mdx branch from c2f39d7 to d69ca11 Compare May 7, 2026 18:30
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
GitHub was asked to rerun all failed jobs for that attempt, and the rerun is being tracked in the rerun attempt.
The job links below point to the failed attempt jobs that matched the retry-safe transient failure rules.

@IEvangelist IEvangelist merged commit aa1e960 into microsoft:main May 7, 2026
569 of 575 checks passed
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.4 milestone May 7, 2026
nellshamrell pushed a commit to nellshamrell/aspire that referenced this pull request May 18, 2026
…d-PR link, SME reviewer) (microsoft#16778)

* Add gh aw workflow to draft aspire.dev support.mdx PR on each release

When a stable Aspire release publishes in microsoft/aspire, this workflow
drafts a pull request in microsoft/aspire.dev that updates the support
policy page (src/frontend/src/content/docs/support.mdx). It handles three
release shapes:

- Patch on the currently supported version: update the Supported row's
  Latest patch version, Patch release date, and the date badge.
- Major or minor bump: demote the previously supported row to the top of
  the Out of support versions table (preserving its patch info, setting
  End of support to the new release date), replace the Supported row with
  the new version, and update the badge.
- Backport servicing patch on an out-of-support version: update the
  matching Out of support row's Latest patch version and Patch release
  date, and update the badge.

Modeled on pr-docs-check.md: same aspire-bot GitHub App, mirrored
microsoft/aspire.dev checkout, and safe-outputs.create-pull-request flow.

Hardening (from rubber-duck design pass):

- Strict github.repository == 'microsoft/aspire' guard plus prerelease /
  draft filtering for release events.
- workflow_dispatch.tag_name is required so manual runs always carry the
  data the agent needs.
- Concurrency group serializes near-simultaneous releases.
- Agent prompt instructs a stale-state reconciliation step against any
  open [support] PR (no-op if it already matches; fail-closed otherwise).
- Fail-closed structural validation of support.mdx headers and tables
  before any edit; UTC date policy codified.
- Idempotency check (no-op if the workspace diff is empty after the edit).
- allowed-base-branches locked to [main]; fallback-as-issue disabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* pr-docs-check: link drafted PR in source-PR comment and request SME as reviewer

Updates the pr-docs-check gh-aw workflow so that:

1. The status comment posted on the merged microsoft/aspire PR includes a
   working link to the drafted documentation PR on microsoft/aspire.dev.
   Previously the agent crafted the comment from a separate add-comment safe
   output and could not reliably reference the freshly created PR (the gh-aw
   temporary-id substitution requires camelCase number/repo fields that
   create_pull_request does not emit), so the link was either missing or
   invalid.

2. The drafted aspire.dev PR is reviewed by the subject-matter expert from the
   source PR (the most recent approver), not the original PR author. The
   previous static reviewers expression always pointed at github.event.pull_request.user.login,
   which is the wrong human in almost every case.

Implementation:

- Removed the framework safe-outputs.add-comment block.
- Removed the static reviewers field from create-pull-request.
- Added a custom safe-outputs.jobs.notify-source-pr job declaring
  needs: [safe_outputs] so it runs after the safe_outputs job and can read
  needs.safe_outputs.outputs.created_pr_url and created_pr_number. The job:
    * Mints two aspire-bot tokens (microsoft/aspire and microsoft/aspire.dev).
    * Posts a status comment on the source PR with the real drafted PR URL,
      handling three states: drafted+URL (success), drafted+no URL (failure
      surfaced explicitly), and skipped (no docs needed). Older comments
      carrying our marker are minimised via GraphQL minimizeComment for clean
      re-runs.
    * Best-effort calls pulls.requestReviewers on the drafted PR with the
      agent-discovered SME login. Wrapped in try/catch so a 422 (user not
      assignable) does not break the comment-posting step.
- Added a new agent step (Step 2) that walks PR reviews, collapses by
  reviewer, prefers the most recent APPROVED reviewer, with fallbacks to a
  CHANGES_REQUESTED reviewer and CODEOWNERS as a hint. The agent emits a
  single notify_source_pr safe-output item carrying source_pr_number, result,
  sme_login, target_branch, and a length-bounded summary. The agent is
  explicitly forbidden from composing the drafted PR URL itself or calling
  add_comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* pr-docs-check: identify human originator for Copilot-authored source PRs

When the source microsoft/aspire PR was authored by GitHub Copilot Coding
Agent (user.type == 'Bot' and login matches 'Copilot' / 'copilot-swe-agent'),
the SME for the drafted aspire.dev PR is the human who initiated the Copilot
session, not whoever happened to approve the bot's output. That originator
is recorded in pull_request.assignees[] alongside the Copilot bot itself.

Step 2 of the agent prompt is restructured into:
- Step 2a: Copilot-author short-circuit. Filter assignees[] for non-bot logins
  and pick the human originator. If multiple humans, prefer the approver,
  fall back to assignee order.
- Step 2b: Existing review-collapse algorithm, used for human-authored PRs and
  as a fallback when Step 2a finds no human.

No lock-file or actions-lock.json change: gh-aw only re-emits the lock when
the frontmatter hash changes, and this is a prompt-body-only edit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants