diff --git a/.github/agents/performance-celebration-article.agent.md b/.github/agents/performance-celebration-article.agent.md index afc2a7bdc59..7a2de7a9c0e 100644 --- a/.github/agents/performance-celebration-article.agent.md +++ b/.github/agents/performance-celebration-article.agent.md @@ -1,5 +1,5 @@ --- -name: Performance celebration article +name: performance-celebration-article description: Measure and collect .NET performance evidence, then present and celebrate verified wins in threading, scaling, CPU, wall time, throughput, allocation, GC, or memory for F# and .NET developers. --- diff --git a/.github/workflows/check_release_notes.yml b/.github/workflows/check_release_notes.yml index 9c1491eaa7d..77dc8ffaed8 100644 --- a/.github/workflows/check_release_notes.yml +++ b/.github/workflows/check_release_notes.yml @@ -19,6 +19,7 @@ jobs: pull-requests: write env: GH_TOKEN: ${{ github.token }} + LOCALIZATION_BOT: dotnet-oneloc-localization[bot] PR_AUTHOR: ${{ github.event.pull_request.user.login }} PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} @@ -281,7 +282,7 @@ jobs: exit 0 fi - OPT_OUT_RELEASE_NOTES=$(jq -r 'any(.labels[]; .name == "NO_RELEASE_NOTES")' <<< "$_current_pr") + OPT_OUT_RELEASE_NOTES=$(jq -r --arg bot "$LOCALIZATION_BOT" 'any(.labels[]; .name == "NO_RELEASE_NOTES") or .user.login == $bot' <<< "$_current_pr") echo "Opt out of release notes: $OPT_OUT_RELEASE_NOTES" RELEASE_NOTES_REQUIRED=false if [[ $RELEASE_NOTES_NOT_FOUND != "" && "$OPT_OUT_RELEASE_NOTES" != true ]]; then @@ -302,7 +303,7 @@ jobs: echo "" echo "## :white_check_mark: Release-note check exempted" echo "" - echo "The NO_RELEASE_NOTES label exempts this pull request." + echo "The NO_RELEASE_NOTES label or localization-bot authorship exempts this pull request." else echo "${RELEASE_NOTES_MESSAGE}" fi @@ -352,7 +353,8 @@ jobs: ...context.repo, pull_number: context.issue.number }); - const exempt = current.labels.some(label => label.name === 'NO_RELEASE_NOTES'); + const exempt = current.labels.some(label => label.name === 'NO_RELEASE_NOTES') || + current.user?.login === process.env.LOCALIZATION_BOT; if (current.head.sha !== process.env.PR_HEAD_SHA || String(exempt) !== process.env.RELEASE_NOTES_EXEMPT) { core.info('Skipping outdated release-note comment.'); diff --git a/.github/workflows/regression-pr-shepherd.lock.yml b/.github/workflows/regression-pr-shepherd.lock.yml index 603f0610c7f..793386787d7 100644 --- a/.github/workflows/regression-pr-shepherd.lock.yml +++ b/.github/workflows/regression-pr-shepherd.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5c039e596d72e8b5b4c975972483e5b87a47bd623c4878d894338a0ea49f05ed","compiler_version":"v0.76.1","strict":true,"agent_id":"copilot","agent_model":"${{ (github.job == 'detection' \u0026\u0026 vars.GH_AW_MODEL_DETECTION_COPILOT) || vars.GH_AW_MODEL_AGENT_COPILOT || 'gpt-5.6-sol' }}"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"27d35c914d940d0986de593c339c094c4011deb5a6a3421134c7162b0b55c0b7","compiler_version":"v0.76.1","strict":true,"agent_id":"copilot","agent_model":"${{ (github.job == 'detection' \u0026\u0026 vars.GH_AW_MODEL_DETECTION_COPILOT) || vars.GH_AW_MODEL_AGENT_COPILOT || 'gpt-5.6-sol' }}"} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.19"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14","pinned_image":"node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14"}]} # ___ _ _ # / _ \ | | (_) @@ -197,24 +197,24 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_47989350a3608f55_EOF' + cat << 'GH_AW_PROMPT_8ac6863d4a6aefa0_EOF' - GH_AW_PROMPT_47989350a3608f55_EOF + GH_AW_PROMPT_8ac6863d4a6aefa0_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/repo_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_47989350a3608f55_EOF' + cat << 'GH_AW_PROMPT_8ac6863d4a6aefa0_EOF' Tools: add_comment(max:5), remove_labels(max:5), push_to_pull_request_branch(max:10), missing_tool, missing_data, noop - GH_AW_PROMPT_47989350a3608f55_EOF + GH_AW_PROMPT_8ac6863d4a6aefa0_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md" - cat << 'GH_AW_PROMPT_47989350a3608f55_EOF' + cat << 'GH_AW_PROMPT_8ac6863d4a6aefa0_EOF' - GH_AW_PROMPT_47989350a3608f55_EOF + GH_AW_PROMPT_8ac6863d4a6aefa0_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_47989350a3608f55_EOF' + cat << 'GH_AW_PROMPT_8ac6863d4a6aefa0_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -243,13 +243,13 @@ jobs: {{/if}} - GH_AW_PROMPT_47989350a3608f55_EOF + GH_AW_PROMPT_8ac6863d4a6aefa0_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_47989350a3608f55_EOF' + cat << 'GH_AW_PROMPT_8ac6863d4a6aefa0_EOF' {{#runtime-import .github/workflows/shared/model-defaults.md}} {{#runtime-import .github/workflows/regression-pr-shepherd.md}} - GH_AW_PROMPT_47989350a3608f55_EOF + GH_AW_PROMPT_8ac6863d4a6aefa0_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -276,7 +276,7 @@ jobs: GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools' GH_AW_MEMORY_BRANCH_NAME: 'memory/regression-pr-shepherd' - GH_AW_MEMORY_CONSTRAINTS: "\n\n**Constraints:**\n- **Max File Size**: 102400 bytes (0.10 MB) per file\n- **Max File Count**: 100 files per commit\n- **Max Patch Size**: 10240 bytes (10 KB) total per push (max: 1024 KB)\n" + GH_AW_MEMORY_CONSTRAINTS: "\n\n**Constraints:**\n- **Max File Size**: 102400 bytes (0.10 MB) per file\n- **Max File Count**: 200 files per commit\n- **Max Patch Size**: 10240 bytes (10 KB) total per push (max: 1024 KB)\n" GH_AW_MEMORY_DESCRIPTION: '' GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/' GH_AW_MEMORY_TARGET_REPO: ' of the current repository' @@ -475,9 +475,9 @@ jobs: mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_7c3c77a312e9daf5_EOF' - {"add_comment":{"hide_older_comments":true,"max":5,"target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"push_to_pull_request_branch":{"allowed_files":["tests/**","vsintegration/tests/**"],"if_no_changes":"warn","max":10,"max_patch_size":1024,"protect_top_level_dot_folders":true,"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","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"fallback-to-issue","required_labels":["AI-Issue-Regression-PR"],"target":"*","title_prefix":"Add regression test: "},"remove_labels":{"allowed":["AI-thinks-issue-fixed"],"max":5,"target":"*"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_7c3c77a312e9daf5_EOF + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_83eba6452b99f2bd_EOF' + {"add_comment":{"hide_older_comments":true,"max":5,"target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":200,"max_file_size":102400,"max_patch_size":10240}]},"push_to_pull_request_branch":{"allowed_files":["tests/**","vsintegration/tests/**"],"if_no_changes":"warn","max":10,"max_patch_size":1024,"protect_top_level_dot_folders":true,"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","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"fallback-to-issue","required_labels":["AI-Issue-Regression-PR"],"target":"*","title_prefix":"Add regression test: "},"remove_labels":{"allowed":["AI-thinks-issue-fixed"],"max":5,"target":"*"},"report_incomplete":{}} + GH_AW_SAFE_OUTPUTS_CONFIG_83eba6452b99f2bd_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -710,7 +710,7 @@ jobs: mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_0cd886509238b4f8_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_295b4a432f80a799_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -754,7 +754,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_0cd886509238b4f8_EOF + GH_AW_MCP_CONFIG_295b4a432f80a799_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -1435,7 +1435,7 @@ jobs: TARGET_REPO: ${{ github.repository }} BRANCH_NAME: memory/regression-pr-shepherd MAX_FILE_SIZE: 102400 - MAX_FILE_COUNT: 100 + MAX_FILE_COUNT: 200 MAX_PATCH_SIZE: 10240 ALLOWED_EXTENSIONS: '[]' with: diff --git a/.github/workflows/regression-pr-shepherd.md b/.github/workflows/regression-pr-shepherd.md index 8f8f1b090fa..93cbcffe7d1 100644 --- a/.github/workflows/regression-pr-shepherd.md +++ b/.github/workflows/regression-pr-shepherd.md @@ -52,7 +52,8 @@ tools: toolsets: [all] min-integrity: none bash: true - repo-memory: true + repo-memory: + max-file-count: 200 --- # Regression PR Shepherd @@ -163,7 +164,7 @@ Before pushing any fix: ### Step 4 — Update memory -Track which PRs you've processed and the last review comment timestamp you addressed, so the next run only processes new feedback. +Track which PRs you've processed and the last review comment timestamp you addressed, so the next run only processes new feedback. Keep all of it in a single `state.json`; do not create per-run memory files, because a push with too many files fails the run. ## Guidelines