Skip to content

Comments

Fix safe-outputs: missing op types in hasSafeOutputType, plural YAML tags, unmerged meta fields, Serena schema enum#17908

Merged
pelikhan merged 6 commits intomainfrom
copilot/fix-safe-outputs-import-gaps
Feb 23, 2026
Merged

Fix safe-outputs: missing op types in hasSafeOutputType, plural YAML tags, unmerged meta fields, Serena schema enum#17908
pelikhan merged 6 commits intomainfrom
copilot/fix-safe-outputs-import-gaps

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

  • Fix hasSafeOutputType() switch: add 11 missing operation type cases
  • Fix SafeOutputsConfig yaml tags: change 7 plural tags to singular to match schema keys
  • Fix mergeSafeOutputConfig(): add merge logic for 5 missing meta fields
  • Fix Serena languages schema enum: expand from 6 to all 32 supported languages
  • Add tests in safe_outputs_fix_test.go
  • Merge main branch and recompile all 158 workflow lock files
  • Fix TestMCPRegistryClient_LiveResponseStructure to skip on stream/CANCEL network errors
Original prompt

This section details on the original issue you should resolve

<issue_title>[plan] Fix safe-outputs import gaps: missing operation types, YAML tag mismatches, and unmerged meta fields</issue_title>
<issue_description>## Context

From schema consistency discussion #17876 (2026-02-23 run, findings 11–13 and two carryovers from Strategy-11).

Objective

Fix four related bugs in the safe-outputs system where import conflict detection, YAML serialization, and field merging produce silent incorrect behavior.

Issues to Fix

1. hasSafeOutputType() missing 11 operation type keys (carryover from Strategy-11)

  • File: pkg/workflow/imports.go:422
  • The switch statement is missing 11 operation types, meaning import conflict detection silently passes through conflicts for those types.
  • Add all missing operation type keys to the switch in hasSafeOutputType().

2. Serena languages schema enum restricted to 6 but runtime supports 32 (carryover from Strategy-11)

  • File: pkg/parser/schemas/main_workflow_schema.json (tools.serena.languages items.enum)
  • Schema enum only allows 6 Serena languages, but SerenaLanguageSupport in runtime_detection.go maps 32.
  • Expand the schema items.enum to match all 32 languages supported by SerenaLanguageSupport, or remove the enum restriction.

3. SafeOutputsConfig plural YAML tags mismatch singular schema keys

  • File: pkg/workflow/compiler_types.go:476-522
  • 7 struct fields use plural yaml tags (e.g., create-issues) that don't match the singular schema keys (e.g., create-issue).
    • CreateIssues → yaml:create-issues vs schema:create-issue
    • CreateDiscussions, CloseDiscussions, AddComments, CreatePullRequests, CreatePullRequestReviewComments, UpdateIssues — same pattern.
  • Parsing uses direct map key lookups so runtime behavior is correct, but marshaling back to YAML would fail additionalProperties: false validation.
  • Fix the yaml struct tags to use singular form matching the schema keys.

4. SafeOutputsConfig meta fields not merged from imported workflows

  • File: pkg/workflow/imports.go:655-720
  • Five meta fields are never merged when importing workflow configs:
    • Footer *bool
    • AllowGitHubReferences []string
    • GroupReports bool
    • MaxBotMentions *string
    • Mentions *MentionsConfig
  • Add merge logic for these fields in the import merge function.

Files to Modify

  • pkg/workflow/imports.go
  • pkg/workflow/compiler_types.go
  • pkg/parser/schemas/main_workflow_schema.json

Acceptance Criteria

  • hasSafeOutputType() switch covers all operation types (no silent pass-through)
  • Serena languages schema enum includes all 32 supported languages
  • SafeOutputsConfig yaml tags use singular form matching schema keys
  • Meta fields (Footer, AllowGitHubReferences, GroupReports, MaxBotMentions, Mentions) are merged from imported workflow configs
  • Run make agent-finish with no errors before committing
  • Run make build after schema changes (schemas are embedded via //go:embed)

Generated by Plan Command for issue #discussion #17876

  • expires on Feb 25, 2026, 12:04 PM UTC

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…, unmerged meta fields, Serena languages

- Add 11 missing operation type cases to hasSafeOutputType() switch statement
- Fix 7 SafeOutputsConfig yaml struct tags to use singular form matching schema keys
- Add merge logic for Footer, AllowGitHubReferences, GroupReports, MaxBotMentions, Mentions meta fields
- Expand Serena languages schema enum from 6 to all 32 supported languages

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix safe-outputs import gaps related to operation types and YAML Fix safe-outputs: missing op types in hasSafeOutputType, plural YAML tags, unmerged meta fields, Serena schema enum Feb 23, 2026
@github-actions
Copy link
Contributor

Hey @Copilot 👋 — excellent work fixing these four silent bugs in the safe-outputs system! The changes are well-scoped and directly address the issues identified in #17907. Here are a few things that would help get this across the finish line:

✅ What's Great:

⚠️ Missing Tests:

While the changes are correct, they lack test coverage for the bugs being fixed. According to the testing guidelines, bug fixes should include regression tests to prevent reoccurrence.

Specifically:

  1. hasSafeOutputType() missing cases — Add a test that verifies all 11 newly added operation types return true when their corresponding config field is non-nil (e.g., update-discussion, mark-pull-request-as-ready-for-review, etc.)

  2. YAML tag fixes — Add a test that marshals a SafeOutputsConfig struct with the affected fields back to YAML and verifies the keys match the schema (singular form: create-issue, not create-issues)

  3. Meta field merging — Add a test in imports_test.go that verifies Footer, AllowGitHubReferences, GroupReports, MaxBotMentions, and Mentions are properly merged from imported workflow configs

  4. Serena languages schema — No test needed since this is a schema-only change, but make sure to run make build after the schema change (schemas are embedded via //go:embed)

If you'd like a hand, you can use this prompt:

Add regression tests for the four bug fixes in this PR:

1. In `pkg/workflow/imports_test.go`, add a test `TestHasSafeOutputType_AllOperationTypes` that:
   - Creates a `SafeOutputsConfig` with each of the 11 newly added operation types set to a non-nil config struct
   - Calls `hasSafeOutputType()` with each operation type key
   - Asserts that it returns `true` for all 11 types: `update-discussion`, `mark-pull-request-as-ready-for-review`, `autofix-code-scanning-alert`, `assign-to-user`, `unassign-from-user`, `create-project`, `create-project-status-update`, `link-sub-issue`, `hide-comment`, `dispatch-workflow`, `missing-data`

2. In `pkg/workflow/compiler_types_test.go` (create if needed), add a test `TestSafeOutputsConfig_YAMLTags` that:
   - Creates a `SafeOutputsConfig` with the 7 affected fields set (CreateIssues, CreateDiscussions, CloseDiscussions, AddComments, CreatePullRequests, CreatePullRequestReviewComments, UpdateIssues)
   - Marshals the struct to YAML using `yaml.Marshal`
   - Parses the YAML and verifies the keys are singular (`create-issue`, `create-discussion`, `close-discussion`, `add-comment`, `create-pull-request`, `create-pull-request-review-comment`, `update-issue`)

3. In `pkg/workflow/imports_test.go`, add a test `TestMergeSafeOutputConfig_MetaFields` that:
   - Creates an importedConfig with Footer, AllowGitHubReferences, GroupReports, MaxBotMentions, and Mentions set to test values
   - Merges into an empty result config
   - Asserts all 5 meta fields were copied to the result

Follow the table-driven test pattern from scratchpad/testing.md. Use `require` for assertions that must pass before continuing, `assert` for final validations.

Run `make test` to verify all tests pass, then `make agent-finish` before completing.

Generated by Contribution Check

@pelikhan pelikhan marked this pull request as ready for review February 23, 2026 15:24
Copilot AI review requested due to automatic review settings February 23, 2026 15:24
@pelikhan
Copy link
Contributor

@copilot add tests

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

Fixes multiple silent failures in the safe-outputs pipeline by improving import conflict detection, aligning safe-outputs YAML serialization with the schema, ensuring imported safe-outputs meta fields aren’t dropped, and expanding Serena language schema validation.

Changes:

  • Expanded hasSafeOutputType() to include previously-missing safe-output operation keys so import conflicts are correctly detected.
  • Added import-merge handling for additional safe-outputs meta fields (footer/mentions/etc.).
  • Updated schema + types to reduce YAML/schema mismatches (safe-outputs keys) and broaden Serena languages enum coverage.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
pkg/workflow/imports.go Adds missing safe-output type detection and merges additional safe-outputs meta fields from imports.
pkg/workflow/compiler_types.go Updates several SafeOutputsConfig YAML tags to match schema-safe singular keys.
pkg/parser/schemas/main_workflow_schema.json Expands Serena languages enum to match supported runtime languages.
Comments suppressed due to low confidence (3)

pkg/workflow/compiler_types.go:489

  • CreateCodeScanningAlerts still uses the YAML tag create-code-scanning-alerts, but the schema and parsing logic use the singular key create-code-scanning-alert. This will continue to emit invalid YAML when marshaling SafeOutputsConfig (and can fail schema validation with additionalProperties: false). Update the struct tag to the singular key to match the schema.
	CreatePullRequestReviewComments *CreatePullRequestReviewCommentsConfig `yaml:"create-pull-request-review-comment,omitempty"`
	SubmitPullRequestReview         *SubmitPullRequestReviewConfig         `yaml:"submit-pull-request-review,omitempty"`           // Submit a PR review with status (APPROVE, REQUEST_CHANGES, COMMENT)
	ReplyToPullRequestReviewComment *ReplyToPullRequestReviewCommentConfig `yaml:"reply-to-pull-request-review-comment,omitempty"` // Reply to existing review comments on PRs
	ResolvePullRequestReviewThread  *ResolvePullRequestReviewThreadConfig  `yaml:"resolve-pull-request-review-thread,omitempty"`   // Resolve a review thread on a pull request
	CreateCodeScanningAlerts        *CreateCodeScanningAlertsConfig        `yaml:"create-code-scanning-alerts,omitempty"`

pkg/workflow/imports.go:673

  • The merge condition for AllowGitHubReferences uses len(result.AllowGitHubReferences) == 0, which treats an explicitly-configured empty list (meaning “allow none”) the same as “unset” and will overwrite it with imported values. Use a nil check (e.g., result.AllowGitHubReferences == nil) to only import when the field wasn’t configured in the main workflow.
	if len(result.AllowGitHubReferences) == 0 && len(importedConfig.AllowGitHubReferences) > 0 {
		result.AllowGitHubReferences = importedConfig.AllowGitHubReferences

pkg/workflow/imports.go:683

  • New merge behavior for the additional meta fields (footer, allowed-github-references, group-reports, max-bot-mentions, mentions) doesn’t appear to be covered by the existing safe-outputs import tests (which already validate other meta fields like allowed-domains, env, etc.). Add/extend tests to assert these new fields are imported and that main-workflow values take precedence when set.
	// Merge additional meta-configuration fields
	if result.Footer == nil && importedConfig.Footer != nil {
		result.Footer = importedConfig.Footer
	}
	if len(result.AllowGitHubReferences) == 0 && len(importedConfig.AllowGitHubReferences) > 0 {
		result.AllowGitHubReferences = importedConfig.AllowGitHubReferences
	}
	if !result.GroupReports && importedConfig.GroupReports {
		result.GroupReports = true
	}
	if result.MaxBotMentions == nil && importedConfig.MaxBotMentions != nil {
		result.MaxBotMentions = importedConfig.MaxBotMentions
	}
	if result.Mentions == nil && importedConfig.Mentions != nil {
		result.Mentions = importedConfig.Mentions
	}

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

… merges, and Serena schema enum

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot add tests

Added tests in pkg/workflow/safe_outputs_fix_test.go (commit faabc1e):

  • TestHasSafeOutputTypeNewKeys — table-driven test verifying all 11 newly added switch cases in hasSafeOutputType() return true when the corresponding field is set and false when nil
  • TestSafeOutputsConfigYAMLTags — marshals a SafeOutputsConfig to YAML and asserts singular keys (create-issue, create-discussion, etc.) are present and plural forms are absent
  • TestMergeSafeOutputsMetaFieldsUnit — table-driven test covering import and main-takes-precedence scenarios for Footer, AllowGitHubReferences, GroupReports, MaxBotMentions, and Mentions
  • TestSerenaSchemaLanguagesEnum — reads the schema from disk and verifies the Serena items.enum contains all 32 runtime-supported languages and has at least 32 entries

@pelikhan
Copy link
Contributor

@copilot merge main and recompile

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot merge main and recompile

Merged main and recompiled all 158 workflow lock files in commit 0a54f3f.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v7 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c --jq .object.sha (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v5 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha -c=4 -nolocalimports -importcfg /tmp/go-build4040084938/b062/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/cli/access_log.go /home/REDACTED/work/gh-aw/gh-aw/pkg/cli/actionlint.go (http block)
  • https://api.github.com/repos/anchore/sbom-action/git/ref/tags/v0
    • Triggering command: /usr/bin/gh gh api /repos/anchore/sbom-action/git/ref/tags/v0 --jq .object.sha (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha (http block)
  • https://api.github.com/repos/docker/build-push-action/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/docker/build-push-action/git/ref/tags/v6 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/login-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/metadata-action/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/docker/metadata-action/git/ref/tags/v5 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb --jq .object.sha (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/# --jq .object.sha (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@pelikhan
Copy link
Contributor

Copilot AI and others added 2 commits February 23, 2026 16:54
…L errors; merge main

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot merge main and fix https://github.com/github/gh-aw/actions/runs/22314510716/job/64557689936

Merged main and fixed the CI failure in commit 5e756b7. The TestMCPRegistryClient_LiveResponseStructure test was failing with stream error: stream ID 13; CANCEL; received from peer because the skip condition didn't cover stream/CANCEL errors. Added "stream" and "CANCEL" to the network error skip check so the test gracefully skips on these transient network failures.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683 --jq .object.sha js/**/*.json&#39; --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v7 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v7 --jq .object.sha cli/install.sh...&#34; (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c --jq .object.sha (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v5 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha js/**/*.json&#39; --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha data/action_pins.json...&#34; (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha json&#39; --ignore-path ../../../.pr**/*.json (http block)
  • https://api.github.com/repos/anchore/sbom-action/git/ref/tags/v0
    • Triggering command: /usr/bin/gh gh api /repos/anchore/sbom-action/git/ref/tags/v0 --jq .object.sha (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha (http block)
  • https://api.github.com/repos/docker/build-push-action/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/docker/build-push-action/git/ref/tags/v6 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/login-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/metadata-action/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/docker/metadata-action/git/ref/tags/v5 --jq .object.sha cp .github/aw/actions-lock.json pkg/workflow/data/action_pins.json; \ echo &#34;��� Action pins syngit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/docker/metadata-action/git/ref/tags/v5 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb --jq .object.sha (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/# --jq .object.sha (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@pelikhan pelikhan merged commit 8a7090e into main Feb 23, 2026
82 checks passed
@pelikhan pelikhan deleted the copilot/fix-safe-outputs-import-gaps branch February 23, 2026 17:00
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.

[plan] Fix safe-outputs import gaps: missing operation types, YAML tag mismatches, and unmerged meta fields

2 participants