diff --git a/.changeset/patch-wiki-note-empty-placeholder.md b/.changeset/patch-wiki-note-empty-placeholder.md new file mode 100644 index 00000000000..4ac06a3e70a --- /dev/null +++ b/.changeset/patch-wiki-note-empty-placeholder.md @@ -0,0 +1,5 @@ +--- +"gh-aw": patch +--- + +Fix `__GH_AW_WIKI_NOTE__` placeholder not being substituted when repo-memory is configured without wiki mode. Previously, when `wiki: false`, the variable used a static empty string that could be missing from the substitution step in older compiled workflows. Now it uses `${{ '' }}` (a GitHub expression evaluating to empty string), ensuring expression interpolation always produces an empty value for the placeholder. diff --git a/.github/workflows/agent-performance-analyzer.lock.yml b/.github/workflows/agent-performance-analyzer.lock.yml index 99dcb1879cc..c7730a5af74 100644 --- a/.github/workflows/agent-performance-analyzer.lock.yml +++ b/.github/workflows/agent-performance-analyzer.lock.yml @@ -119,6 +119,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index d68250fb2c0..37bff4b5bae 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -125,6 +125,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml index ccd2ab6ad5e..2fc3387e813 100644 --- a/.github/workflows/copilot-agent-analysis.lock.yml +++ b/.github/workflows/copilot-agent-analysis.lock.yml @@ -126,6 +126,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/copilot-cli-deep-research.lock.yml b/.github/workflows/copilot-cli-deep-research.lock.yml index 207fc7c5078..05022d38abf 100644 --- a/.github/workflows/copilot-cli-deep-research.lock.yml +++ b/.github/workflows/copilot-cli-deep-research.lock.yml @@ -117,6 +117,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml index f691c591572..12f8c077c89 100644 --- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml +++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml @@ -120,6 +120,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml index ea39aa4ca58..3dd898d511e 100644 --- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml +++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml @@ -120,6 +120,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml index 64f7023c616..4632188c8a8 100644 --- a/.github/workflows/copilot-session-insights.lock.yml +++ b/.github/workflows/copilot-session-insights.lock.yml @@ -129,6 +129,7 @@ jobs: GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/daily-architecture-diagram.lock.yml b/.github/workflows/daily-architecture-diagram.lock.yml index 323a0d0af7b..28dd33528c9 100644 --- a/.github/workflows/daily-architecture-diagram.lock.yml +++ b/.github/workflows/daily-architecture-diagram.lock.yml @@ -345,7 +345,7 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"create_issue":{"expires":168,"max":1},"create_pull_request":{"expires":7,"max":1,"title_prefix":"[architecture] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}} + {"create_issue":{"expires":168,"max":1},"create_pull_request":{"expires":168,"max":1,"title_prefix":"[architecture] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}} GH_AW_SAFE_OUTPUTS_CONFIG_EOF cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF' [ @@ -1289,7 +1289,7 @@ jobs: GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"expires\":168,\"labels\":[\"architecture\",\"diagram\"],\"max\":1,\"title_prefix\":\"🏗️ Architecture Diagram:\"},\"create_pull_request\":{\"expires\":7,\"labels\":[\"architecture\",\"diagram\",\"documentation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[architecture] \"},\"missing_data\":{},\"missing_tool\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"expires\":168,\"labels\":[\"architecture\",\"diagram\"],\"max\":1,\"title_prefix\":\"🏗️ Architecture Diagram:\"},\"create_pull_request\":{\"expires\":168,\"labels\":[\"architecture\",\"diagram\",\"documentation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[architecture] \"},\"missing_data\":{},\"missing_tool\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index 7ad681c59f4..2e33b0b7bbd 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -119,6 +119,7 @@ jobs: GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml index e2a1ede659f..abbf139432b 100644 --- a/.github/workflows/daily-code-metrics.lock.yml +++ b/.github/workflows/daily-code-metrics.lock.yml @@ -125,6 +125,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml index 35fb40eeeb8..6978dda1950 100644 --- a/.github/workflows/daily-copilot-token-report.lock.yml +++ b/.github/workflows/daily-copilot-token-report.lock.yml @@ -118,6 +118,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index b7e6051c166..072e9588495 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -120,6 +120,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/daily-testify-uber-super-expert.lock.yml b/.github/workflows/daily-testify-uber-super-expert.lock.yml index b7b9e96efb5..443f7d48f55 100644 --- a/.github/workflows/daily-testify-uber-super-expert.lock.yml +++ b/.github/workflows/daily-testify-uber-super-expert.lock.yml @@ -122,6 +122,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index fa027419056..a6a21f9b4ee 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -125,6 +125,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/delight.lock.yml b/.github/workflows/delight.lock.yml index 17858ede622..7b6b78641a4 100644 --- a/.github/workflows/delight.lock.yml +++ b/.github/workflows/delight.lock.yml @@ -118,6 +118,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index f2667109b9c..ae2bac6b919 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -121,6 +121,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/firewall-escape.lock.yml b/.github/workflows/firewall-escape.lock.yml index 5994d982711..2ad28228afb 100644 --- a/.github/workflows/firewall-escape.lock.yml +++ b/.github/workflows/firewall-escape.lock.yml @@ -135,6 +135,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/metrics-collector.lock.yml b/.github/workflows/metrics-collector.lock.yml index 6531942a392..b6b8d3ea189 100644 --- a/.github/workflows/metrics-collector.lock.yml +++ b/.github/workflows/metrics-collector.lock.yml @@ -120,6 +120,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index 6ff4c6dd8ec..022ace78abe 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -121,6 +121,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/security-compliance.lock.yml b/.github/workflows/security-compliance.lock.yml index 8adb1d70081..dbcf2499a0f 100644 --- a/.github/workflows/security-compliance.lock.yml +++ b/.github/workflows/security-compliance.lock.yml @@ -143,6 +143,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index b20d38039a9..3bc99120f3d 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -125,6 +125,7 @@ jobs: GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_WIKI_NOTE: ${{ '' }} run: | bash /opt/gh-aw/actions/create_prompt_first.sh { diff --git a/pkg/workflow/repo_memory_prompt.go b/pkg/workflow/repo_memory_prompt.go index c3c3b5056d0..55b0c2730a7 100644 --- a/pkg/workflow/repo_memory_prompt.go +++ b/pkg/workflow/repo_memory_prompt.go @@ -10,6 +10,11 @@ import ( var repoMemoryPromptLog = logger.New("workflow:repo_memory_prompt") +// ghaEmptyStringExpr is the GitHub Actions expression that evaluates to an empty string. +// Using this as an env var value forces the prompt-creation step to include the variable, +// ensuring the substitution step always has a value to substitute. +const ghaEmptyStringExpr = "${{ '' }}" + // buildRepoMemoryPromptSection builds a PromptSection for repo memory instructions. // Returns a PromptSection that references a template file with substitutions, or nil if no memory is configured. func buildRepoMemoryPromptSection(config *RepoMemoryConfig) *PromptSection { @@ -58,8 +63,13 @@ func buildRepoMemoryPromptSection(config *RepoMemoryConfig) *PromptSection { constraintsText = constraints.String() } - // Build wiki note text (non-empty only when wiki mode is enabled) - wikiNoteText := "" + // Build wiki note text. + // When wiki mode is enabled, include a note about the GitHub Wiki. + // When wiki mode is disabled, use a GitHub expression that evaluates to the empty string + // (${{ '' }}). This ensures that, in newly compiled workflows (or workflows with regenerated + // lock files), expression interpolation always substitutes __GH_AW_WIKI_NOTE__ with a value + // by forcing the prompt-creation step to include GH_AW_WIKI_NOTE, even when the note is empty. + wikiNoteText := ghaEmptyStringExpr if memory.Wiki { repoMemoryPromptLog.Print("Wiki mode enabled for repo memory") wikiNoteText = "\n\n> **GitHub Wiki**: This memory is backed by the GitHub Wiki for this repository. " + diff --git a/pkg/workflow/repo_memory_test.go b/pkg/workflow/repo_memory_test.go index dddebc6291f..85658f85515 100644 --- a/pkg/workflow/repo_memory_test.go +++ b/pkg/workflow/repo_memory_test.go @@ -1118,7 +1118,7 @@ func TestRepoMemoryWikiPromptSection(t *testing.T) { assert.Contains(t, wikiNote, "Markdown", "Wiki note should mention Markdown syntax") } -// TestRepoMemoryNonWikiPromptSection tests that non-wiki mode has empty wiki note +// TestRepoMemoryNonWikiPromptSection tests that non-wiki mode uses empty string expression for wiki note func TestRepoMemoryNonWikiPromptSection(t *testing.T) { config := &RepoMemoryConfig{ Memories: []RepoMemoryEntry{ @@ -1135,7 +1135,9 @@ func TestRepoMemoryNonWikiPromptSection(t *testing.T) { 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") + // Non-wiki mode should use a GitHub expression that evaluates to empty string. + // This ensures __GH_AW_WIKI_NOTE__ is always substituted via expression interpolation. + assert.Equal(t, ghaEmptyStringExpr, wikiNote, "Non-wiki mode should use empty string expression for GH_AW_WIKI_NOTE") } // TestRepoMemoryWikiPushAllowedRepos tests that wiki mode sets REPO_MEMORY_ALLOWED_REPOS