From 9eed06b63a0ada6b0aa5c916e9c62b91ab5e3e87 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:15:12 +0000 Subject: [PATCH 1/8] Initial plan From 22a45e082baaf4431f04ff2b299f8f9452e447f7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:27:35 +0000 Subject: [PATCH 2/8] Add AWF platform frontmatter support Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- .../docs/reference/frontmatter-full.md | 6 ++ pkg/parser/schema_test.go | 36 ++++++++++ pkg/parser/schemas/main_workflow_schema.json | 5 ++ pkg/workflow/awf_config.go | 21 ++++++ pkg/workflow/awf_config_test.go | 70 +++++++++++++++++++ .../frontmatter_extraction_security.go | 7 ++ .../frontmatter_extraction_security_test.go | 15 ++++ pkg/workflow/frontmatter_types_test.go | 9 ++- pkg/workflow/sandbox.go | 27 +++---- 9 files changed, 182 insertions(+), 14 deletions(-) diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index 6100c62629e..a28a1104cc3 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -1868,6 +1868,12 @@ sandbox: # (optional) version: "example-value" + # AWF platform.type override. Declares the GitHub deployment type so AWF can + # apply deterministic Copilot auth behavior without relying on host heuristics. + # Omit to use the default github.com behavior. + # (optional) + platform: "ghes" + # Container mounts to add when using AWF. Each mount is specified using Docker # mount syntax: 'source:destination:mode' where mode can be 'ro' (read-only) or # 'rw' (read-write). Example: '/host/path:/container/path:ro' diff --git a/pkg/parser/schema_test.go b/pkg/parser/schema_test.go index 6ffd4e20b88..c6fcfaabcf1 100644 --- a/pkg/parser/schema_test.go +++ b/pkg/parser/schema_test.go @@ -705,6 +705,42 @@ func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxDailyAICreditsN } } +func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_SandboxAgentPlatform(t *testing.T) { + t.Run("valid platform is accepted", func(t *testing.T) { + frontmatter := map[string]any{ + "on": "push", + "sandbox": map[string]any{ + "agent": map[string]any{ + "id": "awf", + "platform": "ghes", + }, + }, + } + + err := ValidateMainWorkflowFrontmatterWithSchemaAndLocation(frontmatter, "/tmp/gh-aw/awf-platform-ghes-test.md") + if err != nil { + t.Fatalf("expected sandbox.agent.platform=ghes to pass schema validation, got: %v", err) + } + }) + + t.Run("unknown platform is rejected", func(t *testing.T) { + frontmatter := map[string]any{ + "on": "push", + "sandbox": map[string]any{ + "agent": map[string]any{ + "id": "awf", + "platform": "github-enterprise", + }, + }, + } + + err := ValidateMainWorkflowFrontmatterWithSchemaAndLocation(frontmatter, "/tmp/gh-aw/awf-platform-invalid-test.md") + if err == nil { + t.Fatal("expected sandbox.agent.platform=github-enterprise to fail schema validation") + } + }) +} + func TestMainWorkflowSchema_WorkflowDispatchNumberTypeDocumentation(t *testing.T) { t.Parallel() diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index d8a83d0f8f1..ab4194475eb 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -3252,6 +3252,11 @@ "type": "string", "description": "AWF version override used to install and run the matching firewall version." }, + "platform": { + "type": "string", + "enum": ["github.com", "ghes", "ghec", "ghec-self-hosted"], + "description": "AWF platform.type override. Declares the GitHub deployment type so AWF can apply deterministic Copilot auth behavior without relying on host heuristics. Omit to use the default github.com behavior." + }, "command": { "type": "string", "x-internal": true, diff --git a/pkg/workflow/awf_config.go b/pkg/workflow/awf_config.go index 473b63a62d4..dc17dcce444 100644 --- a/pkg/workflow/awf_config.go +++ b/pkg/workflow/awf_config.go @@ -162,6 +162,9 @@ type AWFConfigFile struct { // Network contains network egress control configuration. Network *AWFNetworkConfig `json:"network,omitempty"` + // Platform contains GitHub deployment metadata used by AWF auth handling. + Platform *AWFPlatformConfig `json:"platform,omitempty"` + // APIProxy contains API proxy (LLM gateway) configuration. APIProxy *AWFAPIProxyConfig `json:"apiProxy,omitempty"` @@ -186,6 +189,12 @@ type AWFNetworkConfig struct { BlockDomains []string `json:"blockDomains,omitempty"` } +// AWFPlatformConfig is the "platform" section of the AWF config file. +type AWFPlatformConfig struct { + // Type is the GitHub deployment type consumed by AWF for auth behavior. + Type string `json:"type,omitempty"` +} + // AWFAPIProxyConfig is the "apiProxy" section of the AWF config file. // It maps to the --enable-api-proxy and --*-api-target CLI flags. type AWFAPIProxyConfig struct { @@ -352,6 +361,11 @@ func BuildAWFConfigJSON(config AWFCommandConfig) (string, error) { } } + if platformType := extractPlatformType(config.WorkflowData); platformType != "" { + awfConfig.Platform = &AWFPlatformConfig{Type: platformType} + awfConfigLog.Printf("Platform section: type=%s", platformType) + } + // ── API proxy section ───────────────────────────────────────────────────── // maxAICredits is taken from frontmatter/imports only; when unset (0) the // runtime value is resolved from vars.GH_AW_DEFAULT_MAX_AI_CREDITS via a @@ -517,6 +531,13 @@ func extractModelMultipliers(workflowData *WorkflowData) map[string]float64 { return workflowData.EngineConfig.TokenWeights.Multipliers } +func extractPlatformType(workflowData *WorkflowData) string { + if workflowData == nil || workflowData.SandboxConfig == nil || workflowData.SandboxConfig.Agent == nil { + return "" + } + return workflowData.SandboxConfig.Agent.Platform +} + // extractModelFallback returns an AWFModelFallbackConfig if the workflow has configured // sandbox.agent.model-fallback, or nil if the field is absent (letting AWF use its default). func extractModelFallback(workflowData *WorkflowData) *AWFModelFallbackConfig { diff --git a/pkg/workflow/awf_config_test.go b/pkg/workflow/awf_config_test.go index 37e1b168009..69b3d104ac9 100644 --- a/pkg/workflow/awf_config_test.go +++ b/pkg/workflow/awf_config_test.go @@ -695,6 +695,51 @@ func TestBuildAWFConfigJSON(t *testing.T) { assert.NotContains(t, jsonStr, `"authHeader"`, "authHeader should be absent when not configured") }) + t.Run("sandbox agent platform is emitted in awf platform config", func(t *testing.T) { + config := AWFCommandConfig{ + EngineName: "copilot", + AllowedDomains: "github.com", + WorkflowData: &WorkflowData{ + EngineConfig: &EngineConfig{ID: "copilot"}, + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{Enabled: true}, + }, + SandboxConfig: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + Type: SandboxTypeAWF, + Platform: "ghes", + }, + }, + }, + } + + jsonStr, err := BuildAWFConfigJSON(config) + require.NoError(t, err) + assert.Contains(t, jsonStr, `"platform":{"type":"ghes"}`, "should include AWF platform.type when configured") + }) + + t.Run("platform config is omitted when sandbox agent platform is not configured", func(t *testing.T) { + config := AWFCommandConfig{ + EngineName: "copilot", + AllowedDomains: "github.com", + WorkflowData: &WorkflowData{ + EngineConfig: &EngineConfig{ID: "copilot"}, + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{Enabled: true}, + }, + SandboxConfig: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + Type: SandboxTypeAWF, + }, + }, + }, + } + + jsonStr, err := BuildAWFConfigJSON(config) + require.NoError(t, err) + assert.NotContains(t, jsonStr, `"platform":`, "platform section should be absent when sandbox.agent.platform is unset") + }) + t.Run("model-fallback is emitted when enabled is explicitly set to false", func(t *testing.T) { disabled := TemplatableBool("false") config := AWFCommandConfig{ @@ -1196,6 +1241,31 @@ func TestBuildAWFCommand_UsesConfigFile(t *testing.T) { assert.Contains(t, command, `\"enabled\":true`, "config JSON should have apiProxy enabled") } +func TestBuildAWFCommand_EmbedsPlatformConfig(t *testing.T) { + config := AWFCommandConfig{ + EngineName: "copilot", + EngineCommand: "copilot --prompt-file /tmp/prompt.txt", + LogFile: "/tmp/gh-aw/agent-stdio.log", + AllowedDomains: "github.com", + WorkflowData: &WorkflowData{ + EngineConfig: &EngineConfig{ID: "copilot"}, + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{Enabled: true}, + }, + SandboxConfig: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + Type: SandboxTypeAWF, + Platform: "ghes", + }, + }, + }, + } + + command := BuildAWFCommand(config) + + assert.Contains(t, command, `\"platform\":{\"type\":\"ghes\"}`, "expected awf-config JSON in command to include platform.type") +} + func TestBuildAWFCommand_ResolvesMaxAICreditsFromEnv(t *testing.T) { tests := []struct { name string diff --git a/pkg/workflow/frontmatter_extraction_security.go b/pkg/workflow/frontmatter_extraction_security.go index 8c861b2ab28..e5480169459 100644 --- a/pkg/workflow/frontmatter_extraction_security.go +++ b/pkg/workflow/frontmatter_extraction_security.go @@ -197,6 +197,13 @@ func (c *Compiler) extractAgentSandboxConfig(agentVal any) *AgentSandboxConfig { } } + // Extract platform (AWF platform.type override) + if platformVal, hasPlatform := agentObj["platform"]; hasPlatform { + if platformStr, ok := platformVal.(string); ok { + agentConfig.Platform = platformStr + } + } + // Extract config for SRT if configVal, hasConfig := agentObj["config"]; hasConfig { agentConfig.Config = c.extractSRTConfig(configVal) diff --git a/pkg/workflow/frontmatter_extraction_security_test.go b/pkg/workflow/frontmatter_extraction_security_test.go index 0835d123491..414df3ea474 100644 --- a/pkg/workflow/frontmatter_extraction_security_test.go +++ b/pkg/workflow/frontmatter_extraction_security_test.go @@ -24,6 +24,21 @@ func TestExtractAgentSandboxConfigVersion(t *testing.T) { }) } +func TestExtractAgentSandboxConfigPlatform(t *testing.T) { + compiler := &Compiler{} + + t.Run("extracts sandbox.agent.platform from object format", func(t *testing.T) { + agentObj := map[string]any{ + "id": "awf", + "platform": "ghes", + } + + config := compiler.extractAgentSandboxConfig(agentObj) + require.NotNil(t, config, "Should extract agent sandbox config") + assert.Equal(t, "ghes", config.Platform, "Should extract sandbox.agent.platform") + }) +} + func TestExtractAgentSandboxConfigModelFallback(t *testing.T) { compiler := &Compiler{} diff --git a/pkg/workflow/frontmatter_types_test.go b/pkg/workflow/frontmatter_types_test.go index 49345fb7f61..477ac3ea9dc 100644 --- a/pkg/workflow/frontmatter_types_test.go +++ b/pkg/workflow/frontmatter_types_test.go @@ -258,7 +258,8 @@ func TestParseFrontmatterConfig(t *testing.T) { frontmatter := map[string]any{ "sandbox": map[string]any{ "agent": map[string]any{ - "type": "awf", + "type": "awf", + "platform": "ghes", }, }, } @@ -271,6 +272,12 @@ func TestParseFrontmatterConfig(t *testing.T) { if config.Sandbox == nil { t.Fatal("Sandbox should not be nil") } + if config.Sandbox.Agent == nil { + t.Fatal("Sandbox.Agent should not be nil") + } + if config.Sandbox.Agent.Platform != "ghes" { + t.Fatalf("Sandbox.Agent.Platform = %q, want %q", config.Sandbox.Agent.Platform, "ghes") + } }) t.Run("handles observability configuration", func(t *testing.T) { diff --git a/pkg/workflow/sandbox.go b/pkg/workflow/sandbox.go index 45d021f19d0..cf48a01bafc 100644 --- a/pkg/workflow/sandbox.go +++ b/pkg/workflow/sandbox.go @@ -46,19 +46,20 @@ type SandboxConfig struct { // AgentSandboxConfig represents the agent sandbox configuration type AgentSandboxConfig struct { - ID string `yaml:"id,omitempty"` // Agent ID: "awf" or "srt" (replaces Type in new object format) - Type SandboxType `yaml:"type,omitempty"` // Sandbox type: "awf" or "srt" (legacy, use ID instead) - Version string `yaml:"version,omitempty"` // AWF version override used to install and run the matching firewall version - Disabled bool `yaml:"-"` // True when agent is explicitly set to false (disables firewall). This is a runtime flag, not serialized to YAML. - DisableReason string `yaml:"-"` // Operator-authored justification from dangerously-disable-sandbox-agent feature; available for diagnostics and audit logging. - Config *SandboxRuntimeConfig `yaml:"config,omitempty"` // Custom SRT config (optional) - Command string `yaml:"command,omitempty"` // Custom command to replace AWF or SRT installation - Args []string `yaml:"args,omitempty"` // Additional arguments to append to the command - Env map[string]string `yaml:"env,omitempty"` // Environment variables to set on the step - Mounts []string `yaml:"mounts,omitempty"` // Container mounts to add for AWF (format: "source:dest:mode") - Memory string `yaml:"memory,omitempty"` // Memory limit for the AWF container (e.g., "4g", "8g") - ModelFallback *TemplatableBool `yaml:"model-fallback,omitempty"` // AWF API proxy model fallback enable/disable flag (optional) - Targets map[string]*AgentAPIProxyTargetConfig `yaml:"targets,omitempty"` // Per-provider API proxy target overrides keyed by provider name (e.g. "openai", "anthropic") + ID string `yaml:"id,omitempty"` // Agent ID: "awf" or "srt" (replaces Type in new object format) + Type SandboxType `yaml:"type,omitempty"` // Sandbox type: "awf" or "srt" (legacy, use ID instead) + Version string `yaml:"version,omitempty"` // AWF version override used to install and run the matching firewall version + Platform string `yaml:"platform,omitempty" json:"platform,omitempty"` // AWF platform.type override (github.com, ghes, ghec, ghec-self-hosted) + Disabled bool `yaml:"-"` // True when agent is explicitly set to false (disables firewall). This is a runtime flag, not serialized to YAML. + DisableReason string `yaml:"-"` // Operator-authored justification from dangerously-disable-sandbox-agent feature; available for diagnostics and audit logging. + Config *SandboxRuntimeConfig `yaml:"config,omitempty"` // Custom SRT config (optional) + Command string `yaml:"command,omitempty"` // Custom command to replace AWF or SRT installation + Args []string `yaml:"args,omitempty"` // Additional arguments to append to the command + Env map[string]string `yaml:"env,omitempty"` // Environment variables to set on the step + Mounts []string `yaml:"mounts,omitempty"` // Container mounts to add for AWF (format: "source:dest:mode") + Memory string `yaml:"memory,omitempty"` // Memory limit for the AWF container (e.g., "4g", "8g") + ModelFallback *TemplatableBool `yaml:"model-fallback,omitempty"` // AWF API proxy model fallback enable/disable flag (optional) + Targets map[string]*AgentAPIProxyTargetConfig `yaml:"targets,omitempty"` // Per-provider API proxy target overrides keyed by provider name (e.g. "openai", "anthropic") } // AgentAPIProxyTargetConfig configures a single LLM provider's API proxy target. From 192ea8bca8ccce58e018c6d49946be031b7d6c27 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 22 Jun 2026 16:16:32 -0700 Subject: [PATCH 3/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- pkg/workflow/sandbox.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/workflow/sandbox.go b/pkg/workflow/sandbox.go index cf48a01bafc..e3aaa655d99 100644 --- a/pkg/workflow/sandbox.go +++ b/pkg/workflow/sandbox.go @@ -46,11 +46,11 @@ type SandboxConfig struct { // AgentSandboxConfig represents the agent sandbox configuration type AgentSandboxConfig struct { - ID string `yaml:"id,omitempty"` // Agent ID: "awf" or "srt" (replaces Type in new object format) - Type SandboxType `yaml:"type,omitempty"` // Sandbox type: "awf" or "srt" (legacy, use ID instead) - Version string `yaml:"version,omitempty"` // AWF version override used to install and run the matching firewall version - Platform string `yaml:"platform,omitempty" json:"platform,omitempty"` // AWF platform.type override (github.com, ghes, ghec, ghec-self-hosted) - Disabled bool `yaml:"-"` // True when agent is explicitly set to false (disables firewall). This is a runtime flag, not serialized to YAML. + ID string `yaml:"id,omitempty"` // Agent ID: "awf" or "srt" (replaces Type in new object format) + Type SandboxType `yaml:"type,omitempty"` // Sandbox type: "awf" or "srt" (legacy, use ID instead) + Version string `yaml:"version,omitempty"` // AWF version override used to install and run the matching firewall version + Platform string `yaml:"platform,omitempty"` // AWF platform.type override (github.com, ghes, ghec, ghec-self-hosted) + Disabled bool `yaml:"-"` // True when agent is explicitly set to false (disables firewall). This is a runtime flag, not serialized to YAML. DisableReason string `yaml:"-"` // Operator-authored justification from dangerously-disable-sandbox-agent feature; available for diagnostics and audit logging. Config *SandboxRuntimeConfig `yaml:"config,omitempty"` // Custom SRT config (optional) Command string `yaml:"command,omitempty"` // Custom command to replace AWF or SRT installation From ca59d4eebf2fbeb8ab2883ba6da7491b6c1613c5 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 22 Jun 2026 16:16:43 -0700 Subject: [PATCH 4/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- pkg/workflow/awf_config.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/workflow/awf_config.go b/pkg/workflow/awf_config.go index dc17dcce444..8644975727d 100644 --- a/pkg/workflow/awf_config.go +++ b/pkg/workflow/awf_config.go @@ -535,6 +535,12 @@ func extractPlatformType(workflowData *WorkflowData) string { if workflowData == nil || workflowData.SandboxConfig == nil || workflowData.SandboxConfig.Agent == nil { return "" } + if workflowData.SandboxConfig.Agent.Disabled { + return "" + } + if !isSupportedSandboxType(getAgentType(workflowData.SandboxConfig.Agent)) { + return "" + } return workflowData.SandboxConfig.Agent.Platform } From caf390d8c156967078eaa20836f10811871ef305 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 22 Jun 2026 16:16:54 -0700 Subject: [PATCH 5/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- pkg/parser/schemas/main_workflow_schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index ab4194475eb..e8abbf541c9 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -3255,8 +3255,8 @@ "platform": { "type": "string", "enum": ["github.com", "ghes", "ghec", "ghec-self-hosted"], - "description": "AWF platform.type override. Declares the GitHub deployment type so AWF can apply deterministic Copilot auth behavior without relying on host heuristics. Omit to use the default github.com behavior." - }, + "description": "AWF platform.type override. Declares the GitHub deployment type so AWF can apply deterministic Copilot auth behavior without relying on host heuristics. Omit to let AWF use its default host heuristic behavior." + } "command": { "type": "string", "x-internal": true, From 18f2d82de10ed6212bfa8fd24abcaff7ece0ce68 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 22 Jun 2026 16:17:12 -0700 Subject: [PATCH 6/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/src/content/docs/reference/frontmatter-full.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index a28a1104cc3..674d24e70fc 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -1870,7 +1870,7 @@ sandbox: # AWF platform.type override. Declares the GitHub deployment type so AWF can # apply deterministic Copilot auth behavior without relying on host heuristics. - # Omit to use the default github.com behavior. + # Omit to let AWF use its default host heuristic behavior. # (optional) platform: "ghes" From c723081f79d67455d2ab89bb1cdd996b8a407381 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 23:48:32 +0000 Subject: [PATCH 7/8] Plan PR finishing work Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/agentic_commands.yml | 139 ---- .github/workflows/agentics-maintenance.yml | 858 --------------------- 2 files changed, 997 deletions(-) delete mode 100644 .github/workflows/agentic_commands.yml delete mode 100644 .github/workflows/agentics-maintenance.yml diff --git a/.github/workflows/agentic_commands.yml b/.github/workflows/agentic_commands.yml deleted file mode 100644 index 20541b5a12b..00000000000 --- a/.github/workflows/agentic_commands.yml +++ /dev/null @@ -1,139 +0,0 @@ -# gh-aw-commands: {"payload_version":"v1","schema_version":"v1","compiler_version":"dev","commands":["*","ace","approach-validator","archie","brave","cloclo","craft","dependabot-burner","grumpy","matt","mergefest","nit","plan","poem-bot","review","ruflo","scout","security-review","smoke-agent-all-merged","smoke-agent-all-none","smoke-agent-public-approved","smoke-agent-public-none","smoke-agent-scoped-approved","smoke-antigravity","smoke-call-workflow","smoke-claude","smoke-codex","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-arm","smoke-copilot-sdk","smoke-create-cross-repo-pr","smoke-crush","smoke-gemini","smoke-multi-pr","smoke-opencode","smoke-otel-backends","smoke-pi","smoke-project","smoke-service-ports","smoke-temporary-id","smoke-test-tools","smoke-update-cross-repo-pr","summarize","tidy","unbloat"],"workflows":["ace-editor","approach-validator","archie","brave","ci-doctor","cloclo","craft","dependabot-burner","design-decision-gate","dev","grumpy-reviewer","mattpocock-skills-reviewer","mergefest","necromancer","pdf-summary","plan","poem-bot","pr-code-quality-reviewer","pr-nitpick-reviewer","ruflo-backed-task","scout","security-review","skillet","smoke-agent-all-merged","smoke-agent-all-none","smoke-agent-public-approved","smoke-agent-public-none","smoke-agent-scoped-approved","smoke-antigravity","smoke-call-workflow","smoke-claude","smoke-codex","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-arm","smoke-copilot-sdk","smoke-create-cross-repo-pr","smoke-crush","smoke-gemini","smoke-multi-pr","smoke-opencode","smoke-otel-backends","smoke-pi","smoke-project","smoke-service-ports","smoke-temporary-id","smoke-test-tools","smoke-update-cross-repo-pr","test-quality-sentinel","tidy","unbloat-docs"]} -# Routing summary (sorted): -# slash commands: -# /* -> skillet [pull_request_comment,pull_request_review_comment] reaction=eyes -# /ace -> ace-editor [pull_request_comment] reaction=eyes -# /approach-validator -> approach-validator [issue_comment,pull_request_comment] reaction=eyes -# /archie -> archie [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /brave -> brave [issue_comment] reaction=eyes -# /cloclo -> cloclo [discussion,discussion_comment,issue_comment,issues,pull_request,pull_request_comment,pull_request_review_comment] reaction=eyes -# /craft -> craft [issues] reaction=eyes -# /dependabot-burner -> dependabot-burner [pull_request_comment,pull_request_review_comment] reaction=eyes -# /grumpy -> grumpy-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes -# /matt -> mattpocock-skills-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes -# /mergefest -> mergefest [pull_request_comment] reaction=eyes -# /nit -> pr-nitpick-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes -# /plan -> plan [discussion_comment,issue_comment] reaction=eyes -# /poem-bot -> poem-bot [issues] reaction=eyes -# /review -> design-decision-gate [pull_request_comment,pull_request_review_comment] reaction=eyes -# /review -> pr-code-quality-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes -# /review -> test-quality-sentinel [pull_request_comment,pull_request_review_comment] reaction=eyes -# /ruflo -> ruflo-backed-task [issue_comment] reaction=eyes -# /scout -> scout [discussion,discussion_comment,issue_comment,issues,pull_request,pull_request_comment,pull_request_review_comment] reaction=eyes -# /security-review -> security-review [pull_request_comment,pull_request_review_comment] reaction=eyes -# /smoke-agent-all-merged -> smoke-agent-all-merged [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-agent-all-none -> smoke-agent-all-none [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-agent-public-approved -> smoke-agent-public-approved [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-agent-public-none -> smoke-agent-public-none [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-agent-scoped-approved -> smoke-agent-scoped-approved [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-antigravity -> smoke-antigravity [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket -# /smoke-call-workflow -> smoke-call-workflow [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-claude -> smoke-claude [issue_comment,issues,pull_request,pull_request_comment] reaction=heart -# /smoke-codex -> smoke-codex [issue_comment,issues,pull_request,pull_request_comment] reaction=hooray -# /smoke-copilot -> smoke-copilot [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-copilot-aoai-apikey -> smoke-copilot-aoai-apikey [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-copilot-aoai-entra -> smoke-copilot-aoai-entra [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-copilot-arm -> smoke-copilot-arm [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-copilot-sdk -> smoke-copilot-sdk [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-create-cross-repo-pr -> smoke-create-cross-repo-pr [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-crush -> smoke-crush [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-gemini -> smoke-gemini [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket -# /smoke-multi-pr -> smoke-multi-pr [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-opencode -> smoke-opencode [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket -# /smoke-otel-backends -> smoke-otel-backends [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-pi -> smoke-pi [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket -# /smoke-project -> smoke-project [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-service-ports -> smoke-service-ports [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-temporary-id -> smoke-temporary-id [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-test-tools -> smoke-test-tools [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /smoke-update-cross-repo-pr -> smoke-update-cross-repo-pr [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes -# /summarize -> pdf-summary [issue_comment,issues] reaction=eyes -# /tidy -> tidy [pull_request_comment] reaction=eyes -# /unbloat -> unbloat-docs [pull_request_comment] reaction=eyes -# labels: -# approach-proposal -> approach-validator [issues,pull_request] reaction=eyes -# ci-doctor -> ci-doctor [pull_request] reaction=eyes -# cloclo -> cloclo [discussion,issues,pull_request] reaction=eyes -# dev -> dev [discussion,issues,pull_request] reaction=eyes -# necromancer -> necromancer [pull_request] reaction=eyes -# needs-design -> approach-validator [issues,pull_request] reaction=eyes -# smoke -> smoke-copilot [pull_request] reaction=eyes -# smoke -> smoke-copilot-aoai-apikey [pull_request] reaction=eyes -# smoke -> smoke-copilot-aoai-entra [pull_request] reaction=eyes -# smoke -> smoke-otel-backends [pull_request] reaction=eyes -# smoke-sdk -> smoke-copilot-sdk [pull_request] reaction=eyes -# This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md -# -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ -# | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ -# \_| |_/\__, |\___|_| |_|\__|_|\___| -# __/ | -# _ _ |___/ -# | | | | / _| | -# | | | | ___ _ __ _ __| |_| | _____ ____ -# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| -# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ -# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ -# -# -# To regenerate this workflow, run: -# gh aw compile -# Not all edits will cause changes to this file. -# -# For more information: https://github.github.com/gh-aw/introduction/overview/ -# -name: "Agentic Commands" - -on: - issues: - types: [edited, labeled, opened, reopened] - issue_comment: - types: [created, edited] - pull_request: - types: [edited, labeled, opened, reopened] - pull_request_review_comment: - types: [created, edited] - discussion: - types: [created, edited, labeled] - discussion_comment: - types: [created, edited] - -permissions: {} - -jobs: - route: - runs-on: ubuntu-slim - timeout-minutes: 15 - permissions: - actions: write - contents: read - issues: write - pull-requests: write - discussions: write - - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Route slash command - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_SLASH_ROUTING: '{"*":[{"workflow":"skillet","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"ace":[{"workflow":"ace-editor","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"approach-validator":[{"workflow":"approach-validator","events":["issue_comment","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"archie":[{"workflow":"archie","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"brave":[{"workflow":"brave","events":["issue_comment"],"ai_reaction":"eyes","status_comment":true}],"cloclo":[{"workflow":"cloclo","events":["discussion","discussion_comment","issue_comment","issues","pull_request","pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"craft":[{"workflow":"craft","events":["issues"],"ai_reaction":"eyes","status_comment":true}],"dependabot-burner":[{"workflow":"dependabot-burner","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"grumpy":[{"workflow":"grumpy-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"matt":[{"workflow":"mattpocock-skills-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"mergefest":[{"workflow":"mergefest","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"nit":[{"workflow":"pr-nitpick-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"plan":[{"workflow":"plan","events":["discussion_comment","issue_comment"],"ai_reaction":"eyes","status_comment":true}],"poem-bot":[{"workflow":"poem-bot","events":["issues"],"ai_reaction":"eyes","status_comment":true}],"review":[{"workflow":"design-decision-gate","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true},{"workflow":"pr-code-quality-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true},{"workflow":"test-quality-sentinel","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"ruflo":[{"workflow":"ruflo-backed-task","events":["issue_comment"],"ai_reaction":"eyes","status_comment":true}],"scout":[{"workflow":"scout","events":["discussion","discussion_comment","issue_comment","issues","pull_request","pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"security-review":[{"workflow":"security-review","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-all-merged":[{"workflow":"smoke-agent-all-merged","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-all-none":[{"workflow":"smoke-agent-all-none","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-public-approved":[{"workflow":"smoke-agent-public-approved","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-public-none":[{"workflow":"smoke-agent-public-none","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-scoped-approved":[{"workflow":"smoke-agent-scoped-approved","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-antigravity":[{"workflow":"smoke-antigravity","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-call-workflow":[{"workflow":"smoke-call-workflow","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-claude":[{"workflow":"smoke-claude","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"heart","status_comment":true}],"smoke-codex":[{"workflow":"smoke-codex","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"hooray","status_comment":true}],"smoke-copilot":[{"workflow":"smoke-copilot","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-aoai-apikey":[{"workflow":"smoke-copilot-aoai-apikey","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-aoai-entra":[{"workflow":"smoke-copilot-aoai-entra","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-arm":[{"workflow":"smoke-copilot-arm","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-sdk":[{"workflow":"smoke-copilot-sdk","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-create-cross-repo-pr":[{"workflow":"smoke-create-cross-repo-pr","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-crush":[{"workflow":"smoke-crush","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-gemini":[{"workflow":"smoke-gemini","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-multi-pr":[{"workflow":"smoke-multi-pr","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-opencode":[{"workflow":"smoke-opencode","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-otel-backends":[{"workflow":"smoke-otel-backends","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-pi":[{"workflow":"smoke-pi","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-project":[{"workflow":"smoke-project","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-service-ports":[{"workflow":"smoke-service-ports","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-temporary-id":[{"workflow":"smoke-temporary-id","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-test-tools":[{"workflow":"smoke-test-tools","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-update-cross-repo-pr":[{"workflow":"smoke-update-cross-repo-pr","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"summarize":[{"workflow":"pdf-summary","events":["issue_comment","issues"],"ai_reaction":"eyes","status_comment":true}],"tidy":[{"workflow":"tidy","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"unbloat":[{"workflow":"unbloat-docs","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}]}' - GH_AW_LABEL_ROUTING: '{"approach-proposal":[{"workflow":"approach-validator","events":["issues","pull_request"],"ai_reaction":"eyes"}],"ci-doctor":[{"workflow":"ci-doctor","events":["pull_request"],"ai_reaction":"eyes"}],"cloclo":[{"workflow":"cloclo","events":["discussion","issues","pull_request"],"ai_reaction":"eyes"}],"dev":[{"workflow":"dev","events":["discussion","issues","pull_request"],"ai_reaction":"eyes"}],"necromancer":[{"workflow":"necromancer","events":["pull_request"],"ai_reaction":"eyes"}],"needs-design":[{"workflow":"approach-validator","events":["issues","pull_request"],"ai_reaction":"eyes"}],"smoke":[{"workflow":"smoke-copilot","events":["pull_request"],"ai_reaction":"eyes"},{"workflow":"smoke-copilot-aoai-apikey","events":["pull_request"],"ai_reaction":"eyes"},{"workflow":"smoke-copilot-aoai-entra","events":["pull_request"],"ai_reaction":"eyes"},{"workflow":"smoke-otel-backends","events":["pull_request"],"ai_reaction":"eyes"}],"smoke-sdk":[{"workflow":"smoke-copilot-sdk","events":["pull_request"],"ai_reaction":"eyes"}]}' - GH_AW_HELP_COMMANDS: '[{"command":"*","description":"Reviews pull requests by mapping any slash command to a matching repository skill under .github/skills","centralized":true,"decentralized":false,"source_file":"skillet"},{"command":"ace","description":"Generates an ACE editor session link when invoked with /ace command on pull request comments","centralized":true,"decentralized":false,"source_file":"ace-editor"},{"command":"approach-validator","description":"Validates proposed technical approaches before implementation begins using a sequential multi-agent panel of Devil''s Advocate, Alternatives Scout, Implementation Estimator, and Dead End Detector","centralized":true,"decentralized":false,"source_file":"approach-validator"},{"command":"archie","description":"Generates Mermaid diagrams to visualize issue and pull request relationships when invoked with the /archie command","centralized":true,"decentralized":false,"source_file":"archie"},{"command":"brave","description":"Performs web searches using Brave search engine when invoked with /brave command in issues or PRs","centralized":true,"decentralized":false,"source_file":"brave"},{"command":"cloclo","centralized":true,"decentralized":false,"source_file":"cloclo"},{"command":"craft","description":"Generates new agentic workflow markdown files based on user requests when invoked with /craft command","centralized":true,"decentralized":false,"source_file":"craft"},{"command":"dependabot-burner","description":"Runs one grouped Dependabot remediation wave from schedule, manual dispatch, or /dependabot-burner on pull requests","centralized":true,"decentralized":false,"source_file":"dependabot-burner"},{"command":"grumpy","description":"⚠️ DEPRECATED: Use PR Code Quality Reviewer (pr-code-quality-reviewer) instead. Performs critical code review with a focus on edge cases, potential bugs, and code quality issues","centralized":true,"decentralized":false,"source_file":"grumpy-reviewer"},{"command":"matt","description":"Reviews pull requests using Matt Pocock''s engineering skills to provide targeted, high-quality improvement suggestions based on the type of changes","centralized":true,"decentralized":false,"source_file":"mattpocock-skills-reviewer"},{"command":"mergefest","description":"Automatically merges the main branch into pull request branches when invoked with /mergefest command","centralized":true,"decentralized":false,"source_file":"mergefest"},{"command":"nit","description":"⚠️ DEPRECATED: Use PR Code Quality Reviewer (pr-code-quality-reviewer) instead. Provides detailed nitpicky code review focusing on style, best practices, and minor improvements","centralized":true,"decentralized":false,"source_file":"pr-nitpick-reviewer"},{"command":"plan","description":"Generates project plans and task breakdowns when invoked with /plan command in issues or PRs","centralized":true,"decentralized":false,"source_file":"plan"},{"command":"poem-bot","description":"Generates creative poems on specified themes when invoked with /poem-bot command","centralized":true,"decentralized":false,"source_file":"poem-bot"},{"command":"q","description":"Intelligent assistant that answers questions, analyzes repositories, and can create PRs for workflow optimizations","centralized":false,"decentralized":true,"source_file":"q"},{"command":"review","description":"Enforces Architecture Decision Records (ADRs) before implementation work can merge, detecting missing design decisions and generating draft ADRs using AI analysis","centralized":true,"decentralized":false,"source_file":"design-decision-gate"},{"command":"ruflo","description":"Runs a repository task inside GitHub Agentic Workflows while delegating inner planning and coordination to Ruflo","centralized":true,"decentralized":false,"source_file":"ruflo-backed-task"},{"command":"scout","description":"Performs deep research investigations using web search to gather and synthesize comprehensive information on any topic","centralized":true,"decentralized":false,"source_file":"scout"},{"command":"security-review","description":"Security-focused AI agent that reviews pull requests to identify changes that could weaken security posture or extend AWF boundaries","centralized":true,"decentralized":false,"source_file":"security-review"},{"command":"smoke-agent-all-merged","description":"Guard policy smoke test: repos=all, min-integrity=merged (most restrictive)","centralized":true,"decentralized":false,"source_file":"smoke-agent-all-merged"},{"command":"smoke-agent-all-none","description":"Guard policy smoke test: repos=all, min-integrity=none (most permissive)","centralized":true,"decentralized":false,"source_file":"smoke-agent-all-none"},{"command":"smoke-agent-public-approved","description":"Smoke test that validates assign-to-agent with the agentic-workflows custom agent","centralized":true,"decentralized":false,"source_file":"smoke-agent-public-approved"},{"command":"smoke-agent-public-none","description":"Guard policy smoke test: repos=public, min-integrity=none","centralized":true,"decentralized":false,"source_file":"smoke-agent-public-none"},{"command":"smoke-agent-scoped-approved","description":"Guard policy smoke test: repos=[github/gh-aw, github/*], min-integrity=approved (scoped patterns)","centralized":true,"decentralized":false,"source_file":"smoke-agent-scoped-approved"},{"command":"smoke-antigravity","description":"Smoke test workflow that validates Antigravity engine functionality twice daily","centralized":true,"decentralized":false,"source_file":"smoke-antigravity"},{"command":"smoke-call-workflow","description":"Smoke test for the call-workflow safe output - orchestrator that calls a worker via workflow_call at compile-time fan-out","centralized":true,"decentralized":false,"source_file":"smoke-call-workflow"},{"command":"smoke-claude","description":"Smoke test workflow that validates Claude engine functionality by reviewing recent PRs twice daily","centralized":true,"decentralized":false,"source_file":"smoke-claude"},{"command":"smoke-codex","description":"Smoke test workflow that validates Codex engine functionality by reviewing recent PRs twice daily","centralized":true,"decentralized":false,"source_file":"smoke-codex"},{"command":"smoke-copilot","description":"Smoke Copilot","centralized":true,"decentralized":false,"source_file":"smoke-copilot"},{"command":"smoke-copilot-aoai-apikey","description":"Smoke Copilot - AOAI (apikey)","centralized":true,"decentralized":false,"source_file":"smoke-copilot-aoai-apikey"},{"command":"smoke-copilot-aoai-entra","description":"Smoke Copilot - AOAI (Entra)","centralized":true,"decentralized":false,"source_file":"smoke-copilot-aoai-entra"},{"command":"smoke-copilot-arm","description":"Smoke Copilot ARM64","centralized":true,"decentralized":false,"source_file":"smoke-copilot-arm"},{"command":"smoke-copilot-sdk","description":"Smoke Copilot SDK","centralized":true,"decentralized":false,"source_file":"smoke-copilot-sdk"},{"command":"smoke-create-cross-repo-pr","description":"Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo","centralized":true,"decentralized":false,"source_file":"smoke-create-cross-repo-pr"},{"command":"smoke-crush","description":"Smoke test workflow that validates Crush engine functionality","centralized":true,"decentralized":false,"source_file":"smoke-crush"},{"command":"smoke-gemini","description":"Smoke test workflow that validates Gemini engine functionality twice daily","centralized":true,"decentralized":false,"source_file":"smoke-gemini"},{"command":"smoke-multi-pr","description":"Test creating multiple pull requests in a single workflow run","centralized":true,"decentralized":false,"source_file":"smoke-multi-pr"},{"command":"smoke-opencode","description":"Smoke test workflow that validates OpenCode engine functionality","centralized":true,"decentralized":false,"source_file":"smoke-opencode"},{"command":"smoke-otel-backends","description":"Smoke test that validates OTEL span export and query access for Sentry, Grafana, and Datadog","centralized":true,"decentralized":false,"source_file":"smoke-otel-backends"},{"command":"smoke-pi","description":"Smoke test workflow that validates Pi engine functionality","centralized":true,"decentralized":false,"source_file":"smoke-pi"},{"command":"smoke-project","description":"Smoke Project - Test project operations","centralized":true,"decentralized":false,"source_file":"smoke-project"},{"command":"smoke-service-ports","description":"Smoke test to validate --allow-host-service-ports with Redis service container","centralized":true,"decentralized":false,"source_file":"smoke-service-ports"},{"command":"smoke-temporary-id","description":"Test temporary ID functionality for issue chaining and cross-references","centralized":true,"decentralized":false,"source_file":"smoke-temporary-id"},{"command":"smoke-test-tools","description":"Smoke test to validate common development tools are available in the agent container","centralized":true,"decentralized":false,"source_file":"smoke-test-tools"},{"command":"smoke-update-cross-repo-pr","description":"Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer''s Odyssey to the README","centralized":true,"decentralized":false,"source_file":"smoke-update-cross-repo-pr"},{"command":"summarize","description":"pdf summarizer","centralized":true,"decentralized":false,"source_file":"pdf-summary"},{"command":"tidy","description":"Automatically formats and tidies code files (Go, JS, TypeScript) when code changes are pushed or on command","centralized":true,"decentralized":false,"source_file":"tidy"},{"command":"unbloat","description":"Reviews and simplifies documentation by reducing verbosity while maintaining clarity and completeness","centralized":true,"decentralized":false,"source_file":"unbloat-docs"},{"command":"approach-proposal","description":"Validates proposed technical approaches before implementation begins using a sequential multi-agent panel of Devil''s Advocate, Alternatives Scout, Implementation Estimator, and Dead End Detector","centralized":false,"decentralized":false,"label":true,"source_file":"approach-validator"},{"command":"ci-doctor","description":"Investigates failed CI workflows to identify root causes and patterns, creating issues with diagnostic information; also reviews PR check failures when the ci-doctor label is applied","centralized":false,"decentralized":false,"label":true,"source_file":"ci-doctor"},{"command":"cloclo","centralized":false,"decentralized":false,"label":true,"source_file":"cloclo"},{"command":"dev","description":"Daily status report for gh-aw project","centralized":false,"decentralized":false,"label":true,"source_file":"dev"},{"command":"necromancer","description":"Investigates merge-ready pull requests, traces root-cause issues, and adds regression tests before merge","centralized":false,"decentralized":false,"label":true,"source_file":"necromancer"},{"command":"needs-design","description":"Validates proposed technical approaches before implementation begins using a sequential multi-agent panel of Devil''s Advocate, Alternatives Scout, Implementation Estimator, and Dead End Detector","centralized":false,"decentralized":false,"label":true,"source_file":"approach-validator"},{"command":"smoke","description":"Smoke Copilot - AOAI (apikey)","centralized":false,"decentralized":false,"label":true,"source_file":"smoke-copilot-aoai-apikey"},{"command":"smoke-sdk","description":"Smoke Copilot SDK","centralized":false,"decentralized":false,"label":true,"source_file":"smoke-copilot-sdk"}]' - GH_AW_HELP_COMMAND_ENABLED: 'true' - GH_AW_SLASH_COMMAND_DOCS_URL: 'https://github.github.com/gh-aw/reference/command-triggers/' - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/route_slash_command.cjs'); - await main(); diff --git a/.github/workflows/agentics-maintenance.yml b/.github/workflows/agentics-maintenance.yml deleted file mode 100644 index 2c1975dfab9..00000000000 --- a/.github/workflows/agentics-maintenance.yml +++ /dev/null @@ -1,858 +0,0 @@ -# This file was automatically generated by pkg/workflow/maintenance_workflow.go. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md -# -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ -# | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ -# \_| |_/\__, |\___|_| |_|\__|_|\___| -# __/ | -# _ _ |___/ -# | | | | / _| | -# | | | | ___ _ __ _ __| |_| | _____ ____ -# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| -# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ -# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ -# -# -# To regenerate this workflow, run: -# gh aw compile -# Not all edits will cause changes to this file. -# -# For more information: https://github.github.com/gh-aw/introduction/overview/ -# -# This file defines the generated agentic maintenance workflow for this repository. -# It runs scheduled cleanup for expiring safe outputs and supports manual maintenance operations. -# -# This workflow is generated automatically when workflows use expiring safe outputs -# or when repository maintenance features are enabled in .github/workflows/aw.json. -# -# To disable maintenance workflow generation, set in .github/workflows/aw.json: -# {"maintenance": false} -# -# Agentic maintenance docs: -# https://github.github.com/gh-aw/reference/ephemerals/#manual-maintenance-operations -# -name: Agentic Maintenance - -on: - schedule: - - cron: "37 */2 * * *" # Every 2 hours (based on minimum expires: 1 days) - push: - branches: - - main - paths: - - '.github/workflows/*.md' - issues: - types: [labeled] - workflow_dispatch: - inputs: - operation: - description: 'Optional maintenance operation to run' - required: false - type: choice - default: '' - options: - - '' - - 'disable' - - 'enable' - - 'update' - - 'upgrade' - - 'safe_outputs' - - 'create_labels' - - 'activity_report' - - 'close_agentic_workflows_issues' - - 'clean_cache_memories' - - 'update_pull_request_branches' - - 'validate' - - 'forecast' - run_url: - description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.' - required: false - type: string - default: '' - workflow_call: - inputs: - operation: - description: 'Optional maintenance operation to run (disable, enable, update, upgrade, safe_outputs, create_labels, activity_report, close_agentic_workflows_issues, clean_cache_memories, update_pull_request_branches, validate, forecast)' - required: false - type: string - default: '' - run_url: - description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.' - required: false - type: string - default: '' - outputs: - operation_completed: - description: 'The maintenance operation that was completed (empty when none ran or a scheduled job ran)' - value: ${{ jobs.run_operation.outputs.operation || inputs.operation }} - applied_run_url: - description: 'The run URL that safe outputs were applied from' - value: ${{ jobs.apply_safe_outputs.outputs.run_url }} - -permissions: {} - -jobs: - close-expired-entities: - if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} - runs-on: ubuntu-slim - permissions: - discussions: write - issues: write - pull-requests: write - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Close expired discussions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_discussions.cjs'); - await main(); - - - name: Close expired issues - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_issues.cjs'); - await main(); - - - name: Close expired pull requests - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_pull_requests.cjs'); - await main(); - - cleanup-cache-memory: - if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'clean_cache_memories') }} - runs-on: ubuntu-slim - permissions: - actions: write - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Cleanup outdated cache-memory entries - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/cleanup_cache_memory.cjs'); - await main(); - - run_operation: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'activity_report' && inputs.operation != 'close_agentic_workflows_issues' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'update_pull_request_branches' && inputs.operation != 'validate' && inputs.operation != 'forecast' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-slim - permissions: - actions: write - contents: write - pull-requests: write - outputs: - operation: ${{ steps.record.outputs.operation }} - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - - name: Build gh-aw - run: make build - - - name: Run operation - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_AW_OPERATION: ${{ inputs.operation }} - GH_AW_CMD_PREFIX: ./gh-aw - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/run_operation_update_upgrade.cjs'); - await main(); - - - name: Record outputs - id: record - env: - GH_AW_OPERATION: ${{ inputs.operation }} - run: echo "operation=$GH_AW_OPERATION" >> "$GITHUB_OUTPUT" - - update_pull_request_branches: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'update_pull_request_branches' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-slim - permissions: - contents: write - pull-requests: write - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Update pull request branches - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/update_pull_request_branches.cjs'); - await main(); - - apply_safe_outputs: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'safe_outputs' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-slim - permissions: - actions: read - contents: write - discussions: write - issues: write - pull-requests: write - outputs: - run_url: ${{ steps.record.outputs.run_url }} - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Apply Safe Outputs - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_AW_RUN_URL: ${{ inputs.run_url }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/apply_safe_outputs_replay.cjs'); - await main(); - - - name: Record outputs - id: record - env: - GH_AW_RUN_URL: ${{ inputs.run_url }} - run: echo "run_url=$GH_AW_RUN_URL" >> "$GITHUB_OUTPUT" - - create_labels: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'create_labels' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-slim - permissions: - contents: read - issues: write - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - - name: Build gh-aw - run: make build - - - name: Create missing labels - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_CMD_PREFIX: ./gh-aw - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/create_labels.cjs'); - await main(); - - activity_report: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'activity_report' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-slim - timeout-minutes: 120 - permissions: - actions: read - contents: read - issues: write - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - - name: Build gh-aw - run: make build - - - name: Restore activity report logs cache - id: activity_report_logs_cache - uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: ./.cache/gh-aw/activity-report-logs - key: ${{ runner.os }}-activity-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }} - restore-keys: | - ${{ runner.os }}-activity-report-logs-${{ github.repository }}- - ${{ runner.os }}-activity-report-logs- - - name: Download activity report logs - timeout-minutes: 20 - shell: bash - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_AW_CMD_PREFIX: ./gh-aw - run: | - ${GH_AW_CMD_PREFIX} logs \ - --repo "${{ github.repository }}" \ - --start-date -1w \ - --count 500 \ - --output ./.cache/gh-aw/activity-report-logs \ - --format markdown \ - --report-file ./.cache/gh-aw/activity-report-logs/report.md - - - name: Save activity report logs cache - if: ${{ always() }} - uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: ./.cache/gh-aw/activity-report-logs - key: ${{ steps.activity_report_logs_cache.outputs.cache-primary-key }} - - - name: Generate activity report issue - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const fs = require('node:fs'); - const reportPath = './.cache/gh-aw/activity-report-logs/report.md'; - if (!fs.existsSync(reportPath)) { - core.warning('Activity report markdown not found at ' + reportPath + '; skipping issue creation.'); - return; - } - let reportBody = ''; - try { - reportBody = fs.readFileSync(reportPath, 'utf8').trim(); - } catch (error) { - core.warning('Failed to read activity report markdown at ' + reportPath + ': ' + error.message); - return; - } - if (!reportBody) { - core.warning('Activity report markdown is empty at ' + reportPath + '; skipping issue creation.'); - return; - } - const repoSlug = context.repo.owner + '/' + context.repo.repo; - const body = [ - '### Agentic workflow activity report', - '', - 'Repository: ' + repoSlug, - 'Generated at: ' + new Date().toISOString(), - '', - reportBody, - ].join('\n'); - const createdIssue = await github.rest.issues.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: '[aw] agentic status report', - body, - labels: ['agentic-workflows'], - }); - core.info('Created issue #' + createdIssue.data.number + ': ' + createdIssue.data.html_url); - - forecast_report: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'forecast' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-slim - timeout-minutes: 60 - permissions: - actions: read - contents: read - issues: write - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - - name: Build gh-aw - run: make build - - - name: Restore forecast report logs cache - id: forecast_report_logs_cache - uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: ./.github/aw/logs - key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }} - restore-keys: | - ${{ runner.os }}-forecast-report-logs-${{ github.repository }}- - ${{ runner.os }}-forecast-report-logs- - - - name: Generate forecast report - id: generate_forecast_report - timeout-minutes: 30 - shell: bash - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DEBUG: "*" - GH_AW_CMD_PREFIX: ./gh-aw - run: | - mkdir -p ./.cache/gh-aw/forecast - set +e - ${GH_AW_CMD_PREFIX} forecast --repo "${{ github.repository }}" --timeout 30 --verbose --json > ./.cache/gh-aw/forecast/report.json - forecast_exit_code=$? - set -e - if [ "${forecast_exit_code}" -eq 124 ]; then - echo '{"outcome":"timeout","message":"Forecast computation timed out after 30 minutes."}' > ./.cache/gh-aw/forecast/error.json - echo "::error::Forecast computation timed out after 30 minutes." - exit 1 - fi - if [ "${forecast_exit_code}" -ne 0 ]; then - echo '{"outcome":"error","message":"Forecast computation failed before producing a report."}' > ./.cache/gh-aw/forecast/error.json - echo "::error::Forecast computation failed with exit code ${forecast_exit_code}." - exit 1 - fi - - - name: Debug forecast logs folder - if: ${{ always() }} - shell: bash - run: | - if [ ! -d ./.github/aw/logs ]; then - echo "Logs directory not found: ./.github/aw/logs" - exit 0 - fi - echo "Files under ./.github/aw/logs:" - find ./.github/aw/logs -type f | sort - - - name: Save forecast report logs cache - if: ${{ always() }} - uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: ./.github/aw/logs - key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }} - - - name: Generate forecast issue - if: ${{ always() }} - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - FORECAST_STEP_OUTCOME: ${{ steps.generate_forecast_report.outcome }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/create_forecast_issue.cjs'); - await main(); - - close_agentic_workflows_issues: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'close_agentic_workflows_issues' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-slim - permissions: - issues: write - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Close no-repro agentic-workflows issues - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_agentic_workflows_issues.cjs'); - await main(); - - validate_workflows: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'validate' && (!(github.event.repository.fork)) }} - runs-on: ubuntu-latest - permissions: - contents: read - issues: write - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - - name: Build gh-aw - run: make build - - - name: Validate workflows and file issue on findings - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_CMD_PREFIX: ./gh-aw - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/run_validate_workflows.cjs'); - await main(); - - label_disable_agentic_workflow: - if: ${{ (!(github.event.repository.fork)) && github.event_name == 'issues' && github.event.label.name == 'agentic-workflows:disable' }} - runs-on: ubuntu-slim - permissions: - actions: write - contents: read - issues: write - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - id: check_permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Disable agentic workflow - if: ${{ steps.check_permissions.outcome == 'success' }} - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/disable_agentic_workflow.cjs'); - await main(); - - label_apply_safe_outputs: - if: ${{ (!(github.event.repository.fork)) && github.event_name == 'issues' && github.event.label.name == 'agentic-workflows:apply-safe-outputs' }} - runs-on: ubuntu-slim - permissions: - actions: read - contents: write - discussions: write - issues: write - pull-requests: write - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check admin/maintainer permissions - id: check_permissions - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); - await main(); - - - name: Apply safe outputs from referenced run - if: ${{ steps.check_permissions.outcome == 'success' }} - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/label_apply_safe_outputs.cjs'); - await main(); - - compile-workflows: - if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} - runs-on: ubuntu-slim - concurrency: - group: ${{ github.workflow }}-compile-workflows-${{ github.repository }} - cancel-in-progress: true - permissions: - contents: read - issues: write - steps: - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - - name: Build gh-aw - run: make build - - - name: Pre-compile validation - run: | - ./gh-aw compile --validate --no-emit --verbose - echo "✓ Pre-compile validation passed" - - - name: Compile workflows - run: | - ./gh-aw compile --validate --verbose - echo "✓ All workflows compiled successfully" - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Check for out-of-sync workflows and create issue or pull request if needed - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_recompile_needed.cjs'); - await main(); - - secret-validation: - if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} - runs-on: ubuntu-slim - permissions: - contents: read - steps: - - name: Checkout actions folder - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - sparse-checkout: | - actions - persist-credentials: false - - - name: Setup Node.js - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 - with: - node-version: '22' - - - name: Setup Scripts - uses: ./actions/setup - with: - destination: ${{ runner.temp }}/gh-aw/actions - - - name: Validate Secrets - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - # GitHub tokens - GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - GH_AW_COPILOT_TOKEN: ${{ secrets.GH_AW_COPILOT_TOKEN }} - # AI Engine API keys - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - BRAVE_API_KEY: ${{ secrets.BRAVE_API_KEY }} - # Integration tokens - NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }} - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/validate_secrets.cjs'); - await main(); - - - name: Upload secret validation report - if: always() - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: secret-validation-report - path: secret-validation-report.md - retention-days: 30 - if-no-files-found: warn From ce9c36165e296cccf68fc2b1034f15f2dee74c33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 23:59:31 +0000 Subject: [PATCH 8/8] Merge main and fix AWF platform follow-ups Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/agentic_commands.yml | 139 +++ .github/workflows/agentics-maintenance.yml | 858 +++++++++++++++++++ pkg/parser/schema_test.go | 6 + pkg/parser/schemas/main_workflow_schema.json | 2 +- pkg/workflow/awf_config.go | 2 + pkg/workflow/awf_config_test.go | 24 + pkg/workflow/sandbox.go | 28 +- 7 files changed, 1044 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/agentic_commands.yml create mode 100644 .github/workflows/agentics-maintenance.yml diff --git a/.github/workflows/agentic_commands.yml b/.github/workflows/agentic_commands.yml new file mode 100644 index 00000000000..20541b5a12b --- /dev/null +++ b/.github/workflows/agentic_commands.yml @@ -0,0 +1,139 @@ +# gh-aw-commands: {"payload_version":"v1","schema_version":"v1","compiler_version":"dev","commands":["*","ace","approach-validator","archie","brave","cloclo","craft","dependabot-burner","grumpy","matt","mergefest","nit","plan","poem-bot","review","ruflo","scout","security-review","smoke-agent-all-merged","smoke-agent-all-none","smoke-agent-public-approved","smoke-agent-public-none","smoke-agent-scoped-approved","smoke-antigravity","smoke-call-workflow","smoke-claude","smoke-codex","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-arm","smoke-copilot-sdk","smoke-create-cross-repo-pr","smoke-crush","smoke-gemini","smoke-multi-pr","smoke-opencode","smoke-otel-backends","smoke-pi","smoke-project","smoke-service-ports","smoke-temporary-id","smoke-test-tools","smoke-update-cross-repo-pr","summarize","tidy","unbloat"],"workflows":["ace-editor","approach-validator","archie","brave","ci-doctor","cloclo","craft","dependabot-burner","design-decision-gate","dev","grumpy-reviewer","mattpocock-skills-reviewer","mergefest","necromancer","pdf-summary","plan","poem-bot","pr-code-quality-reviewer","pr-nitpick-reviewer","ruflo-backed-task","scout","security-review","skillet","smoke-agent-all-merged","smoke-agent-all-none","smoke-agent-public-approved","smoke-agent-public-none","smoke-agent-scoped-approved","smoke-antigravity","smoke-call-workflow","smoke-claude","smoke-codex","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-arm","smoke-copilot-sdk","smoke-create-cross-repo-pr","smoke-crush","smoke-gemini","smoke-multi-pr","smoke-opencode","smoke-otel-backends","smoke-pi","smoke-project","smoke-service-ports","smoke-temporary-id","smoke-test-tools","smoke-update-cross-repo-pr","test-quality-sentinel","tidy","unbloat-docs"]} +# Routing summary (sorted): +# slash commands: +# /* -> skillet [pull_request_comment,pull_request_review_comment] reaction=eyes +# /ace -> ace-editor [pull_request_comment] reaction=eyes +# /approach-validator -> approach-validator [issue_comment,pull_request_comment] reaction=eyes +# /archie -> archie [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /brave -> brave [issue_comment] reaction=eyes +# /cloclo -> cloclo [discussion,discussion_comment,issue_comment,issues,pull_request,pull_request_comment,pull_request_review_comment] reaction=eyes +# /craft -> craft [issues] reaction=eyes +# /dependabot-burner -> dependabot-burner [pull_request_comment,pull_request_review_comment] reaction=eyes +# /grumpy -> grumpy-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes +# /matt -> mattpocock-skills-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes +# /mergefest -> mergefest [pull_request_comment] reaction=eyes +# /nit -> pr-nitpick-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes +# /plan -> plan [discussion_comment,issue_comment] reaction=eyes +# /poem-bot -> poem-bot [issues] reaction=eyes +# /review -> design-decision-gate [pull_request_comment,pull_request_review_comment] reaction=eyes +# /review -> pr-code-quality-reviewer [pull_request_comment,pull_request_review_comment] reaction=eyes +# /review -> test-quality-sentinel [pull_request_comment,pull_request_review_comment] reaction=eyes +# /ruflo -> ruflo-backed-task [issue_comment] reaction=eyes +# /scout -> scout [discussion,discussion_comment,issue_comment,issues,pull_request,pull_request_comment,pull_request_review_comment] reaction=eyes +# /security-review -> security-review [pull_request_comment,pull_request_review_comment] reaction=eyes +# /smoke-agent-all-merged -> smoke-agent-all-merged [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-agent-all-none -> smoke-agent-all-none [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-agent-public-approved -> smoke-agent-public-approved [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-agent-public-none -> smoke-agent-public-none [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-agent-scoped-approved -> smoke-agent-scoped-approved [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-antigravity -> smoke-antigravity [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket +# /smoke-call-workflow -> smoke-call-workflow [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-claude -> smoke-claude [issue_comment,issues,pull_request,pull_request_comment] reaction=heart +# /smoke-codex -> smoke-codex [issue_comment,issues,pull_request,pull_request_comment] reaction=hooray +# /smoke-copilot -> smoke-copilot [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-copilot-aoai-apikey -> smoke-copilot-aoai-apikey [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-copilot-aoai-entra -> smoke-copilot-aoai-entra [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-copilot-arm -> smoke-copilot-arm [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-copilot-sdk -> smoke-copilot-sdk [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-create-cross-repo-pr -> smoke-create-cross-repo-pr [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-crush -> smoke-crush [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-gemini -> smoke-gemini [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket +# /smoke-multi-pr -> smoke-multi-pr [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-opencode -> smoke-opencode [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket +# /smoke-otel-backends -> smoke-otel-backends [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-pi -> smoke-pi [issue_comment,issues,pull_request,pull_request_comment] reaction=rocket +# /smoke-project -> smoke-project [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-service-ports -> smoke-service-ports [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-temporary-id -> smoke-temporary-id [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-test-tools -> smoke-test-tools [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /smoke-update-cross-repo-pr -> smoke-update-cross-repo-pr [issue_comment,issues,pull_request,pull_request_comment] reaction=eyes +# /summarize -> pdf-summary [issue_comment,issues] reaction=eyes +# /tidy -> tidy [pull_request_comment] reaction=eyes +# /unbloat -> unbloat-docs [pull_request_comment] reaction=eyes +# labels: +# approach-proposal -> approach-validator [issues,pull_request] reaction=eyes +# ci-doctor -> ci-doctor [pull_request] reaction=eyes +# cloclo -> cloclo [discussion,issues,pull_request] reaction=eyes +# dev -> dev [discussion,issues,pull_request] reaction=eyes +# necromancer -> necromancer [pull_request] reaction=eyes +# needs-design -> approach-validator [issues,pull_request] reaction=eyes +# smoke -> smoke-copilot [pull_request] reaction=eyes +# smoke -> smoke-copilot-aoai-apikey [pull_request] reaction=eyes +# smoke -> smoke-copilot-aoai-entra [pull_request] reaction=eyes +# smoke -> smoke-otel-backends [pull_request] reaction=eyes +# smoke-sdk -> smoke-copilot-sdk [pull_request] reaction=eyes +# This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# +# ___ _ _ +# / _ \ | | (_) +# | |_| | __ _ ___ _ __ | |_ _ ___ +# | _ |/ _` |/ _ \ '_ \| __| |/ __| +# | | | | (_| | __/ | | | |_| | (__ +# \_| |_/\__, |\___|_| |_|\__|_|\___| +# __/ | +# _ _ |___/ +# | | | | / _| | +# | | | | ___ _ __ _ __| |_| | _____ ____ +# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| +# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ +# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ +# +# +# To regenerate this workflow, run: +# gh aw compile +# Not all edits will cause changes to this file. +# +# For more information: https://github.github.com/gh-aw/introduction/overview/ +# +name: "Agentic Commands" + +on: + issues: + types: [edited, labeled, opened, reopened] + issue_comment: + types: [created, edited] + pull_request: + types: [edited, labeled, opened, reopened] + pull_request_review_comment: + types: [created, edited] + discussion: + types: [created, edited, labeled] + discussion_comment: + types: [created, edited] + +permissions: {} + +jobs: + route: + runs-on: ubuntu-slim + timeout-minutes: 15 + permissions: + actions: write + contents: read + issues: write + pull-requests: write + discussions: write + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Route slash command + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_SLASH_ROUTING: '{"*":[{"workflow":"skillet","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"ace":[{"workflow":"ace-editor","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"approach-validator":[{"workflow":"approach-validator","events":["issue_comment","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"archie":[{"workflow":"archie","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"brave":[{"workflow":"brave","events":["issue_comment"],"ai_reaction":"eyes","status_comment":true}],"cloclo":[{"workflow":"cloclo","events":["discussion","discussion_comment","issue_comment","issues","pull_request","pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"craft":[{"workflow":"craft","events":["issues"],"ai_reaction":"eyes","status_comment":true}],"dependabot-burner":[{"workflow":"dependabot-burner","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"grumpy":[{"workflow":"grumpy-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"matt":[{"workflow":"mattpocock-skills-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"mergefest":[{"workflow":"mergefest","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"nit":[{"workflow":"pr-nitpick-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"plan":[{"workflow":"plan","events":["discussion_comment","issue_comment"],"ai_reaction":"eyes","status_comment":true}],"poem-bot":[{"workflow":"poem-bot","events":["issues"],"ai_reaction":"eyes","status_comment":true}],"review":[{"workflow":"design-decision-gate","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true},{"workflow":"pr-code-quality-reviewer","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true},{"workflow":"test-quality-sentinel","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"ruflo":[{"workflow":"ruflo-backed-task","events":["issue_comment"],"ai_reaction":"eyes","status_comment":true}],"scout":[{"workflow":"scout","events":["discussion","discussion_comment","issue_comment","issues","pull_request","pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"security-review":[{"workflow":"security-review","events":["pull_request_comment","pull_request_review_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-all-merged":[{"workflow":"smoke-agent-all-merged","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-all-none":[{"workflow":"smoke-agent-all-none","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-public-approved":[{"workflow":"smoke-agent-public-approved","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-public-none":[{"workflow":"smoke-agent-public-none","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-agent-scoped-approved":[{"workflow":"smoke-agent-scoped-approved","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-antigravity":[{"workflow":"smoke-antigravity","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-call-workflow":[{"workflow":"smoke-call-workflow","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-claude":[{"workflow":"smoke-claude","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"heart","status_comment":true}],"smoke-codex":[{"workflow":"smoke-codex","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"hooray","status_comment":true}],"smoke-copilot":[{"workflow":"smoke-copilot","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-aoai-apikey":[{"workflow":"smoke-copilot-aoai-apikey","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-aoai-entra":[{"workflow":"smoke-copilot-aoai-entra","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-arm":[{"workflow":"smoke-copilot-arm","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-copilot-sdk":[{"workflow":"smoke-copilot-sdk","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-create-cross-repo-pr":[{"workflow":"smoke-create-cross-repo-pr","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-crush":[{"workflow":"smoke-crush","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-gemini":[{"workflow":"smoke-gemini","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-multi-pr":[{"workflow":"smoke-multi-pr","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-opencode":[{"workflow":"smoke-opencode","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-otel-backends":[{"workflow":"smoke-otel-backends","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-pi":[{"workflow":"smoke-pi","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"rocket","status_comment":true}],"smoke-project":[{"workflow":"smoke-project","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-service-ports":[{"workflow":"smoke-service-ports","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-temporary-id":[{"workflow":"smoke-temporary-id","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-test-tools":[{"workflow":"smoke-test-tools","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"smoke-update-cross-repo-pr":[{"workflow":"smoke-update-cross-repo-pr","events":["issue_comment","issues","pull_request","pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"summarize":[{"workflow":"pdf-summary","events":["issue_comment","issues"],"ai_reaction":"eyes","status_comment":true}],"tidy":[{"workflow":"tidy","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}],"unbloat":[{"workflow":"unbloat-docs","events":["pull_request_comment"],"ai_reaction":"eyes","status_comment":true}]}' + GH_AW_LABEL_ROUTING: '{"approach-proposal":[{"workflow":"approach-validator","events":["issues","pull_request"],"ai_reaction":"eyes"}],"ci-doctor":[{"workflow":"ci-doctor","events":["pull_request"],"ai_reaction":"eyes"}],"cloclo":[{"workflow":"cloclo","events":["discussion","issues","pull_request"],"ai_reaction":"eyes"}],"dev":[{"workflow":"dev","events":["discussion","issues","pull_request"],"ai_reaction":"eyes"}],"necromancer":[{"workflow":"necromancer","events":["pull_request"],"ai_reaction":"eyes"}],"needs-design":[{"workflow":"approach-validator","events":["issues","pull_request"],"ai_reaction":"eyes"}],"smoke":[{"workflow":"smoke-copilot","events":["pull_request"],"ai_reaction":"eyes"},{"workflow":"smoke-copilot-aoai-apikey","events":["pull_request"],"ai_reaction":"eyes"},{"workflow":"smoke-copilot-aoai-entra","events":["pull_request"],"ai_reaction":"eyes"},{"workflow":"smoke-otel-backends","events":["pull_request"],"ai_reaction":"eyes"}],"smoke-sdk":[{"workflow":"smoke-copilot-sdk","events":["pull_request"],"ai_reaction":"eyes"}]}' + GH_AW_HELP_COMMANDS: '[{"command":"*","description":"Reviews pull requests by mapping any slash command to a matching repository skill under .github/skills","centralized":true,"decentralized":false,"source_file":"skillet"},{"command":"ace","description":"Generates an ACE editor session link when invoked with /ace command on pull request comments","centralized":true,"decentralized":false,"source_file":"ace-editor"},{"command":"approach-validator","description":"Validates proposed technical approaches before implementation begins using a sequential multi-agent panel of Devil''s Advocate, Alternatives Scout, Implementation Estimator, and Dead End Detector","centralized":true,"decentralized":false,"source_file":"approach-validator"},{"command":"archie","description":"Generates Mermaid diagrams to visualize issue and pull request relationships when invoked with the /archie command","centralized":true,"decentralized":false,"source_file":"archie"},{"command":"brave","description":"Performs web searches using Brave search engine when invoked with /brave command in issues or PRs","centralized":true,"decentralized":false,"source_file":"brave"},{"command":"cloclo","centralized":true,"decentralized":false,"source_file":"cloclo"},{"command":"craft","description":"Generates new agentic workflow markdown files based on user requests when invoked with /craft command","centralized":true,"decentralized":false,"source_file":"craft"},{"command":"dependabot-burner","description":"Runs one grouped Dependabot remediation wave from schedule, manual dispatch, or /dependabot-burner on pull requests","centralized":true,"decentralized":false,"source_file":"dependabot-burner"},{"command":"grumpy","description":"⚠️ DEPRECATED: Use PR Code Quality Reviewer (pr-code-quality-reviewer) instead. Performs critical code review with a focus on edge cases, potential bugs, and code quality issues","centralized":true,"decentralized":false,"source_file":"grumpy-reviewer"},{"command":"matt","description":"Reviews pull requests using Matt Pocock''s engineering skills to provide targeted, high-quality improvement suggestions based on the type of changes","centralized":true,"decentralized":false,"source_file":"mattpocock-skills-reviewer"},{"command":"mergefest","description":"Automatically merges the main branch into pull request branches when invoked with /mergefest command","centralized":true,"decentralized":false,"source_file":"mergefest"},{"command":"nit","description":"⚠️ DEPRECATED: Use PR Code Quality Reviewer (pr-code-quality-reviewer) instead. Provides detailed nitpicky code review focusing on style, best practices, and minor improvements","centralized":true,"decentralized":false,"source_file":"pr-nitpick-reviewer"},{"command":"plan","description":"Generates project plans and task breakdowns when invoked with /plan command in issues or PRs","centralized":true,"decentralized":false,"source_file":"plan"},{"command":"poem-bot","description":"Generates creative poems on specified themes when invoked with /poem-bot command","centralized":true,"decentralized":false,"source_file":"poem-bot"},{"command":"q","description":"Intelligent assistant that answers questions, analyzes repositories, and can create PRs for workflow optimizations","centralized":false,"decentralized":true,"source_file":"q"},{"command":"review","description":"Enforces Architecture Decision Records (ADRs) before implementation work can merge, detecting missing design decisions and generating draft ADRs using AI analysis","centralized":true,"decentralized":false,"source_file":"design-decision-gate"},{"command":"ruflo","description":"Runs a repository task inside GitHub Agentic Workflows while delegating inner planning and coordination to Ruflo","centralized":true,"decentralized":false,"source_file":"ruflo-backed-task"},{"command":"scout","description":"Performs deep research investigations using web search to gather and synthesize comprehensive information on any topic","centralized":true,"decentralized":false,"source_file":"scout"},{"command":"security-review","description":"Security-focused AI agent that reviews pull requests to identify changes that could weaken security posture or extend AWF boundaries","centralized":true,"decentralized":false,"source_file":"security-review"},{"command":"smoke-agent-all-merged","description":"Guard policy smoke test: repos=all, min-integrity=merged (most restrictive)","centralized":true,"decentralized":false,"source_file":"smoke-agent-all-merged"},{"command":"smoke-agent-all-none","description":"Guard policy smoke test: repos=all, min-integrity=none (most permissive)","centralized":true,"decentralized":false,"source_file":"smoke-agent-all-none"},{"command":"smoke-agent-public-approved","description":"Smoke test that validates assign-to-agent with the agentic-workflows custom agent","centralized":true,"decentralized":false,"source_file":"smoke-agent-public-approved"},{"command":"smoke-agent-public-none","description":"Guard policy smoke test: repos=public, min-integrity=none","centralized":true,"decentralized":false,"source_file":"smoke-agent-public-none"},{"command":"smoke-agent-scoped-approved","description":"Guard policy smoke test: repos=[github/gh-aw, github/*], min-integrity=approved (scoped patterns)","centralized":true,"decentralized":false,"source_file":"smoke-agent-scoped-approved"},{"command":"smoke-antigravity","description":"Smoke test workflow that validates Antigravity engine functionality twice daily","centralized":true,"decentralized":false,"source_file":"smoke-antigravity"},{"command":"smoke-call-workflow","description":"Smoke test for the call-workflow safe output - orchestrator that calls a worker via workflow_call at compile-time fan-out","centralized":true,"decentralized":false,"source_file":"smoke-call-workflow"},{"command":"smoke-claude","description":"Smoke test workflow that validates Claude engine functionality by reviewing recent PRs twice daily","centralized":true,"decentralized":false,"source_file":"smoke-claude"},{"command":"smoke-codex","description":"Smoke test workflow that validates Codex engine functionality by reviewing recent PRs twice daily","centralized":true,"decentralized":false,"source_file":"smoke-codex"},{"command":"smoke-copilot","description":"Smoke Copilot","centralized":true,"decentralized":false,"source_file":"smoke-copilot"},{"command":"smoke-copilot-aoai-apikey","description":"Smoke Copilot - AOAI (apikey)","centralized":true,"decentralized":false,"source_file":"smoke-copilot-aoai-apikey"},{"command":"smoke-copilot-aoai-entra","description":"Smoke Copilot - AOAI (Entra)","centralized":true,"decentralized":false,"source_file":"smoke-copilot-aoai-entra"},{"command":"smoke-copilot-arm","description":"Smoke Copilot ARM64","centralized":true,"decentralized":false,"source_file":"smoke-copilot-arm"},{"command":"smoke-copilot-sdk","description":"Smoke Copilot SDK","centralized":true,"decentralized":false,"source_file":"smoke-copilot-sdk"},{"command":"smoke-create-cross-repo-pr","description":"Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo","centralized":true,"decentralized":false,"source_file":"smoke-create-cross-repo-pr"},{"command":"smoke-crush","description":"Smoke test workflow that validates Crush engine functionality","centralized":true,"decentralized":false,"source_file":"smoke-crush"},{"command":"smoke-gemini","description":"Smoke test workflow that validates Gemini engine functionality twice daily","centralized":true,"decentralized":false,"source_file":"smoke-gemini"},{"command":"smoke-multi-pr","description":"Test creating multiple pull requests in a single workflow run","centralized":true,"decentralized":false,"source_file":"smoke-multi-pr"},{"command":"smoke-opencode","description":"Smoke test workflow that validates OpenCode engine functionality","centralized":true,"decentralized":false,"source_file":"smoke-opencode"},{"command":"smoke-otel-backends","description":"Smoke test that validates OTEL span export and query access for Sentry, Grafana, and Datadog","centralized":true,"decentralized":false,"source_file":"smoke-otel-backends"},{"command":"smoke-pi","description":"Smoke test workflow that validates Pi engine functionality","centralized":true,"decentralized":false,"source_file":"smoke-pi"},{"command":"smoke-project","description":"Smoke Project - Test project operations","centralized":true,"decentralized":false,"source_file":"smoke-project"},{"command":"smoke-service-ports","description":"Smoke test to validate --allow-host-service-ports with Redis service container","centralized":true,"decentralized":false,"source_file":"smoke-service-ports"},{"command":"smoke-temporary-id","description":"Test temporary ID functionality for issue chaining and cross-references","centralized":true,"decentralized":false,"source_file":"smoke-temporary-id"},{"command":"smoke-test-tools","description":"Smoke test to validate common development tools are available in the agent container","centralized":true,"decentralized":false,"source_file":"smoke-test-tools"},{"command":"smoke-update-cross-repo-pr","description":"Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer''s Odyssey to the README","centralized":true,"decentralized":false,"source_file":"smoke-update-cross-repo-pr"},{"command":"summarize","description":"pdf summarizer","centralized":true,"decentralized":false,"source_file":"pdf-summary"},{"command":"tidy","description":"Automatically formats and tidies code files (Go, JS, TypeScript) when code changes are pushed or on command","centralized":true,"decentralized":false,"source_file":"tidy"},{"command":"unbloat","description":"Reviews and simplifies documentation by reducing verbosity while maintaining clarity and completeness","centralized":true,"decentralized":false,"source_file":"unbloat-docs"},{"command":"approach-proposal","description":"Validates proposed technical approaches before implementation begins using a sequential multi-agent panel of Devil''s Advocate, Alternatives Scout, Implementation Estimator, and Dead End Detector","centralized":false,"decentralized":false,"label":true,"source_file":"approach-validator"},{"command":"ci-doctor","description":"Investigates failed CI workflows to identify root causes and patterns, creating issues with diagnostic information; also reviews PR check failures when the ci-doctor label is applied","centralized":false,"decentralized":false,"label":true,"source_file":"ci-doctor"},{"command":"cloclo","centralized":false,"decentralized":false,"label":true,"source_file":"cloclo"},{"command":"dev","description":"Daily status report for gh-aw project","centralized":false,"decentralized":false,"label":true,"source_file":"dev"},{"command":"necromancer","description":"Investigates merge-ready pull requests, traces root-cause issues, and adds regression tests before merge","centralized":false,"decentralized":false,"label":true,"source_file":"necromancer"},{"command":"needs-design","description":"Validates proposed technical approaches before implementation begins using a sequential multi-agent panel of Devil''s Advocate, Alternatives Scout, Implementation Estimator, and Dead End Detector","centralized":false,"decentralized":false,"label":true,"source_file":"approach-validator"},{"command":"smoke","description":"Smoke Copilot - AOAI (apikey)","centralized":false,"decentralized":false,"label":true,"source_file":"smoke-copilot-aoai-apikey"},{"command":"smoke-sdk","description":"Smoke Copilot SDK","centralized":false,"decentralized":false,"label":true,"source_file":"smoke-copilot-sdk"}]' + GH_AW_HELP_COMMAND_ENABLED: 'true' + GH_AW_SLASH_COMMAND_DOCS_URL: 'https://github.github.com/gh-aw/reference/command-triggers/' + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/route_slash_command.cjs'); + await main(); diff --git a/.github/workflows/agentics-maintenance.yml b/.github/workflows/agentics-maintenance.yml new file mode 100644 index 00000000000..2c1975dfab9 --- /dev/null +++ b/.github/workflows/agentics-maintenance.yml @@ -0,0 +1,858 @@ +# This file was automatically generated by pkg/workflow/maintenance_workflow.go. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# +# ___ _ _ +# / _ \ | | (_) +# | |_| | __ _ ___ _ __ | |_ _ ___ +# | _ |/ _` |/ _ \ '_ \| __| |/ __| +# | | | | (_| | __/ | | | |_| | (__ +# \_| |_/\__, |\___|_| |_|\__|_|\___| +# __/ | +# _ _ |___/ +# | | | | / _| | +# | | | | ___ _ __ _ __| |_| | _____ ____ +# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| +# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ +# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ +# +# +# To regenerate this workflow, run: +# gh aw compile +# Not all edits will cause changes to this file. +# +# For more information: https://github.github.com/gh-aw/introduction/overview/ +# +# This file defines the generated agentic maintenance workflow for this repository. +# It runs scheduled cleanup for expiring safe outputs and supports manual maintenance operations. +# +# This workflow is generated automatically when workflows use expiring safe outputs +# or when repository maintenance features are enabled in .github/workflows/aw.json. +# +# To disable maintenance workflow generation, set in .github/workflows/aw.json: +# {"maintenance": false} +# +# Agentic maintenance docs: +# https://github.github.com/gh-aw/reference/ephemerals/#manual-maintenance-operations +# +name: Agentic Maintenance + +on: + schedule: + - cron: "37 */2 * * *" # Every 2 hours (based on minimum expires: 1 days) + push: + branches: + - main + paths: + - '.github/workflows/*.md' + issues: + types: [labeled] + workflow_dispatch: + inputs: + operation: + description: 'Optional maintenance operation to run' + required: false + type: choice + default: '' + options: + - '' + - 'disable' + - 'enable' + - 'update' + - 'upgrade' + - 'safe_outputs' + - 'create_labels' + - 'activity_report' + - 'close_agentic_workflows_issues' + - 'clean_cache_memories' + - 'update_pull_request_branches' + - 'validate' + - 'forecast' + run_url: + description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.' + required: false + type: string + default: '' + workflow_call: + inputs: + operation: + description: 'Optional maintenance operation to run (disable, enable, update, upgrade, safe_outputs, create_labels, activity_report, close_agentic_workflows_issues, clean_cache_memories, update_pull_request_branches, validate, forecast)' + required: false + type: string + default: '' + run_url: + description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.' + required: false + type: string + default: '' + outputs: + operation_completed: + description: 'The maintenance operation that was completed (empty when none ran or a scheduled job ran)' + value: ${{ jobs.run_operation.outputs.operation || inputs.operation }} + applied_run_url: + description: 'The run URL that safe outputs were applied from' + value: ${{ jobs.apply_safe_outputs.outputs.run_url }} + +permissions: {} + +jobs: + close-expired-entities: + if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} + runs-on: ubuntu-slim + permissions: + discussions: write + issues: write + pull-requests: write + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Close expired discussions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_discussions.cjs'); + await main(); + + - name: Close expired issues + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_issues.cjs'); + await main(); + + - name: Close expired pull requests + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_pull_requests.cjs'); + await main(); + + cleanup-cache-memory: + if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'clean_cache_memories') }} + runs-on: ubuntu-slim + permissions: + actions: write + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Cleanup outdated cache-memory entries + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/cleanup_cache_memory.cjs'); + await main(); + + run_operation: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'activity_report' && inputs.operation != 'close_agentic_workflows_issues' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'update_pull_request_branches' && inputs.operation != 'validate' && inputs.operation != 'forecast' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-slim + permissions: + actions: write + contents: write + pull-requests: write + outputs: + operation: ${{ steps.record.outputs.operation }} + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Setup Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build gh-aw + run: make build + + - name: Run operation + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_AW_OPERATION: ${{ inputs.operation }} + GH_AW_CMD_PREFIX: ./gh-aw + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/run_operation_update_upgrade.cjs'); + await main(); + + - name: Record outputs + id: record + env: + GH_AW_OPERATION: ${{ inputs.operation }} + run: echo "operation=$GH_AW_OPERATION" >> "$GITHUB_OUTPUT" + + update_pull_request_branches: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'update_pull_request_branches' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-slim + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Update pull request branches + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/update_pull_request_branches.cjs'); + await main(); + + apply_safe_outputs: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'safe_outputs' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-slim + permissions: + actions: read + contents: write + discussions: write + issues: write + pull-requests: write + outputs: + run_url: ${{ steps.record.outputs.run_url }} + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Apply Safe Outputs + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_AW_RUN_URL: ${{ inputs.run_url }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/apply_safe_outputs_replay.cjs'); + await main(); + + - name: Record outputs + id: record + env: + GH_AW_RUN_URL: ${{ inputs.run_url }} + run: echo "run_url=$GH_AW_RUN_URL" >> "$GITHUB_OUTPUT" + + create_labels: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'create_labels' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-slim + permissions: + contents: read + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Setup Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build gh-aw + run: make build + + - name: Create missing labels + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_CMD_PREFIX: ./gh-aw + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/create_labels.cjs'); + await main(); + + activity_report: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'activity_report' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-slim + timeout-minutes: 120 + permissions: + actions: read + contents: read + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Setup Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build gh-aw + run: make build + + - name: Restore activity report logs cache + id: activity_report_logs_cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ./.cache/gh-aw/activity-report-logs + key: ${{ runner.os }}-activity-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-activity-report-logs-${{ github.repository }}- + ${{ runner.os }}-activity-report-logs- + - name: Download activity report logs + timeout-minutes: 20 + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_AW_CMD_PREFIX: ./gh-aw + run: | + ${GH_AW_CMD_PREFIX} logs \ + --repo "${{ github.repository }}" \ + --start-date -1w \ + --count 500 \ + --output ./.cache/gh-aw/activity-report-logs \ + --format markdown \ + --report-file ./.cache/gh-aw/activity-report-logs/report.md + + - name: Save activity report logs cache + if: ${{ always() }} + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ./.cache/gh-aw/activity-report-logs + key: ${{ steps.activity_report_logs_cache.outputs.cache-primary-key }} + + - name: Generate activity report issue + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('node:fs'); + const reportPath = './.cache/gh-aw/activity-report-logs/report.md'; + if (!fs.existsSync(reportPath)) { + core.warning('Activity report markdown not found at ' + reportPath + '; skipping issue creation.'); + return; + } + let reportBody = ''; + try { + reportBody = fs.readFileSync(reportPath, 'utf8').trim(); + } catch (error) { + core.warning('Failed to read activity report markdown at ' + reportPath + ': ' + error.message); + return; + } + if (!reportBody) { + core.warning('Activity report markdown is empty at ' + reportPath + '; skipping issue creation.'); + return; + } + const repoSlug = context.repo.owner + '/' + context.repo.repo; + const body = [ + '### Agentic workflow activity report', + '', + 'Repository: ' + repoSlug, + 'Generated at: ' + new Date().toISOString(), + '', + reportBody, + ].join('\n'); + const createdIssue = await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: '[aw] agentic status report', + body, + labels: ['agentic-workflows'], + }); + core.info('Created issue #' + createdIssue.data.number + ': ' + createdIssue.data.html_url); + + forecast_report: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'forecast' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-slim + timeout-minutes: 60 + permissions: + actions: read + contents: read + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Setup Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build gh-aw + run: make build + + - name: Restore forecast report logs cache + id: forecast_report_logs_cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ./.github/aw/logs + key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-forecast-report-logs-${{ github.repository }}- + ${{ runner.os }}-forecast-report-logs- + + - name: Generate forecast report + id: generate_forecast_report + timeout-minutes: 30 + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEBUG: "*" + GH_AW_CMD_PREFIX: ./gh-aw + run: | + mkdir -p ./.cache/gh-aw/forecast + set +e + ${GH_AW_CMD_PREFIX} forecast --repo "${{ github.repository }}" --timeout 30 --verbose --json > ./.cache/gh-aw/forecast/report.json + forecast_exit_code=$? + set -e + if [ "${forecast_exit_code}" -eq 124 ]; then + echo '{"outcome":"timeout","message":"Forecast computation timed out after 30 minutes."}' > ./.cache/gh-aw/forecast/error.json + echo "::error::Forecast computation timed out after 30 minutes." + exit 1 + fi + if [ "${forecast_exit_code}" -ne 0 ]; then + echo '{"outcome":"error","message":"Forecast computation failed before producing a report."}' > ./.cache/gh-aw/forecast/error.json + echo "::error::Forecast computation failed with exit code ${forecast_exit_code}." + exit 1 + fi + + - name: Debug forecast logs folder + if: ${{ always() }} + shell: bash + run: | + if [ ! -d ./.github/aw/logs ]; then + echo "Logs directory not found: ./.github/aw/logs" + exit 0 + fi + echo "Files under ./.github/aw/logs:" + find ./.github/aw/logs -type f | sort + + - name: Save forecast report logs cache + if: ${{ always() }} + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ./.github/aw/logs + key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }} + + - name: Generate forecast issue + if: ${{ always() }} + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + FORECAST_STEP_OUTCOME: ${{ steps.generate_forecast_report.outcome }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/create_forecast_issue.cjs'); + await main(); + + close_agentic_workflows_issues: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'close_agentic_workflows_issues' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-slim + permissions: + issues: write + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Close no-repro agentic-workflows issues + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/close_agentic_workflows_issues.cjs'); + await main(); + + validate_workflows: + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'validate' && (!(github.event.repository.fork)) }} + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Setup Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build gh-aw + run: make build + + - name: Validate workflows and file issue on findings + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_CMD_PREFIX: ./gh-aw + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/run_validate_workflows.cjs'); + await main(); + + label_disable_agentic_workflow: + if: ${{ (!(github.event.repository.fork)) && github.event_name == 'issues' && github.event.label.name == 'agentic-workflows:disable' }} + runs-on: ubuntu-slim + permissions: + actions: write + contents: read + issues: write + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + id: check_permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Disable agentic workflow + if: ${{ steps.check_permissions.outcome == 'success' }} + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/disable_agentic_workflow.cjs'); + await main(); + + label_apply_safe_outputs: + if: ${{ (!(github.event.repository.fork)) && github.event_name == 'issues' && github.event.label.name == 'agentic-workflows:apply-safe-outputs' }} + runs-on: ubuntu-slim + permissions: + actions: read + contents: write + discussions: write + issues: write + pull-requests: write + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check admin/maintainer permissions + id: check_permissions + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + await main(); + + - name: Apply safe outputs from referenced run + if: ${{ steps.check_permissions.outcome == 'success' }} + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/label_apply_safe_outputs.cjs'); + await main(); + + compile-workflows: + if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} + runs-on: ubuntu-slim + concurrency: + group: ${{ github.workflow }}-compile-workflows-${{ github.repository }} + cancel-in-progress: true + permissions: + contents: read + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Setup Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build gh-aw + run: make build + + - name: Pre-compile validation + run: | + ./gh-aw compile --validate --no-emit --verbose + echo "✓ Pre-compile validation passed" + + - name: Compile workflows + run: | + ./gh-aw compile --validate --verbose + echo "✓ All workflows compiled successfully" + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Check for out-of-sync workflows and create issue or pull request if needed + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_recompile_needed.cjs'); + await main(); + + secret-validation: + if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} + runs-on: ubuntu-slim + permissions: + contents: read + steps: + - name: Checkout actions folder + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: | + actions + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '22' + + - name: Setup Scripts + uses: ./actions/setup + with: + destination: ${{ runner.temp }}/gh-aw/actions + + - name: Validate Secrets + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + # GitHub tokens + GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} + GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} + GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} + GH_AW_COPILOT_TOKEN: ${{ secrets.GH_AW_COPILOT_TOKEN }} + # AI Engine API keys + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + BRAVE_API_KEY: ${{ secrets.BRAVE_API_KEY }} + # Integration tokens + NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/validate_secrets.cjs'); + await main(); + + - name: Upload secret validation report + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: secret-validation-report + path: secret-validation-report.md + retention-days: 30 + if-no-files-found: warn diff --git a/pkg/parser/schema_test.go b/pkg/parser/schema_test.go index c6fcfaabcf1..91731cc84f6 100644 --- a/pkg/parser/schema_test.go +++ b/pkg/parser/schema_test.go @@ -706,7 +706,11 @@ func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxDailyAICreditsN } func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_SandboxAgentPlatform(t *testing.T) { + t.Parallel() + t.Run("valid platform is accepted", func(t *testing.T) { + t.Parallel() + frontmatter := map[string]any{ "on": "push", "sandbox": map[string]any{ @@ -724,6 +728,8 @@ func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_SandboxAgentPlatfo }) t.Run("unknown platform is rejected", func(t *testing.T) { + t.Parallel() + frontmatter := map[string]any{ "on": "push", "sandbox": map[string]any{ diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index e8abbf541c9..2ee5dddfba1 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -3256,7 +3256,7 @@ "type": "string", "enum": ["github.com", "ghes", "ghec", "ghec-self-hosted"], "description": "AWF platform.type override. Declares the GitHub deployment type so AWF can apply deterministic Copilot auth behavior without relying on host heuristics. Omit to let AWF use its default host heuristic behavior." - } + }, "command": { "type": "string", "x-internal": true, diff --git a/pkg/workflow/awf_config.go b/pkg/workflow/awf_config.go index 8644975727d..c14ed72abe1 100644 --- a/pkg/workflow/awf_config.go +++ b/pkg/workflow/awf_config.go @@ -531,6 +531,8 @@ func extractModelMultipliers(workflowData *WorkflowData) map[string]float64 { return workflowData.EngineConfig.TokenWeights.Multipliers } +// extractPlatformType returns sandbox.agent.platform only for enabled AWF sandbox +// agents, or an empty string to let AWF fall back to its default platform logic. func extractPlatformType(workflowData *WorkflowData) string { if workflowData == nil || workflowData.SandboxConfig == nil || workflowData.SandboxConfig.Agent == nil { return "" diff --git a/pkg/workflow/awf_config_test.go b/pkg/workflow/awf_config_test.go index 69b3d104ac9..b228a28c99a 100644 --- a/pkg/workflow/awf_config_test.go +++ b/pkg/workflow/awf_config_test.go @@ -58,6 +58,30 @@ func TestBuildAWFConfigJSON(t *testing.T) { assert.Contains(t, jsonStr, `"imageTag"`, "should include imageTag") }) + t.Run("platform config is omitted when sandbox agent is disabled", func(t *testing.T) { + config := AWFCommandConfig{ + EngineName: "copilot", + AllowedDomains: "github.com", + WorkflowData: &WorkflowData{ + EngineConfig: &EngineConfig{ID: "copilot"}, + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{Enabled: true}, + }, + SandboxConfig: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + Type: SandboxTypeAWF, + Platform: "ghes", + Disabled: true, + }, + }, + }, + } + + jsonStr, err := BuildAWFConfigJSON(config) + require.NoError(t, err) + assert.NotContains(t, jsonStr, `"platform":`, "platform should be absent when sandbox agent is disabled") + }) + t.Run("blocked domains are included in the network section", func(t *testing.T) { config := AWFCommandConfig{ EngineName: "copilot", diff --git a/pkg/workflow/sandbox.go b/pkg/workflow/sandbox.go index e3aaa655d99..fa3115f4e3d 100644 --- a/pkg/workflow/sandbox.go +++ b/pkg/workflow/sandbox.go @@ -46,20 +46,20 @@ type SandboxConfig struct { // AgentSandboxConfig represents the agent sandbox configuration type AgentSandboxConfig struct { - ID string `yaml:"id,omitempty"` // Agent ID: "awf" or "srt" (replaces Type in new object format) - Type SandboxType `yaml:"type,omitempty"` // Sandbox type: "awf" or "srt" (legacy, use ID instead) - Version string `yaml:"version,omitempty"` // AWF version override used to install and run the matching firewall version - Platform string `yaml:"platform,omitempty"` // AWF platform.type override (github.com, ghes, ghec, ghec-self-hosted) - Disabled bool `yaml:"-"` // True when agent is explicitly set to false (disables firewall). This is a runtime flag, not serialized to YAML. - DisableReason string `yaml:"-"` // Operator-authored justification from dangerously-disable-sandbox-agent feature; available for diagnostics and audit logging. - Config *SandboxRuntimeConfig `yaml:"config,omitempty"` // Custom SRT config (optional) - Command string `yaml:"command,omitempty"` // Custom command to replace AWF or SRT installation - Args []string `yaml:"args,omitempty"` // Additional arguments to append to the command - Env map[string]string `yaml:"env,omitempty"` // Environment variables to set on the step - Mounts []string `yaml:"mounts,omitempty"` // Container mounts to add for AWF (format: "source:dest:mode") - Memory string `yaml:"memory,omitempty"` // Memory limit for the AWF container (e.g., "4g", "8g") - ModelFallback *TemplatableBool `yaml:"model-fallback,omitempty"` // AWF API proxy model fallback enable/disable flag (optional) - Targets map[string]*AgentAPIProxyTargetConfig `yaml:"targets,omitempty"` // Per-provider API proxy target overrides keyed by provider name (e.g. "openai", "anthropic") + ID string `yaml:"id,omitempty"` // Agent ID: "awf" or "srt" (replaces Type in new object format) + Type SandboxType `yaml:"type,omitempty"` // Sandbox type: "awf" or "srt" (legacy, use ID instead) + Version string `yaml:"version,omitempty"` // AWF version override used to install and run the matching firewall version + Platform string `yaml:"platform,omitempty"` // AWF platform.type override (github.com, ghes, ghec, ghec-self-hosted) + Disabled bool `yaml:"-"` // True when agent is explicitly set to false (disables firewall). This is a runtime flag, not serialized to YAML. + DisableReason string `yaml:"-"` // Operator-authored justification from dangerously-disable-sandbox-agent feature; available for diagnostics and audit logging. + Config *SandboxRuntimeConfig `yaml:"config,omitempty"` // Custom SRT config (optional) + Command string `yaml:"command,omitempty"` // Custom command to replace AWF or SRT installation + Args []string `yaml:"args,omitempty"` // Additional arguments to append to the command + Env map[string]string `yaml:"env,omitempty"` // Environment variables to set on the step + Mounts []string `yaml:"mounts,omitempty"` // Container mounts to add for AWF (format: "source:dest:mode") + Memory string `yaml:"memory,omitempty"` // Memory limit for the AWF container (e.g., "4g", "8g") + ModelFallback *TemplatableBool `yaml:"model-fallback,omitempty"` // AWF API proxy model fallback enable/disable flag (optional) + Targets map[string]*AgentAPIProxyTargetConfig `yaml:"targets,omitempty"` // Per-provider API proxy target overrides keyed by provider name (e.g. "openai", "anthropic") } // AgentAPIProxyTargetConfig configures a single LLM provider's API proxy target.