-
Notifications
You must be signed in to change notification settings - Fork 295
docs: add dedicated staged mode documentation page for safe outputs #20269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1349,8 +1349,36 @@ safe-outputs: | |||||||||||||||
|
|
||||||||||||||||
| **Variables**: `{workflow_name}`, `{run_url}`, `{triggering_number}`, `{workflow_source}`, `{workflow_source_url}`, `{event_type}`, `{status}`, `{operation}` | ||||||||||||||||
|
|
||||||||||||||||
| ## Staged Mode | ||||||||||||||||
|
|
||||||||||||||||
| Staged mode lets you preview what safe outputs a workflow would create without actually creating anything. Every write operation is skipped; instead, a 🎭-labelled preview appears in the GitHub Actions step summary. | ||||||||||||||||
|
|
||||||||||||||||
| Enable it globally by adding `staged: true` to the `safe-outputs:` block: | ||||||||||||||||
|
|
||||||||||||||||
| ```yaml wrap | ||||||||||||||||
| safe-outputs: | ||||||||||||||||
| staged: true | ||||||||||||||||
| create-issue: | ||||||||||||||||
| title-prefix: "[ai] " | ||||||||||||||||
| labels: [automation] | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| You can also scope staged mode to a specific output type by adding `staged: true` directly to that type while leaving the global setting at `false`: | ||||||||||||||||
|
|
||||||||||||||||
| ```yaml wrap | ||||||||||||||||
| safe-outputs: | ||||||||||||||||
| create-pull-request: | ||||||||||||||||
| staged: true # preview only | ||||||||||||||||
| add-comment: # executes normally | ||||||||||||||||
|
Comment on lines
+1370
to
+1372
|
||||||||||||||||
| create-pull-request: | |
| staged: true # preview only | |
| add-comment: # executes normally | |
| staged: false # global default | |
| create-pull-request: | |
| staged: true # preview only | |
| add-comment: # executes normally |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| --- | ||
| title: Staged Mode | ||
| description: Preview safe output operations without making any changes, so you can see exactly what a workflow would do before it acts. | ||
| sidebar: | ||
| order: 820 | ||
| --- | ||
|
|
||
| Staged mode lets you run a workflow and see what [safe outputs](/gh-aw/reference/safe-outputs/) it would create — issues, comments, pull requests, and more — without actually creating anything. Every write operation is skipped; instead, a detailed preview appears in the GitHub Actions step summary with a 🎭 indicator. | ||
|
|
||
| This is useful when you're adopting a new workflow and want to verify its behavior before it has any real effect, or when you want to share what a workflow *would* do with colleagues before enabling it in production. | ||
|
|
||
| ## Enabling Staged Mode | ||
|
|
||
| Add `staged: true` to the `safe-outputs:` block in your workflow frontmatter: | ||
|
|
||
| ```aw wrap | ||
| --- | ||
| on: issues | ||
| safe-outputs: | ||
| staged: true | ||
| create-issue: | ||
| title-prefix: "[ai] " | ||
| labels: [automation] | ||
| --- | ||
|
|
||
| # Issue Analyzer | ||
|
|
||
| Analyze the issue and suggest follow-up tasks. | ||
| ``` | ||
|
|
||
| With this configuration the workflow runs fully — the AI completes its analysis — but no issues are created. Instead, the Actions run summary shows a preview of what would have been created. | ||
|
|
||
| ## Scoping Staged Mode per Output Type | ||
|
|
||
| Use `staged: true` on a specific type to preview only that output type while letting others execute normally: | ||
|
|
||
| ```aw wrap | ||
| --- | ||
| safe-outputs: | ||
| staged: false # default: execute normally | ||
| create-pull-request: | ||
| staged: true # PRs: preview only | ||
| add-comment: # comments: execute normally | ||
| --- | ||
| ``` | ||
|
|
||
| A type-level `staged` setting overrides the global one, so you can pilot one risky output type while keeping other outputs fully active. | ||
|
|
||
| ## What the Preview Looks Like | ||
|
|
||
| When staged mode is active the step summary contains a structured preview for each output type. The 🎭 emoji appears in every heading to make previews easy to spot: | ||
|
|
||
| ```markdown | ||
| ## 🎭 Staged Mode: Issue Creation Preview | ||
|
|
||
| The following 2 issue(s) would be performed if staged mode was disabled: | ||
|
|
||
| ### Operation 1: Add caching layer to database queries | ||
|
|
||
| **Type**: create-issue | ||
| **Title**: Add caching layer to database queries | ||
| **Body**: | ||
| Performance profiling shows repeated queries to the users table … | ||
|
|
||
| **Additional Fields**: | ||
| - Labels: performance, database | ||
| - Assignees: octocat | ||
|
|
||
| ### Operation 2: Update connection pool settings | ||
|
|
||
| … | ||
|
|
||
| --- | ||
| **Preview Summary**: 2 operations previewed. No GitHub resources were created. | ||
| ``` | ||
|
|
||
| The preview includes every field the AI populated — title, body, labels, assignees — so you can evaluate the full output before enabling. | ||
|
|
||
| ## Supported Output Types | ||
|
|
||
| Staged mode is supported by all built-in safe output types: | ||
|
|
||
| | Output type | What the preview shows | | ||
| |---|---| | ||
| | [`create-issue`](/gh-aw/reference/safe-outputs/#issue-creation-create-issue) | Title, body, labels, assignees | | ||
| | [`update-issue`](/gh-aw/reference/safe-outputs/#issue-updates-update-issue) | Target issue, updated fields | | ||
| | [`close-issue`](/gh-aw/reference/safe-outputs/#close-issue-close-issue) | Target issue, closing comment | | ||
| | [`add-comment`](/gh-aw/reference/safe-outputs/#comment-creation-add-comment) | Target issue/PR/discussion, comment body | | ||
| | [`add-labels`](/gh-aw/reference/safe-outputs/#add-labels-add-labels) | Target item, labels to add | | ||
| | [`remove-labels`](/gh-aw/reference/safe-outputs/#remove-labels-remove-labels) | Target item, labels to remove | | ||
| | [`create-discussion`](/gh-aw/reference/safe-outputs/#discussion-creation-create-discussion) | Title, body, category | | ||
| | [`update-discussion`](/gh-aw/reference/safe-outputs/#discussion-updates-update-discussion) | Target discussion, updated fields | | ||
| | [`close-discussion`](/gh-aw/reference/safe-outputs/#close-discussion-close-discussion) | Target discussion, closing comment | | ||
| | [`create-pull-request`](/gh-aw/reference/safe-outputs-pull-requests/#pull-request-creation-create-pull-request) | Title, body, branch, diff | | ||
| | [`update-pull-request`](/gh-aw/reference/safe-outputs/#pull-request-updates-update-pull-request) | Target PR, updated fields | | ||
| | [`close-pull-request`](/gh-aw/reference/safe-outputs/#close-pull-request-close-pull-request) | Target PR | | ||
| | [`create-pull-request-review-comment`](/gh-aw/reference/safe-outputs/#pr-review-comments-create-pull-request-review-comment) | File, line, comment body | | ||
| | [`push-to-pull-request-branch`](/gh-aw/reference/safe-outputs-pull-requests/#push-to-pr-branch-push-to-pull-request-branch) | Branch, patch summary | | ||
| | [`create-project`](/gh-aw/reference/safe-outputs/#project-creation-create-project) | Project title, description | | ||
| | [`update-project`](/gh-aw/reference/safe-outputs/#project-board-updates-update-project) | Target project, project items and fields to update | | ||
| | [`create-project-status-update`](/gh-aw/reference/safe-outputs/#project-status-updates-create-project-status-update) | Status, body | | ||
| | [`update-release`](/gh-aw/reference/safe-outputs/#release-updates-update-release) | Target release, updated body | | ||
| | [`upload-asset`](/gh-aw/reference/safe-outputs/#asset-uploads-upload-asset) | File names and sizes | | ||
| | [`dispatch-workflow`](/gh-aw/reference/safe-outputs/#workflow-dispatch-dispatch-workflow) | Target workflow, inputs | | ||
| | [`assign-to-agent`](/gh-aw/reference/safe-outputs/#assign-to-agent-assign-to-agent) | Target issue/PR | | ||
| | [`assign-to-user`](/gh-aw/reference/safe-outputs/#assign-to-user-assign-to-user) | Target item, user | | ||
| | [`create-agent-session`](/gh-aw/reference/safe-outputs/#agent-session-creation-create-agent-session) | Session details | | ||
|
|
||
| [Custom safe output jobs](/gh-aw/reference/custom-safe-outputs/) receive the `GH_AW_SAFE_OUTPUTS_STAGED` environment variable set to `"true"` when staged mode is active, allowing you to implement your own preview behavior. | ||
|
|
||
| ## Staged Mode for Custom Safe Output Jobs | ||
|
|
||
| Custom jobs check `GH_AW_SAFE_OUTPUTS_STAGED` to skip the real operation and display a preview instead: | ||
|
|
||
| ```javascript | ||
| if (process.env.GH_AW_SAFE_OUTPUTS_STAGED === 'true') { | ||
| core.info('🎭 Staged mode: would send Slack notification'); | ||
| await core.summary | ||
| .addHeading('🎭 Staged Mode: Slack Notification Preview', 2) | ||
| .addRaw(`**Would send**: ${process.env.MESSAGE}`) | ||
| .write(); | ||
| return; | ||
| } | ||
|
|
||
| // Production path — actually send the notification | ||
| await sendSlackMessage(process.env.MESSAGE); | ||
| ``` | ||
|
|
||
| See [Custom Safe Outputs — Staged Mode Support](/gh-aw/reference/custom-safe-outputs/#staged-mode-support) for a complete example. | ||
|
|
||
| ## Customizing Preview Messages | ||
|
|
||
| Override the default preview heading and description using the `messages:` block: | ||
|
|
||
| ```aw wrap | ||
| --- | ||
| safe-outputs: | ||
| staged: true | ||
| messages: | ||
| staged-title: "🎭 Preview: {operation}" | ||
| staged-description: "The following {operation} would occur if staged mode was disabled:" | ||
| create-issue: | ||
| --- | ||
| ``` | ||
|
|
||
| The `{operation}` placeholder is replaced with the safe output operation name (for example, `issue creation`). | ||
|
|
||
| ## Recommended Workflow | ||
|
|
||
| A common adoption pattern is to start with staged mode and disable it once you're satisfied with the output: | ||
|
|
||
| 1. Enable `staged: true` and trigger the workflow on a real event. | ||
| 2. Open the Actions run and review the 🎭 preview in the step summary. | ||
| 3. Adjust the workflow prompt or configuration based on the preview. | ||
| 4. Repeat until the output looks correct. | ||
| 5. Remove `staged: true` (or set it to `false`) to start creating real GitHub resources. | ||
|
|
||
| > [!TIP] | ||
| > Keep staged mode enabled when iterating on prompt changes, and only remove it when the workflow is stable. You can always re-enable it for a single type if you add a new safe output. | ||
|
|
||
| ## Related Documentation | ||
|
|
||
| - [Safe Outputs](/gh-aw/reference/safe-outputs/) — All built-in safe output types and their configuration | ||
| - [Custom Safe Outputs](/gh-aw/reference/custom-safe-outputs/) — Adding custom jobs with staged mode support | ||
| - [Frontmatter (Full)](/gh-aw/reference/frontmatter-full/) — Complete configuration reference | ||
| - [Threat Detection](/gh-aw/reference/threat-detection/) — Security scanning for safe output content |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The text uses UK spelling "🎭-labelled"; elsewhere in these docs the standard spelling is "labeled" (e.g., GitHub event types like
labeled). Consider changing this to "🎭-labeled" for consistency.