Skip to content

Add safe-outputs.steps for injecting custom steps into safe-output jobs#18460

Merged
pelikhan merged 3 commits intomainfrom
copilot/add-safe-output-steps-field
Feb 26, 2026
Merged

Add safe-outputs.steps for injecting custom steps into safe-output jobs#18460
pelikhan merged 3 commits intomainfrom
copilot/add-safe-output-steps-field

Conversation

Copy link
Contributor

Copilot AI commented Feb 26, 2026

Adds a safe-outputs.steps field that lets users inject custom steps into the consolidated safe-outputs job. Injected steps run after repository checkout and action setup, but before any safe-output code executes. Steps from imported workflows are merged (concatenated) with the main workflow's steps.

Changes

  • Schema (pkg/parser/schemas/main_workflow_schema.json): Added steps property to safe-outputs, using $ref: #/$defs/githubActionsStep to reuse the existing step interface
  • Types (pkg/workflow/compiler_types.go): Added Steps []any to SafeOutputsConfig
  • Parser (pkg/workflow/safe_outputs_config.go): Parses steps from safe-outputs frontmatter block
  • Compiler (pkg/workflow/compiler_safe_outputs_job.go): Injects steps after PR checkout (if any) and before the handler manager step; applies action SHA pinning consistent with safe-outputs.jobs.steps
  • Imports (pkg/workflow/imports.go): Merges safe-outputs.steps from imported workflows by concatenating imported steps after the main workflow's steps

Example

safe-outputs:
  create-issue: {}
  steps:
    - name: Install custom tool
      run: npm install my-package
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: "20"

Resulting step order in the generated job:

  1. Checkout actions folder + setup action
  2. Download agent output artifact
  3. (Optional) PR checkout
  4. User-injected steps ← inserted here (main workflow steps first, then steps from imported workflows)
  5. Process Safe Outputs (handler manager)
Original prompt

Add a safe-output.steps field that allows users to inject steps into the safe-output jobs. These steps must run after checking out the repository and setting up the action, and before configuring or running any of the safe-output code. The steps provided by the user are copied into the safe-output jobs.
Add support in the JSON schema, the parser, and the generated code. Reuse the existing interfaces for steps.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@pelikhan
Copy link
Contributor

@copilot entire steps get merged from imported workflows

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add safe-output.steps field for user-defined steps Add safe-outputs.steps for injecting custom steps into safe-output jobs Feb 26, 2026
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 26, 2026

@copilot entire steps get merged from imported workflows

Done in a15c27d. safe-outputs.steps from imported workflows are now concatenated (appended after the main workflow's steps) in mergeSafeOutputConfig in imports.go, consistent with how other array fields are handled.

@pelikhan pelikhan marked this pull request as ready for review February 26, 2026 14:12
Copilot AI review requested due to automatic review settings February 26, 2026 14:12
@pelikhan pelikhan merged commit 21992bd into main Feb 26, 2026
109 of 110 checks passed
@pelikhan pelikhan deleted the copilot/add-safe-output-steps-field branch February 26, 2026 14:19
Copy link
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

This PR adds support for injecting custom steps into the consolidated safe-outputs job through a new safe-outputs.steps configuration field. These steps execute after repository checkout and action setup, but before any safe-output processing logic runs.

Changes:

  • Added steps field to the safe-outputs configuration schema and type definitions
  • Implemented parsing and merging logic for user-provided steps (concatenating imported workflow steps after main workflow steps)
  • Integrated step injection into the safe-outputs job compilation with SHA pinning support

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/parser/schemas/main_workflow_schema.json Added steps property to safe-outputs schema definition
pkg/workflow/compiler_types.go Added Steps []any field to SafeOutputsConfig struct
pkg/workflow/safe_outputs_config.go Implemented parsing of steps from safe-outputs frontmatter
pkg/workflow/imports.go Added logic to concatenate imported steps with main workflow steps
pkg/workflow/compiler_safe_outputs_job.go Implemented step injection with SHA pinning in the consolidated job

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

for i, step := range data.SafeOutputs.Steps {
stepMap, ok := step.(map[string]any)
if !ok {
consolidatedSafeOutputsJobLog.Printf("Warning: safe-outputs step at index %d is not a valid step object (must be a map with properties like name, run, uses). Skipping this step.", i)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The error message should mention that the step will be skipped in the generated workflow to make the impact clearer to users reviewing logs.

Suggested change
consolidatedSafeOutputsJobLog.Printf("Warning: safe-outputs step at index %d is not a valid step object (must be a map with properties like name, run, uses). Skipping this step.", i)
consolidatedSafeOutputsJobLog.Printf("Warning: safe-outputs step at index %d is not a valid step object (must be a map with properties like name, run, uses). Skipping this step in the generated workflow.", i)

Copilot uses AI. Check for mistakes.
}
typedStep, err := MapToStep(stepMap)
if err != nil {
return nil, nil, fmt.Errorf("failed to convert safe-outputs step at index %d to typed step: %w", i, err)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

Error message could be more actionable by suggesting the user check the step structure in their workflow configuration.

Suggested change
return nil, nil, fmt.Errorf("failed to convert safe-outputs step at index %d to typed step: %w", i, err)
return nil, nil, fmt.Errorf("failed to convert safe-outputs step at index %d to typed step: %w. Check that this entry in 'safe-outputs.steps' uses the correct GitHub Actions step structure (a map with keys like 'name', 'run', or 'uses').", i, err)

Copilot uses AI. Check for mistakes.
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