From 94a23a4949e6b9b9a21eb0e5f05b35af8140c285 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 03:49:31 +0000 Subject: [PATCH 1/6] Initial plan From 586f7c6dd83d0400a11b9dd0c89baa74c54f46f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 04:10:30 +0000 Subject: [PATCH 2/6] Add wiki support to repo-memory frontmatter configuration When wiki:true is set in repo-memory config: - Uses the GitHub Wiki git URL ({repo}.wiki.git) for clone/push - Defaults branch-name to 'master' (wiki default branch) - Disables create-orphan (wiki always exists) - Injects wiki-specific prompt text explaining GitHub Wiki syntax Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../agent-performance-analyzer.lock.yml | 4 +- .github/workflows/audit-workflows.lock.yml | 4 +- .../workflows/copilot-agent-analysis.lock.yml | 4 +- .../copilot-cli-deep-research.lock.yml | 4 +- .../copilot-pr-nlp-analysis.lock.yml | 4 +- .../copilot-pr-prompt-analysis.lock.yml | 4 +- .../copilot-session-insights.lock.yml | 4 +- .../workflows/daily-cli-performance.lock.yml | 4 +- .github/workflows/daily-code-metrics.lock.yml | 4 +- .../daily-copilot-token-report.lock.yml | 4 +- .github/workflows/daily-news.lock.yml | 4 +- .../daily-testify-uber-super-expert.lock.yml | 4 +- .github/workflows/deep-report.lock.yml | 4 +- .github/workflows/delight.lock.yml | 4 +- .../workflows/discussion-task-miner.lock.yml | 4 +- .github/workflows/firewall-escape.lock.yml | 4 +- .github/workflows/metrics-collector.lock.yml | 4 +- .github/workflows/pr-triage-agent.lock.yml | 4 +- .../workflows/security-compliance.lock.yml | 4 +- .../workflow-health-manager.lock.yml | 4 +- actions/setup/md/repo_memory_prompt.md | 2 +- .../docs/reference/frontmatter-full.md | 6 + pkg/parser/schemas/main_workflow_schema.json | 8 + pkg/workflow/repo_memory.go | 41 +++++ pkg/workflow/repo_memory_prompt.go | 13 ++ pkg/workflow/repo_memory_test.go | 164 ++++++++++++++++++ 26 files changed, 293 insertions(+), 21 deletions(-) diff --git a/.github/workflows/agent-performance-analyzer.lock.yml b/.github/workflows/agent-performance-analyzer.lock.yml index 3b22ba87134..8ab84c5815f 100644 --- a/.github/workflows/agent-performance-analyzer.lock.yml +++ b/.github/workflows/agent-performance-analyzer.lock.yml @@ -200,6 +200,7 @@ jobs: GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }} + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -224,7 +225,8 @@ jobs: GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, - GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED + GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index 63546f855e3..bca5aecb0b3 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -218,6 +218,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical audit data and patterns' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -244,7 +245,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml index 46335e24572..f5c08a6c3da 100644 --- a/.github/workflows/copilot-agent-analysis.lock.yml +++ b/.github/workflows/copilot-agent-analysis.lock.yml @@ -220,6 +220,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical agent performance metrics' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -246,7 +247,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/copilot-cli-deep-research.lock.yml b/.github/workflows/copilot-cli-deep-research.lock.yml index 9dc4080f252..6872cbd2b84 100644 --- a/.github/workflows/copilot-cli-deep-research.lock.yml +++ b/.github/workflows/copilot-cli-deep-research.lock.yml @@ -200,6 +200,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Copilot CLI research notes and analysis history' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -223,7 +224,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml index f4ac0f66d91..cfe6bee2517 100644 --- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml +++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml @@ -220,6 +220,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical NLP analysis results' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -246,7 +247,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml index c5ea058388d..1eef24d9601 100644 --- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml +++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml @@ -215,6 +215,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical prompt pattern analysis' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -241,7 +242,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml index 837cfb4c851..f2e3c08319f 100644 --- a/.github/workflows/copilot-session-insights.lock.yml +++ b/.github/workflows/copilot-session-insights.lock.yml @@ -234,6 +234,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical session analysis data' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -261,7 +262,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index 2bad32f25bd..66e88aaa3b5 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -206,6 +206,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical CLI compilation performance benchmark results' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -230,7 +231,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml index c1d72380dd2..dc7671fd470 100644 --- a/.github/workflows/daily-code-metrics.lock.yml +++ b/.github/workflows/daily-code-metrics.lock.yml @@ -217,6 +217,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical code quality and health metrics' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -243,7 +244,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml index 53744687a22..f23f3a9b652 100644 --- a/.github/workflows/daily-copilot-token-report.lock.yml +++ b/.github/workflows/daily-copilot-token-report.lock.yml @@ -208,6 +208,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical token consumption and cost data' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -234,7 +235,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index 53c5d868236..7d03b192b64 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -218,6 +218,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Historical news digest data' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -244,7 +245,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/daily-testify-uber-super-expert.lock.yml b/.github/workflows/daily-testify-uber-super-expert.lock.yml index 318bf6a4817..6449bb23726 100644 --- a/.github/workflows/daily-testify-uber-super-expert.lock.yml +++ b/.github/workflows/daily-testify-uber-super-expert.lock.yml @@ -211,6 +211,7 @@ jobs: GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }} + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -235,7 +236,8 @@ jobs: GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, - GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED + GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index e3382421114..59ef2a37b39 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -217,6 +217,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Long-term insights, patterns, and trend data' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -243,7 +244,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/delight.lock.yml b/.github/workflows/delight.lock.yml index 16a7a9eae44..e996407fcf8 100644 --- a/.github/workflows/delight.lock.yml +++ b/.github/workflows/delight.lock.yml @@ -203,6 +203,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Track delight findings and historical patterns' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -226,7 +227,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index b543b2a6695..4f7ffd06bc8 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -204,6 +204,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: ' Track processed discussions and extracted tasks' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -227,7 +228,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/firewall-escape.lock.yml b/.github/workflows/firewall-escape.lock.yml index e05d92cdc7e..dcd3fad9b85 100644 --- a/.github/workflows/firewall-escape.lock.yml +++ b/.github/workflows/firewall-escape.lock.yml @@ -218,6 +218,7 @@ jobs: GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }} + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -245,7 +246,8 @@ jobs: GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, - GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED + GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/metrics-collector.lock.yml b/.github/workflows/metrics-collector.lock.yml index a17980b6ecf..8a73606f9e0 100644 --- a/.github/workflows/metrics-collector.lock.yml +++ b/.github/workflows/metrics-collector.lock.yml @@ -195,6 +195,7 @@ jobs: GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }} + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -219,7 +220,8 @@ jobs: GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, - GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED + GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index dd77e010226..aecfd85d800 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -200,6 +200,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: '' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -223,7 +224,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/security-compliance.lock.yml b/.github/workflows/security-compliance.lock.yml index 2234832ecb8..9574b31962b 100644 --- a/.github/workflows/security-compliance.lock.yml +++ b/.github/workflows/security-compliance.lock.yml @@ -227,6 +227,7 @@ jobs: GH_AW_MEMORY_DESCRIPTION: '' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -253,7 +254,8 @@ jobs: GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, - GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index 693e4bf813b..e83ff605892 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -206,6 +206,7 @@ jobs: GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }} + GH_AW_WIKI_NOTE: '' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -230,7 +231,8 @@ jobs: GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, - GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED + GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders diff --git a/actions/setup/md/repo_memory_prompt.md b/actions/setup/md/repo_memory_prompt.md index e706dc54921..a4dd0f9c32a 100644 --- a/actions/setup/md/repo_memory_prompt.md +++ b/actions/setup/md/repo_memory_prompt.md @@ -1,7 +1,7 @@ ## Repo Memory Available -You have access to a persistent repo memory folder at `__GH_AW_MEMORY_DIR__` where you can read and write files that are stored in a git branch.__GH_AW_MEMORY_DESCRIPTION__ +You have access to a persistent repo memory folder at `__GH_AW_MEMORY_DIR__` where you can read and write files that are stored in a git branch.__GH_AW_MEMORY_DESCRIPTION____GH_AW_WIKI_NOTE__ - **Read/Write Access**: You can freely read from and write to any files in this folder - **Git Branch Storage**: Files are stored in the `__GH_AW_MEMORY_BRANCH_NAME__` branch__GH_AW_MEMORY_TARGET_REPO__ diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index ae4523395de..023fb1b5729 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -1865,6 +1865,12 @@ tools: # (optional) create-orphan: true + # Use the GitHub Wiki git repository instead of the regular repository. When enabled, + # files are stored in and read from the wiki, and the agent will be instructed to + # follow GitHub Wiki markdown syntax (default: false) + # (optional) + wiki: false + # List of allowed file extensions (e.g., [".json", ".txt"]). Default: [".json", # ".jsonl", ".txt", ".md", ".csv"] # (optional) diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index d06a8b4c4e6..2fdd3a2fc6a 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -3648,6 +3648,10 @@ "type": "boolean", "description": "Create orphaned branch if it doesn't exist (default: true)" }, + "wiki": { + "type": "boolean", + "description": "Use the GitHub Wiki git repository instead of the regular repository. When enabled, files are stored in and read from the wiki, and the agent will be instructed to follow GitHub Wiki markdown syntax (default: false)" + }, "allowed-extensions": { "type": "array", "items": { @@ -3729,6 +3733,10 @@ "type": "boolean", "description": "Create orphaned branch if it doesn't exist (default: true)" }, + "wiki": { + "type": "boolean", + "description": "Use the GitHub Wiki git repository instead of the regular repository. When enabled, files are stored in and read from the wiki, and the agent will be instructed to follow GitHub Wiki markdown syntax (default: false)" + }, "allowed-extensions": { "type": "array", "items": { diff --git a/pkg/workflow/repo_memory.go b/pkg/workflow/repo_memory.go index b77189e3017..5c4c896e6fe 100644 --- a/pkg/workflow/repo_memory.go +++ b/pkg/workflow/repo_memory.go @@ -61,6 +61,7 @@ type RepoMemoryEntry struct { Description string `yaml:"description,omitempty"` // optional description for this memory CreateOrphan bool `yaml:"create-orphan,omitempty"` // create orphaned branch if missing (default: true) AllowedExtensions []string `yaml:"allowed-extensions,omitempty"` // allowed file extensions (default: [".json", ".jsonl", ".txt", ".md", ".csv"]) + Wiki bool `yaml:"wiki,omitempty"` // use the GitHub Wiki git repository instead of the regular repo } // RepoMemoryToolConfig represents the configuration for repo-memory in tools @@ -220,9 +221,11 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig, workflowID } // Parse branch-name + explicitBranchName := false if branchName, exists := memoryMap["branch-name"]; exists { if branchStr, ok := branchName.(string); ok { entry.BranchName = branchStr + explicitBranchName = true } } // Set default branch name if not specified. @@ -309,6 +312,20 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig, workflowID } } + // Parse wiki field + if wiki, exists := memoryMap["wiki"]; exists { + if wikiBool, ok := wiki.(bool); ok { + entry.Wiki = wikiBool + } + } + // Apply wiki-mode defaults: wikis use master branch and never need orphan creation + if entry.Wiki { + if !explicitBranchName { + entry.BranchName = "master" + } + entry.CreateOrphan = false + } + // Parse allowed-extensions field if allowedExts, exists := memoryMap["allowed-extensions"]; exists { if extArray, ok := allowedExts.([]any); ok { @@ -370,9 +387,11 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig, workflowID } // Parse branch-name + explicitBranchName := false if branchName, exists := configMap["branch-name"]; exists { if branchStr, ok := branchName.(string); ok { entry.BranchName = branchStr + explicitBranchName = true } } @@ -450,6 +469,20 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig, workflowID } } + // Parse wiki field + if wiki, exists := configMap["wiki"]; exists { + if wikiBool, ok := wiki.(bool); ok { + entry.Wiki = wikiBool + } + } + // Apply wiki-mode defaults: wikis use master branch and never need orphan creation + if entry.Wiki { + if !explicitBranchName { + entry.BranchName = "master" + } + entry.CreateOrphan = false + } + // Parse allowed-extensions field if allowedExts, exists := configMap["allowed-extensions"]; exists { if extArray, ok := allowedExts.([]any); ok { @@ -619,6 +652,10 @@ func generateRepoMemorySteps(builder *strings.Builder, data *WorkflowData) { if targetRepo == "" { targetRepo = "${{ github.repository }}" } + // For wiki mode, append .wiki to the repo path so the clone script uses the wiki git URL + if memory.Wiki { + targetRepo = targetRepo + ".wiki" + } // Determine the memory directory memoryDir := "/tmp/gh-aw/repo-memory/" + memory.ID @@ -697,6 +734,10 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna if targetRepo == "" { targetRepo = "${{ github.repository }}" } + // For wiki mode, append .wiki to the repo path so the push script uses the wiki git URL + if memory.Wiki { + targetRepo = targetRepo + ".wiki" + } artifactDir := "/tmp/gh-aw/repo-memory/" + memory.ID diff --git a/pkg/workflow/repo_memory_prompt.go b/pkg/workflow/repo_memory_prompt.go index 8856d2b8fcf..088d9dcc7d4 100644 --- a/pkg/workflow/repo_memory_prompt.go +++ b/pkg/workflow/repo_memory_prompt.go @@ -58,6 +58,15 @@ func buildRepoMemoryPromptSection(config *RepoMemoryConfig) *PromptSection { constraintsText = constraints.String() } + // Build wiki note text (non-empty only when wiki mode is enabled) + wikiNoteText := "" + if memory.Wiki { + wikiNoteText = "\n\n> **GitHub Wiki**: This memory is backed by the GitHub Wiki for this repository. " + + "Files use GitHub Wiki Markdown syntax. Follow GitHub Wiki conventions when creating or editing pages " + + "(e.g., use standard Markdown headers, use `[[Page Name]]` syntax for internal wiki links, " + + "name page files with spaces replaced by hyphens or use the wiki page title as the filename)." + } + return &PromptSection{ Content: repoMemoryPromptFile, IsFile: true, @@ -67,6 +76,7 @@ func buildRepoMemoryPromptSection(config *RepoMemoryConfig) *PromptSection { "GH_AW_MEMORY_BRANCH_NAME": memory.BranchName, "GH_AW_MEMORY_TARGET_REPO": targetRepoText, "GH_AW_MEMORY_CONSTRAINTS": constraintsText, + "GH_AW_WIKI_NOTE": wikiNoteText, }, } } @@ -86,6 +96,9 @@ func buildRepoMemoryPromptSection(config *RepoMemoryConfig) *PromptSection { if memory.TargetRepo != "" { fmt.Fprintf(&memoryList, " in `%s`", memory.TargetRepo) } + if memory.Wiki { + memoryList.WriteString(", GitHub Wiki") + } memoryList.WriteString(")\n") } diff --git a/pkg/workflow/repo_memory_test.go b/pkg/workflow/repo_memory_test.go index ea047305e37..205143ddffb 100644 --- a/pkg/workflow/repo_memory_test.go +++ b/pkg/workflow/repo_memory_test.go @@ -1026,3 +1026,167 @@ func TestInvalidBranchPrefixRejectsConfig(t *testing.T) { }) } } + +// TestRepoMemoryWikiObjectConfig tests that wiki:true in object config works correctly +func TestRepoMemoryWikiObjectConfig(t *testing.T) { + toolsMap := map[string]any{ + "repo-memory": map[string]any{ + "wiki": true, + }, + } + + toolsConfig, err := ParseToolsConfig(toolsMap) + require.NoError(t, err, "Failed to parse tools config") + + compiler := NewCompiler() + config, err := compiler.extractRepoMemoryConfig(toolsConfig, "my-workflow") + require.NoError(t, err, "Failed to extract repo-memory config") + require.NotNil(t, config, "Expected non-nil config") + require.Len(t, config.Memories, 1, "Expected 1 memory") + + memory := config.Memories[0] + assert.True(t, memory.Wiki, "Expected wiki to be true") + assert.Equal(t, "master", memory.BranchName, "Wiki mode should default to master branch") + assert.False(t, memory.CreateOrphan, "Wiki mode should disable create-orphan") +} + +// TestRepoMemoryWikiArrayConfig tests that wiki:true in array config works correctly +func TestRepoMemoryWikiArrayConfig(t *testing.T) { + toolsMap := map[string]any{ + "repo-memory": []any{ + map[string]any{ + "id": "wiki-memory", + "wiki": true, + }, + }, + } + + toolsConfig, err := ParseToolsConfig(toolsMap) + require.NoError(t, err, "Failed to parse tools config") + + compiler := NewCompiler() + config, err := compiler.extractRepoMemoryConfig(toolsConfig, "my-workflow") + require.NoError(t, err, "Failed to extract repo-memory config") + require.NotNil(t, config, "Expected non-nil config") + require.Len(t, config.Memories, 1, "Expected 1 memory") + + memory := config.Memories[0] + assert.Equal(t, "wiki-memory", memory.ID, "Expected correct memory ID") + assert.True(t, memory.Wiki, "Expected wiki to be true") + assert.Equal(t, "master", memory.BranchName, "Wiki mode should default to master branch") + assert.False(t, memory.CreateOrphan, "Wiki mode should disable create-orphan") +} + +// TestRepoMemoryWikiCustomBranchName tests that wiki mode respects an explicit branch-name +func TestRepoMemoryWikiCustomBranchName(t *testing.T) { + toolsMap := map[string]any{ + "repo-memory": map[string]any{ + "wiki": true, + "branch-name": "custom-branch", + }, + } + + toolsConfig, err := ParseToolsConfig(toolsMap) + require.NoError(t, err, "Failed to parse tools config") + + compiler := NewCompiler() + config, err := compiler.extractRepoMemoryConfig(toolsConfig, "") + require.NoError(t, err, "Failed to extract repo-memory config") + require.NotNil(t, config, "Expected non-nil config") + + memory := config.Memories[0] + assert.True(t, memory.Wiki, "Expected wiki to be true") + assert.Equal(t, "custom-branch", memory.BranchName, "Wiki mode should respect explicit branch-name") +} + +// TestRepoMemoryWikiStepsGeneration tests that wiki:true appends .wiki to TARGET_REPO +func TestRepoMemoryWikiStepsGeneration(t *testing.T) { + config := &RepoMemoryConfig{ + Memories: []RepoMemoryEntry{ + { + ID: "default", + BranchName: "master", + Wiki: true, + }, + }, + } + + data := &WorkflowData{ + RepoMemoryConfig: config, + } + + var builder strings.Builder + generateRepoMemorySteps(&builder, data) + + output := builder.String() + assert.Contains(t, output, "TARGET_REPO: ${{ github.repository }}.wiki", + "Wiki mode should append .wiki to TARGET_REPO") +} + +// TestRepoMemoryWikiStepsWithTargetRepo tests wiki mode with explicit target-repo +func TestRepoMemoryWikiStepsWithTargetRepo(t *testing.T) { + config := &RepoMemoryConfig{ + Memories: []RepoMemoryEntry{ + { + ID: "default", + BranchName: "master", + TargetRepo: "myorg/myrepo", + Wiki: true, + }, + }, + } + + data := &WorkflowData{ + RepoMemoryConfig: config, + } + + var builder strings.Builder + generateRepoMemorySteps(&builder, data) + + output := builder.String() + assert.Contains(t, output, "TARGET_REPO: myorg/myrepo.wiki", + "Wiki mode should append .wiki to explicit target-repo") +} + +// TestRepoMemoryWikiPromptSection tests that wiki mode injects wiki note into prompt +func TestRepoMemoryWikiPromptSection(t *testing.T) { + config := &RepoMemoryConfig{ + Memories: []RepoMemoryEntry{ + { + ID: "default", + BranchName: "master", + Wiki: true, + }, + }, + } + + section := buildRepoMemoryPromptSection(config) + + require.NotNil(t, section, "Expected non-nil prompt section") + require.NotNil(t, section.EnvVars, "Expected env vars") + + wikiNote := section.EnvVars["GH_AW_WIKI_NOTE"] + assert.NotEmpty(t, wikiNote, "Wiki mode should set GH_AW_WIKI_NOTE") + assert.Contains(t, wikiNote, "GitHub Wiki", "Wiki note should mention GitHub Wiki") + assert.Contains(t, wikiNote, "Markdown", "Wiki note should mention Markdown syntax") +} + +// TestRepoMemoryNonWikiPromptSection tests that non-wiki mode has empty wiki note +func TestRepoMemoryNonWikiPromptSection(t *testing.T) { + config := &RepoMemoryConfig{ + Memories: []RepoMemoryEntry{ + { + ID: "default", + BranchName: "memory/default", + }, + }, + } + + section := buildRepoMemoryPromptSection(config) + + require.NotNil(t, section, "Expected non-nil prompt section") + require.NotNil(t, section.EnvVars, "Expected env vars") + + wikiNote := section.EnvVars["GH_AW_WIKI_NOTE"] + assert.Empty(t, wikiNote, "Non-wiki mode should have empty GH_AW_WIKI_NOTE") +} From 2161624d5418eeeba2ae0bbda686e3874eb59d33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:04:11 +0000 Subject: [PATCH 3/6] Enable wiki memory on glossary-maintainer, developer-docs-consolidator, technical-doc-writer These 3 workflows produce documentation that benefits from GitHub Wiki backing: - glossary-maintainer: stores project glossary in wiki for browseable reference - developer-docs-consolidator: stores consolidated dev docs in wiki - technical-doc-writer: stores written docs in wiki with wiki markdown conventions Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../developer-docs-consolidator.lock.yml | 108 +++++++++++++++++- .../workflows/developer-docs-consolidator.md | 3 + .../workflows/glossary-maintainer.lock.yml | 108 +++++++++++++++++- .github/workflows/glossary-maintainer.md | 3 + .../workflows/technical-doc-writer.lock.yml | 108 +++++++++++++++++- .github/workflows/technical-doc-writer.md | 3 + 6 files changed, 327 insertions(+), 6 deletions(-) diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index 97d64f72de9..3f67a8cfa00 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -28,7 +28,7 @@ # - shared/mcp/serena-go.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"fd13d49c5ea89ae0018ad18fa3283f32c323a71e7c28d56d74645be5ceeb85d4"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"ba20f92152708c40f6b55c5384131f6e54f60e07c1d5f0fe932645b137b1ee2e"} name: "Developer Documentation Consolidator" "on": @@ -133,6 +133,7 @@ jobs: cat "/opt/gh-aw/prompts/temp_folder_prompt.md" cat "/opt/gh-aw/prompts/markdown.md" cat "/opt/gh-aw/prompts/cache_memory_prompt.md" + cat "/opt/gh-aw/prompts/repo_memory_prompt.md" cat "/opt/gh-aw/prompts/safe_outputs_prompt.md" cat << 'GH_AW_PROMPT_EOF' @@ -210,6 +211,12 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_MEMORY_BRANCH_NAME: 'master' + GH_AW_MEMORY_CONSTRAINTS: "\n\n**Constraints:**\n- **Max File Size**: 10240 bytes (0.01 MB) per file\n- **Max File Count**: 100 files per commit\n- **Max Patch Size**: 10240 bytes (10 KB) total per push (max: 100 KB)\n" + GH_AW_MEMORY_DESCRIPTION: ' Consolidated developer documentation and instructions' + GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' + GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: "\n\n> **GitHub Wiki**: This memory is backed by the GitHub Wiki for this repository. Files use GitHub Wiki Markdown syntax. Follow GitHub Wiki conventions when creating or editing pages (e.g., use standard Markdown headers, use `[[Page Name]]` syntax for internal wiki links, name page files with spaces replaced by hyphens or use the wiki page title as the filename)." with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -231,7 +238,13 @@ jobs: GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE + GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_MEMORY_BRANCH_NAME: process.env.GH_AW_MEMORY_BRANCH_NAME, + GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, + GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, + GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders @@ -307,6 +320,16 @@ jobs: path: /tmp/gh-aw/cache-memory restore-keys: | developer-docs-cache- + # Repo memory git-based storage configuration from frontmatter processed below + - name: Clone repo-memory branch (default) + env: + GH_TOKEN: ${{ github.token }} + GITHUB_SERVER_URL: ${{ github.server_url }} + BRANCH_NAME: master + TARGET_REPO: ${{ github.repository }}.wiki + MEMORY_DIR: /tmp/gh-aw/repo-memory/default + CREATE_ORPHAN: false + run: bash /opt/gh-aw/actions/clone_repo_memory_branch.sh - name: Configure Git credentials env: REPO_NAME: ${{ github.repository }} @@ -999,6 +1022,15 @@ jobs: else echo 'AWF binary not installed, skipping firewall log summary' fi + # Upload repo memory as artifacts for push job + - name: Upload repo-memory artifact (default) + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 + with: + name: repo-memory-default + path: /tmp/gh-aw/repo-memory/default + retention-days: 1 + if-no-files-found: ignore - name: Upload cache-memory data as artifact uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 if: always() @@ -1150,6 +1182,7 @@ jobs: needs: - activation - agent + - push_repo_memory - safe_outputs - update_cache_memory if: (always()) && (needs.agent.result != 'skipped') @@ -1232,6 +1265,8 @@ jobs: GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" GH_AW_TIMEOUT_MINUTES: "30" with: @@ -1273,6 +1308,75 @@ jobs: const { main } = require('/opt/gh-aw/actions/handle_create_pr_error.cjs'); await main(); + push_repo_memory: + needs: agent + if: always() && needs.agent.outputs.detection_success == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + concurrency: + group: "push-repo-memory-${{ github.repository }}" + cancel-in-progress: false + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} + steps: + - name: Checkout actions folder + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + sparse-checkout: | + actions + persist-credentials: false + - name: Setup Scripts + uses: ./actions/setup + with: + destination: /opt/gh-aw/actions + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + sparse-checkout: . + - name: Configure Git credentials + env: + REPO_NAME: ${{ github.repository }} + SERVER_URL: ${{ github.server_url }} + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git config --global am.keepcr true + # Re-authenticate git with GitHub token + SERVER_URL_STRIPPED="${SERVER_URL#https://}" + git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" + echo "Git configured with standard GitHub Actions identity" + - name: Download repo-memory artifact (default) + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8 + continue-on-error: true + with: + name: repo-memory-default + path: /tmp/gh-aw/repo-memory/default + - name: Push repo-memory changes (default) + id: push_repo_memory_default + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + GH_TOKEN: ${{ github.token }} + GITHUB_RUN_ID: ${{ github.run_id }} + GITHUB_SERVER_URL: ${{ github.server_url }} + ARTIFACT_DIR: /tmp/gh-aw/repo-memory/default + MEMORY_ID: default + TARGET_REPO: ${{ github.repository }}.wiki + BRANCH_NAME: master + MAX_FILE_SIZE: 10240 + MAX_FILE_COUNT: 100 + MAX_PATCH_SIZE: 10240 + ALLOWED_EXTENSIONS: '[]' + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('/opt/gh-aw/actions/push_repo_memory.cjs'); + await main(); + safe_outputs: needs: - activation diff --git a/.github/workflows/developer-docs-consolidator.md b/.github/workflows/developer-docs-consolidator.md index 2fb8ff55bfa..bafcc7b9fca 100644 --- a/.github/workflows/developer-docs-consolidator.md +++ b/.github/workflows/developer-docs-consolidator.md @@ -35,6 +35,9 @@ safe-outputs: tools: cache-memory: key: developer-docs-cache + repo-memory: + wiki: true + description: "Consolidated developer documentation and instructions" github: toolsets: [default] edit: diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 0f442ba0325..577c5375d02 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -29,7 +29,7 @@ # - ../skills/documentation/SKILL.md # - shared/mcp/serena-go.md # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"08dcdc5b5ba8dec921cd60fdced8e0fdcdbefbc60f9e28ee4d9264e060d1d15b"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"a8396d3fdc420a67bda3195b1a040e89160fd59ac515a342320200c977c49452"} name: "Glossary Maintainer" "on": @@ -133,6 +133,7 @@ jobs: cat "/opt/gh-aw/prompts/temp_folder_prompt.md" cat "/opt/gh-aw/prompts/markdown.md" cat "/opt/gh-aw/prompts/cache_memory_prompt.md" + cat "/opt/gh-aw/prompts/repo_memory_prompt.md" cat "/opt/gh-aw/prompts/safe_outputs_prompt.md" cat << 'GH_AW_PROMPT_EOF' @@ -212,6 +213,12 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_MEMORY_BRANCH_NAME: 'master' + GH_AW_MEMORY_CONSTRAINTS: "\n\n**Constraints:**\n- **Max File Size**: 10240 bytes (0.01 MB) per file\n- **Max File Count**: 100 files per commit\n- **Max Patch Size**: 10240 bytes (10 KB) total per push (max: 100 KB)\n" + GH_AW_MEMORY_DESCRIPTION: ' Project glossary and terminology reference' + GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' + GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: "\n\n> **GitHub Wiki**: This memory is backed by the GitHub Wiki for this repository. Files use GitHub Wiki Markdown syntax. Follow GitHub Wiki conventions when creating or editing pages (e.g., use standard Markdown headers, use `[[Page Name]]` syntax for internal wiki links, name page files with spaces replaced by hyphens or use the wiki page title as the filename)." with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -233,7 +240,13 @@ jobs: GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE + GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_MEMORY_BRANCH_NAME: process.env.GH_AW_MEMORY_BRANCH_NAME, + GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, + GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, + GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders @@ -321,6 +334,16 @@ jobs: path: /tmp/gh-aw/cache-memory restore-keys: | memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- + # Repo memory git-based storage configuration from frontmatter processed below + - name: Clone repo-memory branch (default) + env: + GH_TOKEN: ${{ github.token }} + GITHUB_SERVER_URL: ${{ github.server_url }} + BRANCH_NAME: master + TARGET_REPO: ${{ github.repository }}.wiki + MEMORY_DIR: /tmp/gh-aw/repo-memory/default + CREATE_ORPHAN: false + run: bash /opt/gh-aw/actions/clone_repo_memory_branch.sh - name: Configure Git credentials env: REPO_NAME: ${{ github.repository }} @@ -905,6 +928,15 @@ jobs: else echo 'AWF binary not installed, skipping firewall log summary' fi + # Upload repo memory as artifacts for push job + - name: Upload repo-memory artifact (default) + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 + with: + name: repo-memory-default + path: /tmp/gh-aw/repo-memory/default + retention-days: 1 + if-no-files-found: ignore - name: Upload cache-memory data as artifact uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 if: always() @@ -1046,6 +1078,7 @@ jobs: needs: - activation - agent + - push_repo_memory - safe_outputs - update_cache_memory if: (always()) && (needs.agent.result != 'skipped') @@ -1126,6 +1159,8 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" GH_AW_TIMEOUT_MINUTES: "20" with: @@ -1167,6 +1202,75 @@ jobs: const { main } = require('/opt/gh-aw/actions/handle_create_pr_error.cjs'); await main(); + push_repo_memory: + needs: agent + if: always() && needs.agent.outputs.detection_success == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + concurrency: + group: "push-repo-memory-${{ github.repository }}" + cancel-in-progress: false + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} + steps: + - name: Checkout actions folder + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + sparse-checkout: | + actions + persist-credentials: false + - name: Setup Scripts + uses: ./actions/setup + with: + destination: /opt/gh-aw/actions + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + sparse-checkout: . + - name: Configure Git credentials + env: + REPO_NAME: ${{ github.repository }} + SERVER_URL: ${{ github.server_url }} + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git config --global am.keepcr true + # Re-authenticate git with GitHub token + SERVER_URL_STRIPPED="${SERVER_URL#https://}" + git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" + echo "Git configured with standard GitHub Actions identity" + - name: Download repo-memory artifact (default) + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8 + continue-on-error: true + with: + name: repo-memory-default + path: /tmp/gh-aw/repo-memory/default + - name: Push repo-memory changes (default) + id: push_repo_memory_default + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + GH_TOKEN: ${{ github.token }} + GITHUB_RUN_ID: ${{ github.run_id }} + GITHUB_SERVER_URL: ${{ github.server_url }} + ARTIFACT_DIR: /tmp/gh-aw/repo-memory/default + MEMORY_ID: default + TARGET_REPO: ${{ github.repository }}.wiki + BRANCH_NAME: master + MAX_FILE_SIZE: 10240 + MAX_FILE_COUNT: 100 + MAX_PATCH_SIZE: 10240 + ALLOWED_EXTENSIONS: '[]' + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('/opt/gh-aw/actions/push_repo_memory.cjs'); + await main(); + safe_outputs: needs: - activation diff --git a/.github/workflows/glossary-maintainer.md b/.github/workflows/glossary-maintainer.md index b58c4d9183e..47fec3ce330 100644 --- a/.github/workflows/glossary-maintainer.md +++ b/.github/workflows/glossary-maintainer.md @@ -36,6 +36,9 @@ safe-outputs: tools: cache-memory: true + repo-memory: + wiki: true + description: "Project glossary and terminology reference" github: toolsets: [default] edit: diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index 2fc61a499e3..9903a4547e1 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -28,7 +28,7 @@ # - ../agents/technical-doc-writer.agent.md # - ../skills/documentation/SKILL.md # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"f174f894cfb342e523c23e48a2c841a391fdfb8ac21ab6f7f1160f434906bb2f"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"d344e91215e214c742c60a7c71f20c15fd9f545fa90bfe88550b392cbd69fb93"} name: "Rebuild the documentation after making changes" "on": @@ -136,6 +136,7 @@ jobs: cat "/opt/gh-aw/prompts/temp_folder_prompt.md" cat "/opt/gh-aw/prompts/markdown.md" cat "/opt/gh-aw/prompts/cache_memory_prompt.md" + cat "/opt/gh-aw/prompts/repo_memory_prompt.md" cat "/opt/gh-aw/prompts/safe_outputs_prompt.md" cat << 'GH_AW_PROMPT_EOF' @@ -215,6 +216,12 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_MEMORY_BRANCH_NAME: 'master' + GH_AW_MEMORY_CONSTRAINTS: "\n\n**Constraints:**\n- **Max File Size**: 10240 bytes (0.01 MB) per file\n- **Max File Count**: 100 files per commit\n- **Max Patch Size**: 10240 bytes (10 KB) total per push (max: 100 KB)\n" + GH_AW_MEMORY_DESCRIPTION: ' Technical documentation library' + GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' + GH_AW_MEMORY_TARGET_REPO: ' of the current repository' + GH_AW_WIKI_NOTE: "\n\n> **GitHub Wiki**: This memory is backed by the GitHub Wiki for this repository. Files use GitHub Wiki Markdown syntax. Follow GitHub Wiki conventions when creating or editing pages (e.g., use standard Markdown headers, use `[[Page Name]]` syntax for internal wiki links, name page files with spaces replaced by hyphens or use the wiki page title as the filename)." with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -237,7 +244,13 @@ jobs: GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE + GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_MEMORY_BRANCH_NAME: process.env.GH_AW_MEMORY_BRANCH_NAME, + GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS, + GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION, + GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR, + GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO, + GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE } }); - name: Validate prompt placeholders @@ -339,6 +352,16 @@ jobs: path: /tmp/gh-aw/cache-memory restore-keys: | memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- + # Repo memory git-based storage configuration from frontmatter processed below + - name: Clone repo-memory branch (default) + env: + GH_TOKEN: ${{ github.token }} + GITHUB_SERVER_URL: ${{ github.server_url }} + BRANCH_NAME: master + TARGET_REPO: ${{ github.repository }}.wiki + MEMORY_DIR: /tmp/gh-aw/repo-memory/default + CREATE_ORPHAN: false + run: bash /opt/gh-aw/actions/clone_repo_memory_branch.sh - name: Configure Git credentials env: REPO_NAME: ${{ github.repository }} @@ -974,6 +997,15 @@ jobs: else echo 'AWF binary not installed, skipping firewall log summary' fi + # Upload repo memory as artifacts for push job + - name: Upload repo-memory artifact (default) + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 + with: + name: repo-memory-default + path: /tmp/gh-aw/repo-memory/default + retention-days: 1 + if-no-files-found: ignore - name: Upload cache-memory data as artifact uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 if: always() @@ -1124,6 +1156,7 @@ jobs: needs: - activation - agent + - push_repo_memory - safe_outputs - update_cache_memory - upload_assets @@ -1207,6 +1240,8 @@ jobs: GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📝 *Documentation by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"✍️ The Technical Writer begins! [{workflow_name}]({run_url}) is documenting this {event_type}...\",\"runSuccess\":\"📝 Documentation complete! [{workflow_name}]({run_url}) has written the docs. Clear as crystal! ✨\",\"runFailure\":\"✍️ Writer's block! [{workflow_name}]({run_url}) {status}. The page remains blank...\"}" + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" GH_AW_TIMEOUT_MINUTES: "10" with: @@ -1248,6 +1283,75 @@ jobs: const { main } = require('/opt/gh-aw/actions/handle_create_pr_error.cjs'); await main(); + push_repo_memory: + needs: agent + if: always() && needs.agent.outputs.detection_success == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + concurrency: + group: "push-repo-memory-${{ github.repository }}" + cancel-in-progress: false + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} + steps: + - name: Checkout actions folder + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + sparse-checkout: | + actions + persist-credentials: false + - name: Setup Scripts + uses: ./actions/setup + with: + destination: /opt/gh-aw/actions + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + sparse-checkout: . + - name: Configure Git credentials + env: + REPO_NAME: ${{ github.repository }} + SERVER_URL: ${{ github.server_url }} + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git config --global am.keepcr true + # Re-authenticate git with GitHub token + SERVER_URL_STRIPPED="${SERVER_URL#https://}" + git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" + echo "Git configured with standard GitHub Actions identity" + - name: Download repo-memory artifact (default) + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8 + continue-on-error: true + with: + name: repo-memory-default + path: /tmp/gh-aw/repo-memory/default + - name: Push repo-memory changes (default) + id: push_repo_memory_default + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + GH_TOKEN: ${{ github.token }} + GITHUB_RUN_ID: ${{ github.run_id }} + GITHUB_SERVER_URL: ${{ github.server_url }} + ARTIFACT_DIR: /tmp/gh-aw/repo-memory/default + MEMORY_ID: default + TARGET_REPO: ${{ github.repository }}.wiki + BRANCH_NAME: master + MAX_FILE_SIZE: 10240 + MAX_FILE_COUNT: 100 + MAX_PATCH_SIZE: 10240 + ALLOWED_EXTENSIONS: '[]' + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('/opt/gh-aw/actions/push_repo_memory.cjs'); + await main(); + safe_outputs: needs: - activation diff --git a/.github/workflows/technical-doc-writer.md b/.github/workflows/technical-doc-writer.md index 5a3c9bbc2bd..22c35d86155 100644 --- a/.github/workflows/technical-doc-writer.md +++ b/.github/workflows/technical-doc-writer.md @@ -63,6 +63,9 @@ steps: tools: cache-memory: true + repo-memory: + wiki: true + description: "Technical documentation library" github: toolsets: [default] edit: From 263c60ac3174db231e819684051b47ab0b7cf593 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:23:56 +0000 Subject: [PATCH 4/6] Update generated step names to reflect wiki mode (wiki-memory vs repo-memory) - Clone wiki-memory branch / Clone repo-memory branch - Upload wiki-memory artifact / Upload repo-memory artifact - Download wiki-memory artifact / Download repo-memory artifact - Push wiki-memory changes / Push repo-memory changes Also add step name assertions to existing wiki tests. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../developer-docs-consolidator.lock.yml | 8 ++--- .../workflows/glossary-maintainer.lock.yml | 8 ++--- .../workflows/technical-doc-writer.lock.yml | 8 ++--- pkg/workflow/repo_memory.go | 30 +++++++++++++++---- pkg/workflow/repo_memory_test.go | 4 +++ 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index 3f67a8cfa00..2fb0794f0dd 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -321,7 +321,7 @@ jobs: restore-keys: | developer-docs-cache- # Repo memory git-based storage configuration from frontmatter processed below - - name: Clone repo-memory branch (default) + - name: Clone wiki-memory branch (default) env: GH_TOKEN: ${{ github.token }} GITHUB_SERVER_URL: ${{ github.server_url }} @@ -1023,7 +1023,7 @@ jobs: echo 'AWF binary not installed, skipping firewall log summary' fi # Upload repo memory as artifacts for push job - - name: Upload repo-memory artifact (default) + - name: Upload wiki-memory artifact (default) if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: @@ -1348,13 +1348,13 @@ jobs: SERVER_URL_STRIPPED="${SERVER_URL#https://}" git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" echo "Git configured with standard GitHub Actions identity" - - name: Download repo-memory artifact (default) + - name: Download wiki-memory artifact (default) uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8 continue-on-error: true with: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - - name: Push repo-memory changes (default) + - name: Push wiki-memory changes (default) id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 577c5375d02..2fc646d225c 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -335,7 +335,7 @@ jobs: restore-keys: | memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- # Repo memory git-based storage configuration from frontmatter processed below - - name: Clone repo-memory branch (default) + - name: Clone wiki-memory branch (default) env: GH_TOKEN: ${{ github.token }} GITHUB_SERVER_URL: ${{ github.server_url }} @@ -929,7 +929,7 @@ jobs: echo 'AWF binary not installed, skipping firewall log summary' fi # Upload repo memory as artifacts for push job - - name: Upload repo-memory artifact (default) + - name: Upload wiki-memory artifact (default) if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: @@ -1242,13 +1242,13 @@ jobs: SERVER_URL_STRIPPED="${SERVER_URL#https://}" git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" echo "Git configured with standard GitHub Actions identity" - - name: Download repo-memory artifact (default) + - name: Download wiki-memory artifact (default) uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8 continue-on-error: true with: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - - name: Push repo-memory changes (default) + - name: Push wiki-memory changes (default) id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index 9903a4547e1..fafbe1ea7cd 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -353,7 +353,7 @@ jobs: restore-keys: | memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- # Repo memory git-based storage configuration from frontmatter processed below - - name: Clone repo-memory branch (default) + - name: Clone wiki-memory branch (default) env: GH_TOKEN: ${{ github.token }} GITHUB_SERVER_URL: ${{ github.server_url }} @@ -998,7 +998,7 @@ jobs: echo 'AWF binary not installed, skipping firewall log summary' fi # Upload repo memory as artifacts for push job - - name: Upload repo-memory artifact (default) + - name: Upload wiki-memory artifact (default) if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: @@ -1323,13 +1323,13 @@ jobs: SERVER_URL_STRIPPED="${SERVER_URL#https://}" git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" echo "Git configured with standard GitHub Actions identity" - - name: Download repo-memory artifact (default) + - name: Download wiki-memory artifact (default) uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8 continue-on-error: true with: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - - name: Push repo-memory changes (default) + - name: Push wiki-memory changes (default) id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 diff --git a/pkg/workflow/repo_memory.go b/pkg/workflow/repo_memory.go index 5c4c896e6fe..4b1b577f969 100644 --- a/pkg/workflow/repo_memory.go +++ b/pkg/workflow/repo_memory.go @@ -537,7 +537,11 @@ func generateRepoMemoryArtifactUpload(builder *strings.Builder, data *WorkflowDa sanitizedID := SanitizeWorkflowIDForCacheKey(memory.ID) // Step: Upload repo-memory directory as artifact - fmt.Fprintf(builder, " - name: Upload repo-memory artifact (%s)\n", memory.ID) + if memory.Wiki { + fmt.Fprintf(builder, " - name: Upload wiki-memory artifact (%s)\n", memory.ID) + } else { + fmt.Fprintf(builder, " - name: Upload repo-memory artifact (%s)\n", memory.ID) + } builder.WriteString(" if: always()\n") fmt.Fprintf(builder, " uses: %s\n", GetActionPin("actions/upload-artifact")) builder.WriteString(" with:\n") @@ -570,7 +574,11 @@ func generateRepoMemoryPushSteps(builder *strings.Builder, data *WorkflowData) { memoryDir := "/tmp/gh-aw/repo-memory/" + memory.ID // Step: Push changes to repo-memory branch - fmt.Fprintf(builder, " - name: Push repo-memory changes (%s)\n", memory.ID) + if memory.Wiki { + fmt.Fprintf(builder, " - name: Push wiki-memory changes (%s)\n", memory.ID) + } else { + fmt.Fprintf(builder, " - name: Push repo-memory changes (%s)\n", memory.ID) + } builder.WriteString(" if: always()\n") builder.WriteString(" env:\n") builder.WriteString(" GH_TOKEN: ${{ github.token }}\n") @@ -661,7 +669,11 @@ func generateRepoMemorySteps(builder *strings.Builder, data *WorkflowData) { memoryDir := "/tmp/gh-aw/repo-memory/" + memory.ID // Step 1: Clone the repo-memory branch - fmt.Fprintf(builder, " - name: Clone repo-memory branch (%s)\n", memory.ID) + if memory.Wiki { + fmt.Fprintf(builder, " - name: Clone wiki-memory branch (%s)\n", memory.ID) + } else { + fmt.Fprintf(builder, " - name: Clone repo-memory branch (%s)\n", memory.ID) + } builder.WriteString(" env:\n") builder.WriteString(" GH_TOKEN: ${{ github.token }}\n") builder.WriteString(" GITHUB_SERVER_URL: ${{ github.server_url }}\n") @@ -716,7 +728,11 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna // Download artifact step var step strings.Builder - fmt.Fprintf(&step, " - name: Download repo-memory artifact (%s)\n", memory.ID) + if memory.Wiki { + fmt.Fprintf(&step, " - name: Download wiki-memory artifact (%s)\n", memory.ID) + } else { + fmt.Fprintf(&step, " - name: Download repo-memory artifact (%s)\n", memory.ID) + } fmt.Fprintf(&step, " uses: %s\n", GetActionPin("actions/download-artifact")) step.WriteString(" continue-on-error: true\n") step.WriteString(" with:\n") @@ -749,7 +765,11 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna // Build step with github-script action var step strings.Builder - fmt.Fprintf(&step, " - name: Push repo-memory changes (%s)\n", memory.ID) + if memory.Wiki { + fmt.Fprintf(&step, " - name: Push wiki-memory changes (%s)\n", memory.ID) + } else { + fmt.Fprintf(&step, " - name: Push repo-memory changes (%s)\n", memory.ID) + } fmt.Fprintf(&step, " id: push_repo_memory_%s\n", memory.ID) step.WriteString(" if: always()\n") fmt.Fprintf(&step, " uses: %s\n", GetActionPin("actions/github-script")) diff --git a/pkg/workflow/repo_memory_test.go b/pkg/workflow/repo_memory_test.go index 205143ddffb..14c0f96b57b 100644 --- a/pkg/workflow/repo_memory_test.go +++ b/pkg/workflow/repo_memory_test.go @@ -1121,6 +1121,8 @@ func TestRepoMemoryWikiStepsGeneration(t *testing.T) { output := builder.String() assert.Contains(t, output, "TARGET_REPO: ${{ github.repository }}.wiki", "Wiki mode should append .wiki to TARGET_REPO") + assert.Contains(t, output, "- name: Clone wiki-memory branch (default)", + "Wiki mode should use wiki-memory step name") } // TestRepoMemoryWikiStepsWithTargetRepo tests wiki mode with explicit target-repo @@ -1146,6 +1148,8 @@ func TestRepoMemoryWikiStepsWithTargetRepo(t *testing.T) { output := builder.String() assert.Contains(t, output, "TARGET_REPO: myorg/myrepo.wiki", "Wiki mode should append .wiki to explicit target-repo") + assert.Contains(t, output, "- name: Clone wiki-memory branch (default)", + "Wiki mode should use wiki-memory step name") } // TestRepoMemoryWikiPromptSection tests that wiki mode injects wiki note into prompt From a12fce688e7d29b316782ee6452a198dcc4823ed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:33:44 +0000 Subject: [PATCH 5/6] Add REPO_MEMORY_ALLOWED_REPOS to wiki push step to allow .wiki repo target When wiki:true, the push script's defaultRepo is github.repository (e.g. github/gh-aw) but TARGET_REPO is github/gh-aw.wiki. Pre-populate REPO_MEMORY_ALLOWED_REPOS with the wiki repo so validateRepo() accepts it. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../developer-docs-consolidator.lock.yml | 1 + .../workflows/glossary-maintainer.lock.yml | 1 + .../workflows/technical-doc-writer.lock.yml | 1 + pkg/workflow/repo_memory.go | 5 ++ pkg/workflow/repo_memory_test.go | 52 +++++++++++++++++++ 5 files changed, 60 insertions(+) diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index 2fb0794f0dd..e076516ae0d 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -1366,6 +1366,7 @@ jobs: MEMORY_ID: default TARGET_REPO: ${{ github.repository }}.wiki BRANCH_NAME: master + REPO_MEMORY_ALLOWED_REPOS: ${{ github.repository }}.wiki MAX_FILE_SIZE: 10240 MAX_FILE_COUNT: 100 MAX_PATCH_SIZE: 10240 diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 2fc646d225c..8040d0d3c8c 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -1260,6 +1260,7 @@ jobs: MEMORY_ID: default TARGET_REPO: ${{ github.repository }}.wiki BRANCH_NAME: master + REPO_MEMORY_ALLOWED_REPOS: ${{ github.repository }}.wiki MAX_FILE_SIZE: 10240 MAX_FILE_COUNT: 100 MAX_PATCH_SIZE: 10240 diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index fafbe1ea7cd..ebf63b6081b 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -1341,6 +1341,7 @@ jobs: MEMORY_ID: default TARGET_REPO: ${{ github.repository }}.wiki BRANCH_NAME: master + REPO_MEMORY_ALLOWED_REPOS: ${{ github.repository }}.wiki MAX_FILE_SIZE: 10240 MAX_FILE_COUNT: 100 MAX_PATCH_SIZE: 10240 diff --git a/pkg/workflow/repo_memory.go b/pkg/workflow/repo_memory.go index 4b1b577f969..f57ad29235f 100644 --- a/pkg/workflow/repo_memory.go +++ b/pkg/workflow/repo_memory.go @@ -781,6 +781,11 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna fmt.Fprintf(&step, " MEMORY_ID: %s\n", memory.ID) fmt.Fprintf(&step, " TARGET_REPO: %s\n", targetRepo) fmt.Fprintf(&step, " BRANCH_NAME: %s\n", memory.BranchName) + // For wiki mode, pre-populate the allowed-repos list with the wiki repo so the push + // script accepts it (defaultRepo is always the plain github.repository, not .wiki) + if memory.Wiki { + fmt.Fprintf(&step, " REPO_MEMORY_ALLOWED_REPOS: %s\n", targetRepo) + } fmt.Fprintf(&step, " MAX_FILE_SIZE: %d\n", memory.MaxFileSize) fmt.Fprintf(&step, " MAX_FILE_COUNT: %d\n", memory.MaxFileCount) fmt.Fprintf(&step, " MAX_PATCH_SIZE: %d\n", memory.MaxPatchSize) diff --git a/pkg/workflow/repo_memory_test.go b/pkg/workflow/repo_memory_test.go index 14c0f96b57b..bd4ddebcdc7 100644 --- a/pkg/workflow/repo_memory_test.go +++ b/pkg/workflow/repo_memory_test.go @@ -1194,3 +1194,55 @@ func TestRepoMemoryNonWikiPromptSection(t *testing.T) { wikiNote := section.EnvVars["GH_AW_WIKI_NOTE"] assert.Empty(t, wikiNote, "Non-wiki mode should have empty GH_AW_WIKI_NOTE") } + +// TestRepoMemoryWikiPushAllowedRepos tests that wiki mode sets REPO_MEMORY_ALLOWED_REPOS +// in the push step so the push script accepts the .wiki repo as a valid target. +func TestRepoMemoryWikiPushAllowedRepos(t *testing.T) { + config := &RepoMemoryConfig{ + Memories: []RepoMemoryEntry{ + { + ID: "default", + BranchName: "master", + Wiki: true, + }, + }, + } + + data := &WorkflowData{ + RepoMemoryConfig: config, + } + + compiler := NewCompiler() + pushJob, err := compiler.buildPushRepoMemoryJob(data, false) + require.NoError(t, err, "Should build push job without error") + require.NotNil(t, pushJob, "Should produce a push job") + + pushJobOutput := strings.Join(pushJob.Steps, "\n") + assert.Contains(t, pushJobOutput, "REPO_MEMORY_ALLOWED_REPOS: ${{ github.repository }}.wiki", + "Wiki push step should pre-populate allowed repos with the wiki repo") +} + +// TestRepoMemoryNonWikiPushNoAllowedRepos tests that non-wiki mode does NOT set REPO_MEMORY_ALLOWED_REPOS +func TestRepoMemoryNonWikiPushNoAllowedRepos(t *testing.T) { + config := &RepoMemoryConfig{ + Memories: []RepoMemoryEntry{ + { + ID: "default", + BranchName: "memory/default", + }, + }, + } + + data := &WorkflowData{ + RepoMemoryConfig: config, + } + + compiler := NewCompiler() + pushJob, err := compiler.buildPushRepoMemoryJob(data, false) + require.NoError(t, err, "Should build push job without error") + require.NotNil(t, pushJob, "Should produce a push job") + + pushJobOutput := strings.Join(pushJob.Steps, "\n") + assert.NotContains(t, pushJobOutput, "REPO_MEMORY_ALLOWED_REPOS", + "Non-wiki push step should not set REPO_MEMORY_ALLOWED_REPOS") +} From 2caccdc6ab35f7b6dc6c70ac1441987f4614952f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:54:54 +0000 Subject: [PATCH 6/6] Report push_repo_memory job failures in conclusion job issue/comment When the push_repo_memory job itself fails (e.g. E004 permission errors), pass GH_AW_PUSH_REPO_MEMORY_RESULT to the conclusion job so the failure handler creates/updates the agent failure issue with a diagnostic message. - notify_comment.go: add GH_AW_PUSH_REPO_MEMORY_RESULT env var pointing to needs.push_repo_memory.result when repo-memory is configured - handle_agent_failure.cjs: read the result, add hasPushRepoMemoryFailure check to the skip condition, and build pushRepoMemoryFailureContext for both the new-issue and add-comment branches - agent_failure_issue.md / agent_failure_comment.md: add the {push_repo_memory_failure_context} placeholder - Tests: TestConclusionJobPushRepoMemoryResult and TestConclusionJobNoPushRepoMemoryResult Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../agent-performance-analyzer.lock.yml | 1 + .github/workflows/audit-workflows.lock.yml | 1 + .../workflows/code-scanning-fixer.lock.yml | 1 + .../workflows/copilot-agent-analysis.lock.yml | 1 + .../copilot-cli-deep-research.lock.yml | 1 + .../copilot-pr-nlp-analysis.lock.yml | 1 + .../copilot-pr-prompt-analysis.lock.yml | 1 + .../copilot-session-insights.lock.yml | 1 + .../workflows/daily-cli-performance.lock.yml | 1 + .github/workflows/daily-code-metrics.lock.yml | 1 + .../daily-copilot-token-report.lock.yml | 1 + .github/workflows/daily-news.lock.yml | 1 + .../daily-testify-uber-super-expert.lock.yml | 1 + .github/workflows/deep-report.lock.yml | 1 + .github/workflows/delight.lock.yml | 1 + .../developer-docs-consolidator.lock.yml | 1 + .../workflows/discussion-task-miner.lock.yml | 1 + .github/workflows/firewall-escape.lock.yml | 1 + .../workflows/glossary-maintainer.lock.yml | 1 + .github/workflows/pr-triage-agent.lock.yml | 1 + ...ecurity-alert-burndown.campaign.g.lock.yml | 1 + .../workflows/security-compliance.lock.yml | 1 + .../workflows/technical-doc-writer.lock.yml | 1 + .../workflow-health-manager.lock.yml | 1 + actions/setup/js/handle_agent_failure.cjs | 27 ++++++++- actions/setup/md/agent_failure_comment.md | 2 +- actions/setup/md/agent_failure_issue.md | 2 +- pkg/workflow/notify_comment.go | 7 ++- pkg/workflow/notify_comment_test.go | 59 +++++++++++++++++++ 29 files changed, 114 insertions(+), 7 deletions(-) diff --git a/.github/workflows/agent-performance-analyzer.lock.yml b/.github/workflows/agent-performance-analyzer.lock.yml index 8ab84c5815f..bb56d1d996e 100644 --- a/.github/workflows/agent-performance-analyzer.lock.yml +++ b/.github/workflows/agent-performance-analyzer.lock.yml @@ -1248,6 +1248,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index bca5aecb0b3..0c0bed59b80 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -1282,6 +1282,7 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/code-scanning-fixer.lock.yml b/.github/workflows/code-scanning-fixer.lock.yml index a0987d9253e..5a4d74f00a0 100644 --- a/.github/workflows/code-scanning-fixer.lock.yml +++ b/.github/workflows/code-scanning-fixer.lock.yml @@ -1132,6 +1132,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_campaigns: ${{ needs.push_repo_memory.outputs.validation_failed_campaigns }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_campaigns: ${{ needs.push_repo_memory.outputs.validation_error_campaigns }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml index f5c08a6c3da..04455ef0553 100644 --- a/.github/workflows/copilot-agent-analysis.lock.yml +++ b/.github/workflows/copilot-agent-analysis.lock.yml @@ -1147,6 +1147,7 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/copilot-cli-deep-research.lock.yml b/.github/workflows/copilot-cli-deep-research.lock.yml index 6872cbd2b84..5b2e709cb28 100644 --- a/.github/workflows/copilot-cli-deep-research.lock.yml +++ b/.github/workflows/copilot-cli-deep-research.lock.yml @@ -1072,6 +1072,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml index cfe6bee2517..b185eb7e594 100644 --- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml +++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml @@ -1176,6 +1176,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml index 1eef24d9601..e0bca88b121 100644 --- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml +++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml @@ -1092,6 +1092,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml index f2e3c08319f..a13ef94367c 100644 --- a/.github/workflows/copilot-session-insights.lock.yml +++ b/.github/workflows/copilot-session-insights.lock.yml @@ -1234,6 +1234,7 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index 66e88aaa3b5..74bd651d1fc 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -1270,6 +1270,7 @@ jobs: GH_AW_WORKFLOW_ID: "daily-cli-performance" GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml index dc7671fd470..a12fc1bc616 100644 --- a/.github/workflows/daily-code-metrics.lock.yml +++ b/.github/workflows/daily-code-metrics.lock.yml @@ -1211,6 +1211,7 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml index f23f3a9b652..5af92f360bf 100644 --- a/.github/workflows/daily-copilot-token-report.lock.yml +++ b/.github/workflows/daily-copilot-token-report.lock.yml @@ -1186,6 +1186,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index 7d03b192b64..e23e8049d84 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -1248,6 +1248,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/daily-testify-uber-super-expert.lock.yml b/.github/workflows/daily-testify-uber-super-expert.lock.yml index 6449bb23726..79ece547532 100644 --- a/.github/workflows/daily-testify-uber-super-expert.lock.yml +++ b/.github/workflows/daily-testify-uber-super-expert.lock.yml @@ -1111,6 +1111,7 @@ jobs: GH_AW_WORKFLOW_ID: "daily-testify-uber-super-expert" GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index 59ef2a37b39..692e48a9058 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -1287,6 +1287,7 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/delight.lock.yml b/.github/workflows/delight.lock.yml index e996407fcf8..f2cd80a7ffa 100644 --- a/.github/workflows/delight.lock.yml +++ b/.github/workflows/delight.lock.yml @@ -1164,6 +1164,7 @@ jobs: GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📊 *User experience analysis by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📊 Delight Agent starting! [{workflow_name}]({run_url}) is analyzing user-facing aspects for improvement opportunities...\",\"runSuccess\":\"✅ Analysis complete! [{workflow_name}]({run_url}) has identified targeted improvements for user experience.\",\"runFailure\":\"⚠️ Analysis interrupted! [{workflow_name}]({run_url}) {status}. Please review the logs...\"}" + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index e076516ae0d..b440bc260d2 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -1265,6 +1265,7 @@ jobs: GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index 4f7ffd06bc8..5f763ebc4b2 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -1138,6 +1138,7 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔍 *Task mining by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔍 Discussion Task Miner starting! [{workflow_name}]({run_url}) is scanning discussions for code quality improvements...\",\"runSuccess\":\"✅ Task mining complete! [{workflow_name}]({run_url}) has identified actionable code quality tasks. 📊\",\"runFailure\":\"⚠️ Task mining interrupted! [{workflow_name}]({run_url}) {status}. Please review the logs...\"}" + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/firewall-escape.lock.yml b/.github/workflows/firewall-escape.lock.yml index dcd3fad9b85..d02805f6097 100644 --- a/.github/workflows/firewall-escape.lock.yml +++ b/.github/workflows/firewall-escape.lock.yml @@ -1090,6 +1090,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 8040d0d3c8c..514296ab486 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -1159,6 +1159,7 @@ jobs: GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index aecfd85d800..c889a34d8ca 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -1153,6 +1153,7 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"runStarted\":\"🔍 Starting PR triage analysis... [{workflow_name}]({run_url}) is categorizing and prioritizing agent-created PRs\",\"runSuccess\":\"✅ PR triage complete! [{workflow_name}]({run_url}) has analyzed and categorized PRs. Check the issue for detailed report.\",\"runFailure\":\"❌ PR triage failed! [{workflow_name}]({run_url}) {status}. Some PRs may not be triaged.\"}" + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/security-alert-burndown.campaign.g.lock.yml b/.github/workflows/security-alert-burndown.campaign.g.lock.yml index 4994ea60ec7..0f9798c6fa3 100644 --- a/.github/workflows/security-alert-burndown.campaign.g.lock.yml +++ b/.github/workflows/security-alert-burndown.campaign.g.lock.yml @@ -1453,6 +1453,7 @@ jobs: GH_AW_WORKFLOW_ID: "security-alert-burndown.campaign.g" GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_campaigns: ${{ needs.push_repo_memory.outputs.validation_failed_campaigns }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_campaigns: ${{ needs.push_repo_memory.outputs.validation_error_campaigns }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/security-compliance.lock.yml b/.github/workflows/security-compliance.lock.yml index 9574b31962b..71c4b72602d 100644 --- a/.github/workflows/security-compliance.lock.yml +++ b/.github/workflows/security-compliance.lock.yml @@ -1093,6 +1093,7 @@ jobs: GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index ebf63b6081b..c04be0f39c6 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -1240,6 +1240,7 @@ jobs: GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📝 *Documentation by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"✍️ The Technical Writer begins! [{workflow_name}]({run_url}) is documenting this {event_type}...\",\"runSuccess\":\"📝 Documentation complete! [{workflow_name}]({run_url}) has written the docs. Clear as crystal! ✨\",\"runFailure\":\"✍️ Writer's block! [{workflow_name}]({run_url}) {status}. The page remains blank...\"}" + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index e83ff605892..391f5578106 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -1249,6 +1249,7 @@ jobs: GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} + GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }} GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} GH_AW_GROUP_REPORTS: "false" diff --git a/actions/setup/js/handle_agent_failure.cjs b/actions/setup/js/handle_agent_failure.cjs index 492c47b1c69..064f51c7a27 100644 --- a/actions/setup/js/handle_agent_failure.cjs +++ b/actions/setup/js/handle_agent_failure.cjs @@ -492,6 +492,7 @@ async function main() { const checkoutPRSuccess = process.env.GH_AW_CHECKOUT_PR_SUCCESS || ""; const timeoutMinutes = process.env.GH_AW_TIMEOUT_MINUTES || ""; const inferenceAccessError = process.env.GH_AW_INFERENCE_ACCESS_ERROR === "true"; + const pushRepoMemoryResult = process.env.GH_AW_PUSH_REPO_MEMORY_RESULT || ""; // Collect repo-memory validation errors from all memory configurations const repoMemoryValidationErrors = []; @@ -516,6 +517,7 @@ async function main() { core.info(`Code push failure count: ${codePushFailureCount}`); core.info(`Checkout PR success: ${checkoutPRSuccess}`); core.info(`Inference access error: ${inferenceAccessError}`); + core.info(`Push repo-memory result: ${pushRepoMemoryResult}`); // Check if the agent timed out const isTimedOut = agentConclusion === "timed_out"; @@ -529,6 +531,9 @@ async function main() { // Check if there are code-push failures (regardless of agent job status) const hasCodePushFailures = parseInt(codePushFailureCount, 10) > 0; + // Check if the push_repo_memory job itself failed (e.g. permission or config errors) + const hasPushRepoMemoryFailure = pushRepoMemoryResult === "failure"; + // Check if agent succeeded but produced no safe outputs let hasMissingSafeOutputs = false; let hasOnlyNoopOutputs = false; @@ -549,10 +554,10 @@ async function main() { } } - // Only proceed if the agent job actually failed OR timed out OR there are assignment errors OR create_discussion errors OR code-push failures OR missing safe outputs + // Only proceed if the agent job actually failed OR timed out OR there are assignment errors OR create_discussion errors OR code-push failures OR push_repo_memory failed OR missing safe outputs // BUT skip if we only have noop outputs (that's a successful no-action scenario) - if (agentConclusion !== "failure" && !isTimedOut && !hasAssignmentErrors && !hasCreateDiscussionErrors && !hasCodePushFailures && !hasMissingSafeOutputs) { - core.info(`Agent job did not fail and no assignment/discussion/code-push errors and has safe outputs (conclusion: ${agentConclusion}), skipping failure handling`); + if (agentConclusion !== "failure" && !isTimedOut && !hasAssignmentErrors && !hasCreateDiscussionErrors && !hasCodePushFailures && !hasPushRepoMemoryFailure && !hasMissingSafeOutputs) { + core.info(`Agent job did not fail and no assignment/discussion/code-push/push-repo-memory errors and has safe outputs (conclusion: ${agentConclusion}), skipping failure handling`); return; } @@ -664,6 +669,13 @@ async function main() { repoMemoryValidationContext += "\n"; } + // Build push_repo_memory job failure context + const pushRepoMemoryFailureContext = hasPushRepoMemoryFailure + ? "\n**⚠️ Repo-Memory Push Failed**: The push-repo-memory job failed to write memory back to the repository. This may indicate a permission issue, a configuration error, or a network problem. Check the [workflow run](" + + runUrl + + ") for details.\n\n" + : ""; + // Build missing_data context const missingDataContext = buildMissingDataContext(); @@ -705,6 +717,7 @@ async function main() { create_discussion_errors_context: createDiscussionErrorsContext, code_push_failure_context: codePushFailureContext, repo_memory_validation_context: repoMemoryValidationContext, + push_repo_memory_failure_context: pushRepoMemoryFailureContext, missing_data_context: missingDataContext, missing_safe_outputs_context: missingSafeOutputsContext, timeout_context: timeoutContext, @@ -784,6 +797,13 @@ async function main() { repoMemoryValidationContext += "\n"; } + // Build push_repo_memory job failure context + const pushRepoMemoryFailureContext = hasPushRepoMemoryFailure + ? "\n**⚠️ Repo-Memory Push Failed**: The push-repo-memory job failed to write memory back to the repository. This may indicate a permission issue, a configuration error, or a network problem. Check the [workflow run](" + + runUrl + + ") for details.\n\n" + : ""; + // Build missing_data context const missingDataContext = buildMissingDataContext(); @@ -826,6 +846,7 @@ async function main() { create_discussion_errors_context: createDiscussionErrorsContext, code_push_failure_context: codePushFailureContext, repo_memory_validation_context: repoMemoryValidationContext, + push_repo_memory_failure_context: pushRepoMemoryFailureContext, missing_data_context: missingDataContext, missing_safe_outputs_context: missingSafeOutputsContext, timeout_context: timeoutContext, diff --git a/actions/setup/md/agent_failure_comment.md b/actions/setup/md/agent_failure_comment.md index e7d992bd46d..1f491da4d79 100644 --- a/actions/setup/md/agent_failure_comment.md +++ b/actions/setup/md/agent_failure_comment.md @@ -1,3 +1,3 @@ Agent job [{run_id}]({run_url}) failed. -{secret_verification_context}{inference_access_error_context}{assignment_errors_context}{create_discussion_errors_context}{code_push_failure_context}{repo_memory_validation_context}{missing_data_context}{missing_safe_outputs_context}{timeout_context}{fork_context} +{secret_verification_context}{inference_access_error_context}{assignment_errors_context}{create_discussion_errors_context}{code_push_failure_context}{repo_memory_validation_context}{push_repo_memory_failure_context}{missing_data_context}{missing_safe_outputs_context}{timeout_context}{fork_context} diff --git a/actions/setup/md/agent_failure_issue.md b/actions/setup/md/agent_failure_issue.md index 481c79f8450..37460db6461 100644 --- a/actions/setup/md/agent_failure_issue.md +++ b/actions/setup/md/agent_failure_issue.md @@ -4,7 +4,7 @@ **Branch:** {branch} **Run:** {run_url}{pull_request_info} -{secret_verification_context}{inference_access_error_context}{assignment_errors_context}{create_discussion_errors_context}{code_push_failure_context}{repo_memory_validation_context}{missing_data_context}{missing_safe_outputs_context}{timeout_context}{fork_context} +{secret_verification_context}{inference_access_error_context}{assignment_errors_context}{create_discussion_errors_context}{code_push_failure_context}{repo_memory_validation_context}{push_repo_memory_failure_context}{missing_data_context}{missing_safe_outputs_context}{timeout_context}{fork_context} ### Action Required diff --git a/pkg/workflow/notify_comment.go b/pkg/workflow/notify_comment.go index 41730282147..b0847e26227 100644 --- a/pkg/workflow/notify_comment.go +++ b/pkg/workflow/notify_comment.go @@ -177,9 +177,12 @@ func (c *Compiler) buildConclusionJob(data *WorkflowData, mainJobName string, sa } } - // Pass repo-memory validation failure outputs if repo-memory is configured - // This allows the agent failure handler to report validation issues + // Pass repo-memory failure outputs if repo-memory is configured + // This allows the agent failure handler to report both job-level failures and validation issues if data.RepoMemoryConfig != nil && len(data.RepoMemoryConfig.Memories) > 0 { + // Pass the overall push_repo_memory job result so the failure handler + // can report when the push job itself fails (e.g. permission or configuration errors) + agentFailureEnvVars = append(agentFailureEnvVars, " GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }}\n") for _, memory := range data.RepoMemoryConfig.Memories { // Add validation status for each memory agentFailureEnvVars = append(agentFailureEnvVars, fmt.Sprintf(" GH_AW_REPO_MEMORY_VALIDATION_FAILED_%s: ${{ needs.push_repo_memory.outputs.validation_failed_%s }}\n", memory.ID, memory.ID)) diff --git a/pkg/workflow/notify_comment_test.go b/pkg/workflow/notify_comment_test.go index e6fda94112d..aac7f055906 100644 --- a/pkg/workflow/notify_comment_test.go +++ b/pkg/workflow/notify_comment_test.go @@ -842,3 +842,62 @@ func TestConclusionJobConcurrencyGroup(t *testing.T) { }) } } + +// TestConclusionJobPushRepoMemoryResult verifies that when repo-memory is configured, +// GH_AW_PUSH_REPO_MEMORY_RESULT is passed to the conclusion job so the failure handler +// can report push_repo_memory job-level failures. +func TestConclusionJobPushRepoMemoryResult(t *testing.T) { + compiler := NewCompiler() + workflowData := &WorkflowData{ + Name: "Test Workflow", + SafeOutputs: &SafeOutputsConfig{ + MissingTool: &MissingToolConfig{}, + }, + RepoMemoryConfig: &RepoMemoryConfig{ + Memories: []RepoMemoryEntry{ + {ID: "default", BranchName: "memory/default"}, + }, + }, + } + + job, err := compiler.buildConclusionJob(workflowData, string(constants.AgentJobName), []string{}) + if err != nil { + t.Fatalf("Failed to build conclusion job: %v", err) + } + if job == nil { + t.Fatal("Expected conclusion job to be created") + } + + allSteps := strings.Join(job.Steps, "\n") + if !strings.Contains(allSteps, "GH_AW_PUSH_REPO_MEMORY_RESULT") { + t.Error("Expected conclusion job to include GH_AW_PUSH_REPO_MEMORY_RESULT env var for push job failure reporting") + } + if !strings.Contains(allSteps, "${{ needs.push_repo_memory.result }}") { + t.Error("Expected GH_AW_PUSH_REPO_MEMORY_RESULT to reference needs.push_repo_memory.result") + } +} + +// TestConclusionJobNoPushRepoMemoryResult verifies that when repo-memory is NOT configured, +// GH_AW_PUSH_REPO_MEMORY_RESULT is not added to the conclusion job (no unnecessary env vars). +func TestConclusionJobNoPushRepoMemoryResult(t *testing.T) { + compiler := NewCompiler() + workflowData := &WorkflowData{ + Name: "Test Workflow", + SafeOutputs: &SafeOutputsConfig{ + MissingTool: &MissingToolConfig{}, + }, + } + + job, err := compiler.buildConclusionJob(workflowData, string(constants.AgentJobName), []string{}) + if err != nil { + t.Fatalf("Failed to build conclusion job: %v", err) + } + if job == nil { + t.Fatal("Expected conclusion job to be created") + } + + allSteps := strings.Join(job.Steps, "\n") + if strings.Contains(allSteps, "GH_AW_PUSH_REPO_MEMORY_RESULT") { + t.Error("Expected conclusion job to NOT include GH_AW_PUSH_REPO_MEMORY_RESULT when repo-memory is not configured") + } +}