From 2ea957d30d2275c5cdf9d7e90e72a8e974906691 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Jun 2026 00:43:16 +0000 Subject: [PATCH 1/5] Initial plan From 2ec53310e2cf9071d0d751770dea4af2cb9ddbde Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Jun 2026 01:17:35 +0000 Subject: [PATCH 2/5] Apply remaining changes Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/aw/safe-outputs-runtime.md | 3 +- pkg/parser/schemas/main_workflow_schema.json | 7 +++- .../compiler_safe_outputs_config_test.go | 11 ++++++ pkg/workflow/compiler_types.go | 2 +- pkg/workflow/imports.go | 5 +++ pkg/workflow/notify_comment.go | 38 +++++++++++++++---- pkg/workflow/notify_comment_test.go | 28 ++++++++++++++ pkg/workflow/safe_outputs_config.go | 29 +++++++++++--- pkg/workflow/safe_outputs_import_test.go | 5 +++ 9 files changed, 111 insertions(+), 17 deletions(-) diff --git a/.github/aw/safe-outputs-runtime.md b/.github/aw/safe-outputs-runtime.md index 31f21184d8f..26de7bbcc3b 100644 --- a/.github/aw/safe-outputs-runtime.md +++ b/.github/aw/safe-outputs-runtime.md @@ -203,8 +203,9 @@ Fields that influence permission computation (`add-comment.discussions`, `create - Increase this limit for long-running branches that touch many files - `group-reports:` - Group workflow failure reports as sub-issues (boolean, default: `false`) - When `true`, creates a parent `[aw] Failed runs` issue that tracks all workflow failures as sub-issues; useful for larger repositories -- `report-failure-as-issue:` - Control whether workflow failures are reported as GitHub issues (boolean, default: `true`) +- `report-failure-as-issue:` - Control whether workflow failures are reported as GitHub issues (boolean, expression, or category array; default: `true`) - When `false`, suppresses automatic failure issue creation for this workflow + - Supports templatable boolean expressions, e.g. `report-failure-as-issue: ${{ inputs.report-failure-as-issue }}` - Use to silence noisy failure reports for workflows where failures are expected or handled externally - `failure-issue-repo:` - Repository to create failure tracking issues in (string, format: `"owner/repo"`) - Defaults to the current repository when not specified diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index c38d2782a33..dc5696461b4 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -10306,6 +10306,11 @@ "type": "boolean", "description": "When false, disables creating failure tracking issues when workflows fail. When true, all failures trigger issues. Defaults to true." }, + { + "type": "string", + "pattern": "^\\$\\{\\{.*\\}\\}$", + "description": "GitHub Actions expression that resolves to a boolean at runtime (for example: '${{ inputs.report-failure-as-issue }}')." + }, { "type": "array", "description": "List of failure categories that should trigger issue creation. Categories can be prefixed with '!' to exclude them (e.g., '!inference_access_error'). If only non-prefixed categories are specified, only those categories trigger issues. If only prefixed (excluded) categories are specified, all categories except those trigger issues. If both are specified, categories must match included AND not match excluded. Common categories: agent_failure, timed_out, missing_safe_outputs, report_incomplete, missing_tool, missing_data, inference_access_error, mcp_policy_error, ai_credits_rate_limit_error, max_ai_credits_exceeded.", @@ -10318,7 +10323,7 @@ } ], "default": true, - "examples": [false, true, ["agent_failure", "missing_safe_outputs"], ["!inference_access_error", "!ai_credits_rate_limit_error"]] + "examples": [false, true, "${{ inputs.report-failure-as-issue }}", ["agent_failure", "missing_safe_outputs"], ["!inference_access_error", "!ai_credits_rate_limit_error"]] }, "failure-issue-repo": { "type": "string", diff --git a/pkg/workflow/compiler_safe_outputs_config_test.go b/pkg/workflow/compiler_safe_outputs_config_test.go index 9cca7fc1523..0f7e4ca16fb 100644 --- a/pkg/workflow/compiler_safe_outputs_config_test.go +++ b/pkg/workflow/compiler_safe_outputs_config_test.go @@ -3398,6 +3398,7 @@ func TestReportFailureAsIssueWithCategoriesFilter(t *testing.T) { name string reportValue any expectBool *bool + expectString string expectCategories []string expectExcludedCategories []string }{ @@ -3411,6 +3412,11 @@ func TestReportFailureAsIssueWithCategoriesFilter(t *testing.T) { reportValue: false, expectBool: boolPtr(false), }, + { + name: "templatable expression", + reportValue: "${{ inputs.report-failure-as-issue }}", + expectString: "${{ inputs.report-failure-as-issue }}", + }, { name: "array of categories", reportValue: []any{"agent_failure", "missing_safe_outputs"}, @@ -3454,6 +3460,11 @@ func TestReportFailureAsIssueWithCategoriesFilter(t *testing.T) { require.True(t, ok, "ReportFailureAsIssue should be bool") assert.Equal(t, *tt.expectBool, reportBool, "Boolean value should match") } + if tt.expectString != "" { + reportString, ok := config.ReportFailureAsIssue.(string) + require.True(t, ok, "ReportFailureAsIssue should be string") + assert.Equal(t, tt.expectString, reportString, "String value should match") + } if len(tt.expectCategories) > 0 { assert.Equal(t, tt.expectCategories, config.ReportFailureAsIssueCategories, "Categories should match") diff --git a/pkg/workflow/compiler_types.go b/pkg/workflow/compiler_types.go index ef9faed82fb..4b6a1369b44 100644 --- a/pkg/workflow/compiler_types.go +++ b/pkg/workflow/compiler_types.go @@ -737,7 +737,7 @@ type SafeOutputsConfig struct { Mentions *MentionsConfig `yaml:"mentions,omitempty"` // Configuration for @mention filtering in safe outputs Footer *bool `yaml:"footer,omitempty"` // Global footer control - when false, omits visible footer from all safe outputs (XML markers still included) GroupReports bool `yaml:"group-reports,omitempty"` // If true, create parent "Failed runs" issue for agent failures (default: false) - ReportFailureAsIssue any `yaml:"report-failure-as-issue,omitempty"` // Controls failure issue creation: bool (true/false) or []interface{} (parsed from YAML array, converted to []string in ReportFailureAsIssueCategories). Default: true + ReportFailureAsIssue any `yaml:"report-failure-as-issue,omitempty"` // Controls failure issue creation: bool, templatable expression string, or []interface{} categories (parsed to ReportFailureAsIssueCategories/ExcludedCategories). Default: true ReportFailureAsIssueCategories []string `yaml:"-"` // Parsed failure categories for report-failure-as-issue (internal use only, included categories) ReportFailureAsIssueExcludedCategories []string `yaml:"-"` // Parsed excluded failure categories for report-failure-as-issue (internal use only, categories starting with "!") FailureIssueRepo string `yaml:"failure-issue-repo,omitempty"` // Repository to create failure issues in (format: "owner/repo"), defaults to current repo diff --git a/pkg/workflow/imports.go b/pkg/workflow/imports.go index e662678ac37..d8707007112 100644 --- a/pkg/workflow/imports.go +++ b/pkg/workflow/imports.go @@ -476,6 +476,11 @@ func mergeSafeOutputConfig(result *SafeOutputsConfig, config map[string]any, c * if !result.GroupReports && importedConfig.GroupReports { result.GroupReports = true } + if result.ReportFailureAsIssue == nil && importedConfig.ReportFailureAsIssue != nil { + result.ReportFailureAsIssue = importedConfig.ReportFailureAsIssue + result.ReportFailureAsIssueCategories = importedConfig.ReportFailureAsIssueCategories + result.ReportFailureAsIssueExcludedCategories = importedConfig.ReportFailureAsIssueExcludedCategories + } if result.FailureIssueRepo == "" && importedConfig.FailureIssueRepo != "" { result.FailureIssueRepo = importedConfig.FailureIssueRepo } diff --git a/pkg/workflow/notify_comment.go b/pkg/workflow/notify_comment.go index 49861817bc5..1cdcf75b6d7 100644 --- a/pkg/workflow/notify_comment.go +++ b/pkg/workflow/notify_comment.go @@ -393,21 +393,43 @@ func (c *Compiler) buildConclusionJob(data *WorkflowData, mainJobName string, sa agentFailureEnvVars = append(agentFailureEnvVars, " GH_AW_GROUP_REPORTS: \"false\"\n") } - // Pass report-failure-as-issue configuration flag (defaults to true if not specified) - // Supports both bool and array of category strings (with ! prefix for exclusions) + // Pass report-failure-as-issue configuration flag (defaults to true if not specified). + // Supports templatable bool values and array-of-category filters (with ! prefix for exclusions). if data.SafeOutputs != nil && data.SafeOutputs.ReportFailureAsIssue != nil { - if reportBool, ok := data.SafeOutputs.ReportFailureAsIssue.(bool); ok && !reportBool { - agentFailureEnvVars = append(agentFailureEnvVars, " GH_AW_FAILURE_REPORT_AS_ISSUE: \"false\"\n") - } else { - agentFailureEnvVars = append(agentFailureEnvVars, " GH_AW_FAILURE_REPORT_AS_ISSUE: \"true\"\n") - // If included categories filter is configured, pass it as JSON + appendReportFailureEnvVar := func(enabled bool) { + agentFailureEnvVars = append(agentFailureEnvVars, fmt.Sprintf(" GH_AW_FAILURE_REPORT_AS_ISSUE: %q\n", strconv.FormatBool(enabled))) + } + shouldIncludeCategoryFilters := true + switch reportSetting := data.SafeOutputs.ReportFailureAsIssue.(type) { + case bool: + appendReportFailureEnvVar(reportSetting) + shouldIncludeCategoryFilters = reportSetting + case string: + reportExpression := reportSetting + switch reportExpression { + case "true": + appendReportFailureEnvVar(true) + case "false": + appendReportFailureEnvVar(false) + shouldIncludeCategoryFilters = false + default: + agentFailureEnvVars = append(agentFailureEnvVars, buildTemplatableBoolEnvVar("GH_AW_FAILURE_REPORT_AS_ISSUE", &reportExpression)...) + shouldIncludeCategoryFilters = false + } + case []any: + appendReportFailureEnvVar(true) + default: + appendReportFailureEnvVar(true) + } + if shouldIncludeCategoryFilters { + // If included categories filter is configured, pass it as JSON. if len(data.SafeOutputs.ReportFailureAsIssueCategories) > 0 { categoriesJSON, err := json.Marshal(data.SafeOutputs.ReportFailureAsIssueCategories) if err == nil { agentFailureEnvVars = append(agentFailureEnvVars, fmt.Sprintf(" GH_AW_FAILURE_CATEGORIES_FILTER: %q\n", string(categoriesJSON))) } } - // If excluded categories filter is configured, pass it as JSON + // If excluded categories filter is configured, pass it as JSON. if len(data.SafeOutputs.ReportFailureAsIssueExcludedCategories) > 0 { excludedCategoriesJSON, err := json.Marshal(data.SafeOutputs.ReportFailureAsIssueExcludedCategories) if err == nil { diff --git a/pkg/workflow/notify_comment_test.go b/pkg/workflow/notify_comment_test.go index 16efa7cfb41..a7e00bba554 100644 --- a/pkg/workflow/notify_comment_test.go +++ b/pkg/workflow/notify_comment_test.go @@ -1222,6 +1222,34 @@ func TestConclusionJobCategoriesFilterQuoting(t *testing.T) { }) } +func TestConclusionJobReportFailureAsIssueTemplatableExpression(t *testing.T) { + compiler := NewCompiler() + workflowData := &WorkflowData{ + Name: "Test Workflow", + SafeOutputs: &SafeOutputsConfig{ + NoOp: &NoOpConfig{}, + ReportFailureAsIssue: "${{ inputs.report-failure-as-issue }}", + ReportFailureAsIssueCategories: []string{"agent_failure"}, + }, + } + + job, err := compiler.buildConclusionJob(workflowData, string(constants.AgentJobName), []string{}) + if err != nil { + t.Fatalf("Failed to build conclusion job: %v", err) + } + if job == nil { + t.Fatal("Expected conclusion job to be created") + } + + jobYAML := strings.Join(job.Steps, "") + if !strings.Contains(jobYAML, "GH_AW_FAILURE_REPORT_AS_ISSUE:") || !strings.Contains(jobYAML, "${{ inputs.report-failure-as-issue }}") { + t.Errorf("Expected templatable GH_AW_FAILURE_REPORT_AS_ISSUE env var in generated conclusion job YAML.\nGenerated YAML:\n%s", jobYAML) + } + if strings.Contains(jobYAML, "GH_AW_FAILURE_CATEGORIES_FILTER:") { + t.Errorf("Expected category filters to be omitted when report-failure-as-issue is templatable.\nGenerated YAML:\n%s", jobYAML) + } +} + func TestConclusionJobIncludesUsageArtifactSteps(t *testing.T) { compiler := NewCompiler() workflowData := &WorkflowData{ diff --git a/pkg/workflow/safe_outputs_config.go b/pkg/workflow/safe_outputs_config.go index 49766d07873..581ae1a4bde 100644 --- a/pkg/workflow/safe_outputs_config.go +++ b/pkg/workflow/safe_outputs_config.go @@ -630,13 +630,10 @@ func (c *Compiler) extractSafeOutputsConfig(frontmatter map[string]any) *SafeOut } } - // Handle report-failure-as-issue flag or array of categories + // Handle report-failure-as-issue as templatable bool or array of categories. if reportFailureAsIssue, exists := outputMap["report-failure-as-issue"]; exists { - // Support both bool (legacy) and []any (new with categories filter) - if reportFailureAsIssueBool, ok := reportFailureAsIssue.(bool); ok { - config.ReportFailureAsIssue = reportFailureAsIssueBool - safeOutputsConfigLog.Printf("Report failure as issue: %t", reportFailureAsIssueBool) - } else if categoriesList, ok := reportFailureAsIssue.([]any); ok { + // Support []any category filters. + if categoriesList, ok := reportFailureAsIssue.([]any); ok { // Parse as array of category strings, separating included (no prefix) and excluded (! prefix) includedCategories := make([]string, 0, len(categoriesList)) excludedCategories := make([]string, 0, len(categoriesList)) @@ -661,6 +658,26 @@ func (c *Compiler) extractSafeOutputsConfig(frontmatter map[string]any) *SafeOut } else if len(excludedCategories) > 0 { safeOutputsConfigLog.Printf("Report failure as issue with exclude filter: %v", excludedCategories) } + } else { + // Support bool and templatable string values. + if err := preprocessBoolFieldAsString(outputMap, "report-failure-as-issue", safeOutputsConfigLog); err != nil { + safeOutputsConfigLog.Printf("Failed to preprocess report-failure-as-issue field: %v (ignoring invalid value and leaving field unset)", err) + } else { + if reportFailureAsIssueStr, ok := outputMap["report-failure-as-issue"].(string); ok { + switch reportFailureAsIssueStr { + case "true": + config.ReportFailureAsIssue = true + case "false": + config.ReportFailureAsIssue = false + default: + config.ReportFailureAsIssue = reportFailureAsIssueStr + } + safeOutputsConfigLog.Printf("Report failure as issue: %v", config.ReportFailureAsIssue) + } else if reportFailureAsIssueBool, ok := outputMap["report-failure-as-issue"].(bool); ok { + config.ReportFailureAsIssue = reportFailureAsIssueBool + safeOutputsConfigLog.Printf("Report failure as issue: %t", reportFailureAsIssueBool) + } + } } } diff --git a/pkg/workflow/safe_outputs_import_test.go b/pkg/workflow/safe_outputs_import_test.go index e7bf08bbf94..c21b165d77e 100644 --- a/pkg/workflow/safe_outputs_import_test.go +++ b/pkg/workflow/safe_outputs_import_test.go @@ -726,6 +726,7 @@ safe-outputs: allowed-domains: - "example.com" - "api.example.com" + report-failure-as-issue: ${{ inputs.report-failure-as-issue }} staged: true env: TEST_VAR: "test_value" @@ -785,6 +786,7 @@ This workflow uses the imported meta configuration. assert.True(t, templatableBoolIsTrue(workflowData.SafeOutputs.Staged), "Staged should be imported and set to true") assert.Equal(t, map[string]string{"TEST_VAR": "test_value"}, workflowData.SafeOutputs.Env, "Env should be imported") assert.Equal(t, "${{ secrets.CUSTOM_TOKEN }}", workflowData.SafeOutputs.GitHubToken, "GitHubToken should be imported") + assert.Equal(t, "${{ inputs.report-failure-as-issue }}", workflowData.SafeOutputs.ReportFailureAsIssue, "ReportFailureAsIssue should be imported as templatable bool") // Note: When main workflow has safe-outputs section, extractSafeOutputsConfig sets MaximumPatchSize default (4096) // before merge happens, so imported value is not used. User should specify max-patch-size in main workflow. assert.Equal(t, 4096, workflowData.SafeOutputs.MaximumPatchSize, "MaximumPatchSize defaults to 4096 when main has safe-outputs") @@ -806,6 +808,7 @@ func TestSafeOutputsImportMetaFieldsMainTakesPrecedence(t *testing.T) { safe-outputs: allowed-domains: - "shared.example.com" + report-failure-as-issue: false github-token: "${{ secrets.SHARED_TOKEN }}" max-patch-size: 1024 --- @@ -827,6 +830,7 @@ imports: safe-outputs: allowed-domains: - "main.example.com" + report-failure-as-issue: ${{ inputs.report-failure-as-issue }} github-token: "${{ secrets.MAIN_TOKEN }}" max-patch-size: 2048 create-issue: @@ -856,6 +860,7 @@ This workflow has its own meta configuration that should take precedence. // Verify main workflow meta fields take precedence assert.Equal(t, []string{"main.example.com"}, workflowData.SafeOutputs.AllowedDomains, "AllowedDomains from main should take precedence") + assert.Equal(t, "${{ inputs.report-failure-as-issue }}", workflowData.SafeOutputs.ReportFailureAsIssue, "ReportFailureAsIssue from main should take precedence") assert.Equal(t, "${{ secrets.MAIN_TOKEN }}", workflowData.SafeOutputs.GitHubToken, "GitHubToken from main should take precedence") assert.Equal(t, 2048, workflowData.SafeOutputs.MaximumPatchSize, "MaximumPatchSize from main should take precedence") } From 81f59fff4fbdf258d38f5e54ef077f090d644f41 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:31:39 +0000 Subject: [PATCH 3/5] Apply remaining changes Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/handle_agent_failure.cjs | 3 +- .../setup/js/handle_agent_failure.test.cjs | 28 +++++++++++++++++++ actions/setup/js/templatable.cjs | 4 ++- actions/setup/js/templatable.test.cjs | 5 ++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/actions/setup/js/handle_agent_failure.cjs b/actions/setup/js/handle_agent_failure.cjs index 8e410f08d48..d4ad6f8de40 100644 --- a/actions/setup/js/handle_agent_failure.cjs +++ b/actions/setup/js/handle_agent_failure.cjs @@ -14,6 +14,7 @@ const { AWF_INFRA_LINE_RE } = require("./log_parser_shared.cjs"); const { resolveFirewallAuditLogPath, resolveAICreditsFailureState, parseMaxAICreditsFromAuditLog, parseAICreditsErrorInfoFromAuditLog, parseUnknownModelAICreditsFromAuditLog } = require("./ai_credits_context.cjs"); const { formatAICCredits } = require("./daily_aic_workflow_helpers.cjs"); const { formatAIC } = require("./model_costs.cjs"); +const { parseBoolTemplatable } = require("./templatable.cjs"); const { parseTokenUsageJsonl, generateTokenUsageSummary } = require("./parse_mcp_gateway_log.cjs"); const { readDedupedTokenUsage, TOKEN_USAGE_PATHS } = require("./parse_token_usage.cjs"); const { extractShellCommandFromToolData } = require("./tool_call_details.cjs"); @@ -2692,7 +2693,7 @@ async function main() { const unknownModelAICreditsFromAudit = parseUnknownModelAICreditsFromAuditLog(); const unknownModelAICredits = unknownModelAICreditsFromAudit || (unknownModelAICreditsFromOutput && agentConclusion === "failure"); const pushRepoMemoryResult = process.env.GH_AW_PUSH_REPO_MEMORY_RESULT || ""; - const reportFailureAsIssue = process.env.GH_AW_FAILURE_REPORT_AS_ISSUE !== "false"; // Default to true + const reportFailureAsIssue = parseBoolTemplatable(process.env.GH_AW_FAILURE_REPORT_AS_ISSUE, true); // Parse included categories filter for report-failure-as-issue (optional JSON array of category strings) const failureCategoriesFilterRaw = process.env.GH_AW_FAILURE_CATEGORIES_FILTER || ""; let failureCategoriesFilter = null; diff --git a/actions/setup/js/handle_agent_failure.test.cjs b/actions/setup/js/handle_agent_failure.test.cjs index 4f788d30886..acdfb40ebae 100644 --- a/actions/setup/js/handle_agent_failure.test.cjs +++ b/actions/setup/js/handle_agent_failure.test.cjs @@ -485,6 +485,34 @@ describe("handle_agent_failure", () => { expect(createIssueMock).not.toHaveBeenCalled(); }); + it("skips failure issue creation when the runtime report flag resolves to false", async () => { + const searchMock = vi.fn(); + const createCommentMock = vi.fn(); + const createIssueMock = vi.fn(); + process.env.GH_AW_FAILURE_REPORT_AS_ISSUE = " False "; + + global.github = { + rest: { + search: { + issuesAndPullRequests: searchMock, + }, + issues: { + create: createIssueMock, + createComment: createCommentMock, + }, + pulls: { get: vi.fn() }, + }, + graphql: vi.fn(), + }; + + await main(); + + expect(searchMock).not.toHaveBeenCalled(); + expect(createCommentMock).not.toHaveBeenCalled(); + expect(createIssueMock).not.toHaveBeenCalled(); + expect(global.core.info).toHaveBeenCalledWith("Failure issue reporting is disabled (report-failure-as-issue: false), skipping failure issue creation"); + }); + it("adds a comment when existing issue metadata contains commas in free-form values", async () => { const createCommentMock = vi.fn(async () => ({ data: { id: 1001 } })); const createIssueMock = vi.fn(); diff --git a/actions/setup/js/templatable.cjs b/actions/setup/js/templatable.cjs index c2035e3e905..7dfffa7fa2e 100644 --- a/actions/setup/js/templatable.cjs +++ b/actions/setup/js/templatable.cjs @@ -22,6 +22,8 @@ * - boolean `false` → `false` * - string `"true"` → `true` * - string `"false"` → `false` + * - string variants that normalize to `"false"` after trim/lowercase + * (for example `" False "`) → `false` * - any other string (e.g. a resolved GitHub Actions expression value * that was not "false") → `true` * @@ -32,7 +34,7 @@ */ function parseBoolTemplatable(value, defaultValue = true) { if (value === undefined || value === null) return defaultValue; - return String(value) !== "false"; + return String(value).trim().toLowerCase() !== "false"; } /** diff --git a/actions/setup/js/templatable.test.cjs b/actions/setup/js/templatable.test.cjs index 9a39c955b62..16c08f6a5a6 100644 --- a/actions/setup/js/templatable.test.cjs +++ b/actions/setup/js/templatable.test.cjs @@ -33,6 +33,11 @@ describe("templatable.cjs", () => { expect(parseBoolTemplatable("false")).toBe(false); }); + it("handles normalized false string variants", () => { + expect(parseBoolTemplatable("False")).toBe(false); + expect(parseBoolTemplatable(" false ")).toBe(false); + }); + it("treats a resolved expression value other than false as truthy", () => { // GitHub Actions expressions that resolve to something other than "false" // (e.g. "yes", "1", an empty object representation) should be truthy. From 02e7d43b535c8789ee5c79344595ab1683651e39 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:57:43 +0000 Subject: [PATCH 4/5] Reuse templatable boolean schema ref Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/skills/agentic-workflows/SKILL.md | 1 + pkg/parser/schemas/main_workflow_schema.json | 8 +------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/skills/agentic-workflows/SKILL.md b/.github/skills/agentic-workflows/SKILL.md index ee714d339d8..b5fc4eb84f4 100644 --- a/.github/skills/agentic-workflows/SKILL.md +++ b/.github/skills/agentic-workflows/SKILL.md @@ -28,6 +28,7 @@ Load these files from `github/gh-aw` (they are not available locally). - `.github/aw/github-agentic-workflows.md` - `.github/aw/github-mcp-server.md` - `.github/aw/llms.md` +- `.github/aw/loop.md` - `.github/aw/mcp-clis.md` - `.github/aw/memory.md` - `.github/aw/messages.md` diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index dc5696461b4..107db0f6db7 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -10303,13 +10303,7 @@ "report-failure-as-issue": { "oneOf": [ { - "type": "boolean", - "description": "When false, disables creating failure tracking issues when workflows fail. When true, all failures trigger issues. Defaults to true." - }, - { - "type": "string", - "pattern": "^\\$\\{\\{.*\\}\\}$", - "description": "GitHub Actions expression that resolves to a boolean at runtime (for example: '${{ inputs.report-failure-as-issue }}')." + "$ref": "#/$defs/templatable_boolean" }, { "type": "array", From 888698be51756708b3ee4cfd734173112d158062 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:57:50 +0000 Subject: [PATCH 5/5] Drop unrelated skill file change Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/skills/agentic-workflows/SKILL.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/skills/agentic-workflows/SKILL.md b/.github/skills/agentic-workflows/SKILL.md index b5fc4eb84f4..ee714d339d8 100644 --- a/.github/skills/agentic-workflows/SKILL.md +++ b/.github/skills/agentic-workflows/SKILL.md @@ -28,7 +28,6 @@ Load these files from `github/gh-aw` (they are not available locally). - `.github/aw/github-agentic-workflows.md` - `.github/aw/github-mcp-server.md` - `.github/aw/llms.md` -- `.github/aw/loop.md` - `.github/aw/mcp-clis.md` - `.github/aw/memory.md` - `.github/aw/messages.md`