diff --git a/src/msbuild/.github/aw/actions-lock.json b/src/msbuild/.github/aw/actions-lock.json index dfe067e3a6b1..7adf14e7c8ad 100644 --- a/src/msbuild/.github/aw/actions-lock.json +++ b/src/msbuild/.github/aw/actions-lock.json @@ -5,15 +5,15 @@ "version": "v8", "sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd" }, - "github/gh-aw-actions/setup@v0.59.0": { - "repo": "github/gh-aw-actions/setup", - "version": "v0.59.0", - "sha": "066087f607f52664010289ddd52198f33044c38a" + "actions/github-script@v9": { + "repo": "actions/github-script", + "version": "v9", + "sha": "3a2844b7e9c422d3c10d287c895573f7108da1b3" }, - "github/gh-aw-actions/setup@v0.67.1": { + "github/gh-aw-actions/setup@v0.68.1": { "repo": "github/gh-aw-actions/setup", - "version": "v0.67.1", - "sha": "80471a493be8c528dd27daf73cd644242a7965e0" + "version": "v0.68.1", + "sha": "2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc" } } } diff --git a/src/msbuild/.github/workflows/close-stale-prs.agent.lock.yml b/src/msbuild/.github/workflows/close-stale-prs.agent.lock.yml index d12360f1fdf0..171a31cec208 100644 --- a/src/msbuild/.github/workflows/close-stale-prs.agent.lock.yml +++ b/src/msbuild/.github/workflows/close-stale-prs.agent.lock.yml @@ -1,4 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"00fdca5431be3e873606981ab5b9593d2f83f571aef0d74307942cb5a4f722c5","compiler_version":"v0.67.1","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"00fdca5431be3e873606981ab5b9593d2f83f571aef0d74307942cb5a4f722c5","compiler_version":"v0.68.1","strict":true,"agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","COPILOT_GITHUB_TOKEN_1","COPILOT_GITHUB_TOKEN_2","COPILOT_GITHUB_TOKEN_3","COPILOT_GITHUB_TOKEN_4","COPILOT_GITHUB_TOKEN_5","COPILOT_GITHUB_TOKEN_6","COPILOT_GITHUB_TOKEN_7","COPILOT_GITHUB_TOKEN_8","COPILOT_GITHUB_TOKEN_9","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"},{"repo":"actions/upload-artifact","sha":"bbbca2ddaa5d8feaa63e36b76fdaad77386f024f","version":"v7"},{"repo":"github/gh-aw-actions/setup","sha":"2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc","version":"v0.68.1"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -13,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.67.1). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.68.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -41,9 +42,9 @@ # Custom actions used: # - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 -# - actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 +# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 # - actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 -# - github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 +# - github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 name: "Close Stale Pull Requests" "on": @@ -93,6 +94,7 @@ jobs: if: needs.pre_activation.outputs.activated == 'true' runs-on: ubuntu-slim permissions: + actions: read contents: read outputs: comment_id: "" @@ -101,10 +103,11 @@ jobs: model: ${{ steps.generate_aw_info.outputs.model }} secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -115,29 +118,29 @@ jobs: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} - GH_AW_INFO_VERSION: "latest" - GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.67.1" + GH_AW_INFO_VERSION: "1.0.21" + GH_AW_INFO_AGENT_VERSION: "1.0.21" + GH_AW_INFO_CLI_VERSION: "v0.68.1" GH_AW_INFO_WORKFLOW_NAME: "Close Stale Pull Requests" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.13" + GH_AW_INFO_AWF_VERSION: "v0.25.18" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "true" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Validate COPILOT_GITHUB_TOKEN secret id: validate-secret - run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default env: COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} - name: Checkout .github and .agents folders @@ -150,24 +153,25 @@ jobs: sparse-checkout-cone-mode: true fetch-depth: 1 - name: Check workflow lock file - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + id: check-lock-file + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_WORKFLOW_FILE: "close-stale-prs.agent.lock.yml" GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); await main(); - name: Check compile-agentic version - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: - GH_AW_COMPILED_VERSION: "v0.67.1" + GH_AW_COMPILED_VERSION: "v0.68.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); await main(); - name: Create prompt with built-in context @@ -184,7 +188,7 @@ jobs: GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} # poutine:ignore untrusted_checkout_exec run: | - bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh + bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { cat << 'GH_AW_PROMPT_6d0bdab256507ee4_EOF' @@ -233,17 +237,17 @@ jobs: GH_AW_PROMPT_6d0bdab256507ee4_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); await main(); - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -258,7 +262,7 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); @@ -281,12 +285,12 @@ jobs: env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt # poutine:ignore untrusted_checkout_exec - run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt # poutine:ignore untrusted_checkout_exec - run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" - name: Upload activation artifact if: success() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 @@ -325,7 +329,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -341,9 +345,9 @@ jobs: with: persist-credentials: false - name: Create gh-aw temp directory - run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" - name: Configure gh CLI for GitHub Enterprise - run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh" env: GH_TOKEN: ${{ github.token }} - name: Configure Git credentials @@ -363,25 +367,25 @@ jobs: id: checkout-pr if: | github.event.pull_request || github.event.issue.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); await main(); - name: Install GitHub Copilot CLI - run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 env: GH_HOST: github.com - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.18 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} @@ -390,141 +394,145 @@ jobs: const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 ghcr.io/github/gh-aw-mcpg:v0.2.14 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.18 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.18 ghcr.io/github/gh-aw-firewall/squid:0.25.18 ghcr.io/github/gh-aw-mcpg:v0.2.17 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine - name: Write Safe Outputs Config run: | - mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs + 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_d9c9e1b057f5464d_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_d9c9e1b057f5464d_EOF' {"add_comment":{"max":30},"close_pull_request":{"max":25},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} GH_AW_SAFE_OUTPUTS_CONFIG_d9c9e1b057f5464d_EOF - name: Write Safe Outputs Tools - run: | - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_5dc96d6e4c95046c_EOF' - { - "description_suffixes": { - "add_comment": " CONSTRAINTS: Maximum 30 comment(s) can be added.", - "close_pull_request": " CONSTRAINTS: Maximum 25 pull request(s) can be closed." - }, - "repo_params": {}, - "dynamic_tools": [] - } - GH_AW_SAFE_OUTPUTS_TOOLS_META_5dc96d6e4c95046c_EOF - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_3ce7dc31f4b7e3f6_EOF' - { - "add_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "item_number": { - "issueOrPRNumber": true - }, - "repo": { - "type": "string", - "maxLength": 256 + env: + GH_AW_TOOLS_META_JSON: | + { + "description_suffixes": { + "add_comment": " CONSTRAINTS: Maximum 30 comment(s) can be added.", + "close_pull_request": " CONSTRAINTS: Maximum 25 pull request(s) can be closed." + }, + "repo_params": {}, + "dynamic_tools": [] + } + GH_AW_VALIDATION_JSON: | + { + "add_comment": { + "defaultMax": 1, + "fields": { + "body": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "item_number": { + "issueOrPRNumber": true + }, + "repo": { + "type": "string", + "maxLength": 256 + } } - } - }, - "close_pull_request": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "pull_request_number": { - "optionalPositiveInteger": true - }, - "repo": { - "type": "string", - "maxLength": 256 + }, + "close_pull_request": { + "defaultMax": 1, + "fields": { + "body": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "pull_request_number": { + "optionalPositiveInteger": true + }, + "repo": { + "type": "string", + "maxLength": 256 + } } - } - }, - "missing_data": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "context": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "data_type": { - "type": "string", - "sanitize": true, - "maxLength": 128 - }, - "reason": { - "type": "string", - "sanitize": true, - "maxLength": 256 + }, + "missing_data": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "context": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "data_type": { + "type": "string", + "sanitize": true, + "maxLength": 128 + }, + "reason": { + "type": "string", + "sanitize": true, + "maxLength": 256 + } } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 + }, + "missing_tool": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 512 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "tool": { + "type": "string", + "sanitize": true, + "maxLength": 128 + } } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 + }, + "noop": { + "defaultMax": 1, + "fields": { + "message": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + } } - } - }, - "report_incomplete": { - "defaultMax": 5, - "fields": { - "details": { - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 1024 + }, + "report_incomplete": { + "defaultMax": 5, + "fields": { + "details": { + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 1024 + } } } } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_3ce7dc31f4b7e3f6_EOF - node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + await main(); - name: Generate Safe Outputs MCP Server Config id: safe-outputs-config run: | @@ -563,7 +571,7 @@ jobs: export GH_AW_SAFE_OUTPUTS_CONFIG_PATH export GH_AW_MCP_LOG_DIR - bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh + bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh" - name: Start MCP Gateway id: start-mcp-gateway @@ -590,10 +598,10 @@ jobs: export DEBUG="*" export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.14' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.17' mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_f78a1e23f001bf50_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh + cat << GH_AW_MCP_CONFIG_f78a1e23f001bf50_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh" { "mcpServers": { "github": { @@ -642,7 +650,7 @@ jobs: path: /tmp/gh-aw - name: Clean git credentials continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh" - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): @@ -650,9 +658,10 @@ jobs: run: | set -o pipefail touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 - sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-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,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-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,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.18 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} @@ -661,7 +670,7 @@ jobs: GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.67.1 + GH_AW_VERSION: v0.68.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -679,7 +688,7 @@ jobs: id: detect-inference-error if: always() continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh" - name: Configure Git credentials env: REPO_NAME: ${{ github.repository }} @@ -696,7 +705,7 @@ jobs: - name: Copy Copilot session state files to logs if: always() continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh" - name: Stop MCP Gateway if: always() continue-on-error: true @@ -705,14 +714,14 @@ jobs: MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} run: | - bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" + bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID" - name: Redact secrets in logs if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); await main(); env: @@ -732,7 +741,7 @@ jobs: SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Append agent step summary if: always() - run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh" - name: Copy Safe Outputs if: always() env: @@ -743,7 +752,7 @@ jobs: - name: Ingest agent output id: collect_output if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} 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,www.googleapis.com" @@ -752,28 +761,28 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); await main(); - name: Parse agent logs for step summary if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); await main(); - name: Parse MCP Gateway logs for step summary if: always() id: parse-mcp-gateway - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); await main(); - name: Print firewall logs @@ -794,11 +803,11 @@ jobs: - name: Parse token usage for step summary if: always() continue-on-error: true - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); await main(); - name: Write agent output placeholder if missing @@ -844,7 +853,9 @@ jobs: - agent - detection - safe_outputs - if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true') + if: > + always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || + needs.activation.outputs.stale_lock_file_failed == 'true') runs-on: ubuntu-slim permissions: contents: read @@ -862,7 +873,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -883,7 +894,7 @@ jobs: echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - name: Process No-Op Messages id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_NOOP_MAX: "1" @@ -895,12 +906,12 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); await main(); - - name: Record Missing Tool + - name: Record missing tool id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_MISSING_TOOL_CREATE_ISSUE: "true" @@ -909,12 +920,12 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); await main(); - - name: Record Incomplete + - name: Record incomplete id: report_incomplete - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true" @@ -923,13 +934,13 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); await main(); - - name: Handle Agent Failure + - name: Handle agent failure id: handle_agent_failure if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests" @@ -941,6 +952,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_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }} + GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }} GH_AW_GROUP_REPORTS: "false" GH_AW_FAILURE_REPORT_AS_ISSUE: "true" GH_AW_TIMEOUT_MINUTES: "20" @@ -948,7 +960,7 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); await main(); @@ -967,7 +979,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -993,7 +1005,7 @@ jobs: persist-credentials: false # --- Threat Detection --- - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.18 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.18 ghcr.io/github/gh-aw-firewall/squid:0.25.18 - name: Check if detection needed id: detection_guard if: always() @@ -1030,7 +1042,7 @@ jobs: ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: WORKFLOW_NAME: "Close Stale Pull Requests" WORKFLOW_DESCRIPTION: "Automatically warn about and close pull requests that have been open for more than 180 days with no recent activity." @@ -1038,7 +1050,7 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); await main(); - name: Ensure threat-detection directory and log @@ -1047,11 +1059,11 @@ jobs: mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - name: Install GitHub Copilot CLI - run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 env: GH_HOST: github.com - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.18 - name: Execute GitHub Copilot CLI if: always() && steps.detection_guard.outputs.run_detection == 'true' id: detection_agentic_execution @@ -1060,16 +1072,17 @@ jobs: run: | set -o pipefail touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) # shellcheck disable=SC1003 - sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.18 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.67.1 + GH_AW_VERSION: v0.68.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -1092,13 +1105,13 @@ jobs: - name: Parse and conclude threat detection id: detection_conclusion if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); await main(); @@ -1113,20 +1126,20 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} - name: Check team membership for workflow id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_REQUIRED_ROLES: "admin,maintainer,write" with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs'); await main(); - name: Checkout the select-copilot-pat action folder @@ -1183,7 +1196,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1213,7 +1226,7 @@ jobs: echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" - name: Process Safe Outputs id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} 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,www.googleapis.com" @@ -1224,14 +1237,14 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); await main(); - - name: Upload Safe Output Items + - name: Upload Safe Outputs Items if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: - name: safe-output-items + name: safe-outputs-items path: /tmp/gh-aw/safe-output-items.jsonl if-no-files-found: ignore diff --git a/src/msbuild/.github/workflows/review-on-open.agent.lock.yml b/src/msbuild/.github/workflows/review-on-open.agent.lock.yml index 1557822c2763..7f888cc46fb9 100644 --- a/src/msbuild/.github/workflows/review-on-open.agent.lock.yml +++ b/src/msbuild/.github/workflows/review-on-open.agent.lock.yml @@ -1,4 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"57f7734059be051198a41fce57f2d7c0d0adc1cb3324e181df8c0cf0495b2867","compiler_version":"v0.67.1","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"57f7734059be051198a41fce57f2d7c0d0adc1cb3324e181df8c0cf0495b2867","compiler_version":"v0.68.1","strict":true,"agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","COPILOT_GITHUB_TOKEN_1","COPILOT_GITHUB_TOKEN_2","COPILOT_GITHUB_TOKEN_3","COPILOT_GITHUB_TOKEN_4","COPILOT_GITHUB_TOKEN_5","COPILOT_GITHUB_TOKEN_6","COPILOT_GITHUB_TOKEN_7","COPILOT_GITHUB_TOKEN_8","COPILOT_GITHUB_TOKEN_9","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"},{"repo":"actions/upload-artifact","sha":"bbbca2ddaa5d8feaa63e36b76fdaad77386f024f","version":"v7"},{"repo":"github/gh-aw-actions/setup","sha":"2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc","version":"v0.68.1"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -13,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.67.1). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.68.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -45,9 +46,9 @@ # Custom actions used: # - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 -# - actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 +# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 # - actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 -# - github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 +# - github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 name: "Expert Code Review (on open)" "on": @@ -97,6 +98,7 @@ jobs: if: needs.pre_activation.outputs.activated == 'true' && (github.event.pull_request.draft == false) runs-on: ubuntu-slim permissions: + actions: read contents: read outputs: body: ${{ steps.sanitized.outputs.body }} @@ -106,12 +108,13 @@ jobs: model: ${{ steps.generate_aw_info.outputs.model }} secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }} text: ${{ steps.sanitized.outputs.text }} title: ${{ steps.sanitized.outputs.title }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -122,29 +125,29 @@ jobs: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} - GH_AW_INFO_VERSION: "latest" - GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.67.1" + GH_AW_INFO_VERSION: "1.0.21" + GH_AW_INFO_AGENT_VERSION: "1.0.21" + GH_AW_INFO_CLI_VERSION: "v0.68.1" GH_AW_INFO_WORKFLOW_NAME: "Expert Code Review (on open)" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.13" + GH_AW_INFO_AWF_VERSION: "v0.25.18" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "true" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Validate COPILOT_GITHUB_TOKEN secret id: validate-secret - run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default env: COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} - name: Checkout .github and .agents folders @@ -157,33 +160,34 @@ jobs: sparse-checkout-cone-mode: true fetch-depth: 1 - name: Check workflow lock file - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + id: check-lock-file + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_WORKFLOW_FILE: "review-on-open.agent.lock.yml" GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); await main(); - name: Check compile-agentic version - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: - GH_AW_COMPILED_VERSION: "v0.67.1" + GH_AW_COMPILED_VERSION: "v0.68.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); await main(); - name: Compute current body text id: sanitized - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/compute_text.cjs'); await main(); - name: Create prompt with built-in context @@ -200,7 +204,7 @@ jobs: GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} # poutine:ignore untrusted_checkout_exec run: | - bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh + bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { cat << 'GH_AW_PROMPT_bac3f4f17f0d53fb_EOF' @@ -250,17 +254,17 @@ jobs: GH_AW_PROMPT_bac3f4f17f0d53fb_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); await main(); - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -275,7 +279,7 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); @@ -298,12 +302,12 @@ jobs: env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt # poutine:ignore untrusted_checkout_exec - run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt # poutine:ignore untrusted_checkout_exec - run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" - name: Upload activation artifact if: success() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 @@ -341,7 +345,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -357,9 +361,9 @@ jobs: with: persist-credentials: false - name: Create gh-aw temp directory - run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" - name: Configure gh CLI for GitHub Enterprise - run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh" env: GH_TOKEN: ${{ github.token }} - name: Configure Git credentials @@ -379,25 +383,25 @@ jobs: id: checkout-pr if: | github.event.pull_request || github.event.issue.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); await main(); - name: Install GitHub Copilot CLI - run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 env: GH_HOST: github.com - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.18 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} @@ -406,179 +410,183 @@ jobs: const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 ghcr.io/github/gh-aw-mcpg:v0.2.14 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.18 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.18 ghcr.io/github/gh-aw-firewall/squid:0.25.18 ghcr.io/github/gh-aw-mcpg:v0.2.17 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine - name: Write Safe Outputs Config run: | - mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs + 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_8bf5f36be4cd3c92_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_8bf5f36be4cd3c92_EOF' {"add_comment":{"max":5},"create_pull_request_review_comment":{"max":30,"side":"RIGHT"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{},"submit_pull_request_review":{"max":1}} GH_AW_SAFE_OUTPUTS_CONFIG_8bf5f36be4cd3c92_EOF - name: Write Safe Outputs Tools - run: | - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_7191a3f5fde22c3b_EOF' - { - "description_suffixes": { - "add_comment": " CONSTRAINTS: Maximum 5 comment(s) can be added.", - "create_pull_request_review_comment": " CONSTRAINTS: Maximum 30 review comment(s) can be created. Comments will be on the RIGHT side of the diff.", - "submit_pull_request_review": " CONSTRAINTS: Maximum 1 review(s) can be submitted." - }, - "repo_params": {}, - "dynamic_tools": [] - } - GH_AW_SAFE_OUTPUTS_TOOLS_META_7191a3f5fde22c3b_EOF - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_d88e91a02df89e42_EOF' - { - "add_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "item_number": { - "issueOrPRNumber": true - }, - "repo": { - "type": "string", - "maxLength": 256 - } - } - }, - "create_pull_request_review_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "line": { - "required": true, - "positiveInteger": true - }, - "path": { - "required": true, - "type": "string" - }, - "pull_request_number": { - "optionalPositiveInteger": true - }, - "repo": { - "type": "string", - "maxLength": 256 - }, - "side": { - "type": "string", - "enum": [ - "LEFT", - "RIGHT" - ] - }, - "start_line": { - "optionalPositiveInteger": true + env: + GH_AW_TOOLS_META_JSON: | + { + "description_suffixes": { + "add_comment": " CONSTRAINTS: Maximum 5 comment(s) can be added.", + "create_pull_request_review_comment": " CONSTRAINTS: Maximum 30 review comment(s) can be created. Comments will be on the RIGHT side of the diff.", + "submit_pull_request_review": " CONSTRAINTS: Maximum 1 review(s) can be submitted." + }, + "repo_params": {}, + "dynamic_tools": [] + } + GH_AW_VALIDATION_JSON: | + { + "add_comment": { + "defaultMax": 1, + "fields": { + "body": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "item_number": { + "issueOrPRNumber": true + }, + "repo": { + "type": "string", + "maxLength": 256 + } } }, - "customValidation": "startLineLessOrEqualLine" - }, - "missing_data": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "context": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "data_type": { - "type": "string", - "sanitize": true, - "maxLength": 128 + "create_pull_request_review_comment": { + "defaultMax": 1, + "fields": { + "body": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "line": { + "required": true, + "positiveInteger": true + }, + "path": { + "required": true, + "type": "string" + }, + "pull_request_number": { + "optionalPositiveInteger": true + }, + "repo": { + "type": "string", + "maxLength": 256 + }, + "side": { + "type": "string", + "enum": [ + "LEFT", + "RIGHT" + ] + }, + "start_line": { + "optionalPositiveInteger": true + } }, - "reason": { - "type": "string", - "sanitize": true, - "maxLength": 256 + "customValidation": "startLineLessOrEqualLine" + }, + "missing_data": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "context": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "data_type": { + "type": "string", + "sanitize": true, + "maxLength": 128 + }, + "reason": { + "type": "string", + "sanitize": true, + "maxLength": 256 + } } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 + }, + "missing_tool": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 512 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "tool": { + "type": "string", + "sanitize": true, + "maxLength": 128 + } } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 + }, + "noop": { + "defaultMax": 1, + "fields": { + "message": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + } } - } - }, - "report_incomplete": { - "defaultMax": 5, - "fields": { - "details": { - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 1024 + }, + "report_incomplete": { + "defaultMax": 5, + "fields": { + "details": { + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 1024 + } } - } - }, - "submit_pull_request_review": { - "defaultMax": 1, - "fields": { - "body": { - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "event": { - "type": "string", - "enum": [ - "APPROVE", - "REQUEST_CHANGES", - "COMMENT" - ] + }, + "submit_pull_request_review": { + "defaultMax": 1, + "fields": { + "body": { + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "event": { + "type": "string", + "enum": [ + "APPROVE", + "REQUEST_CHANGES", + "COMMENT" + ] + } } } } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_d88e91a02df89e42_EOF - node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + await main(); - name: Generate Safe Outputs MCP Server Config id: safe-outputs-config run: | @@ -617,7 +625,7 @@ jobs: export GH_AW_SAFE_OUTPUTS_CONFIG_PATH export GH_AW_MCP_LOG_DIR - bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh + bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh" - name: Start MCP Gateway id: start-mcp-gateway @@ -644,10 +652,10 @@ jobs: export DEBUG="*" export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.14' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.17' mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_95dc438e78a995c8_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh + cat << GH_AW_MCP_CONFIG_95dc438e78a995c8_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh" { "mcpServers": { "github": { @@ -696,7 +704,7 @@ jobs: path: /tmp/gh-aw - name: Clean git credentials continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh" - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): @@ -704,9 +712,10 @@ jobs: run: | set -o pipefail touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 - sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-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,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-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,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.18 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} @@ -715,7 +724,7 @@ jobs: GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.67.1 + GH_AW_VERSION: v0.68.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -733,7 +742,7 @@ jobs: id: detect-inference-error if: always() continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh" - name: Configure Git credentials env: REPO_NAME: ${{ github.repository }} @@ -750,7 +759,7 @@ jobs: - name: Copy Copilot session state files to logs if: always() continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh" - name: Stop MCP Gateway if: always() continue-on-error: true @@ -759,14 +768,14 @@ jobs: MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} run: | - bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" + bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID" - name: Redact secrets in logs if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); await main(); env: @@ -786,7 +795,7 @@ jobs: SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Append agent step summary if: always() - run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh" - name: Copy Safe Outputs if: always() env: @@ -797,7 +806,7 @@ jobs: - name: Ingest agent output id: collect_output if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} 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,www.googleapis.com" @@ -806,28 +815,28 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); await main(); - name: Parse agent logs for step summary if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); await main(); - name: Parse MCP Gateway logs for step summary if: always() id: parse-mcp-gateway - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); await main(); - name: Print firewall logs @@ -848,11 +857,11 @@ jobs: - name: Parse token usage for step summary if: always() continue-on-error: true - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); await main(); - name: Write agent output placeholder if missing @@ -898,7 +907,9 @@ jobs: - agent - detection - safe_outputs - if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true') + if: > + always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || + needs.activation.outputs.stale_lock_file_failed == 'true') runs-on: ubuntu-slim permissions: contents: read @@ -916,7 +927,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -937,7 +948,7 @@ jobs: echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - name: Process No-Op Messages id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_NOOP_MAX: "1" @@ -949,12 +960,12 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); await main(); - - name: Record Missing Tool + - name: Record missing tool id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_MISSING_TOOL_CREATE_ISSUE: "true" @@ -963,12 +974,12 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); await main(); - - name: Record Incomplete + - name: Record incomplete id: report_incomplete - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true" @@ -977,13 +988,13 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); await main(); - - name: Handle Agent Failure + - name: Handle agent failure id: handle_agent_failure if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_WORKFLOW_NAME: "Expert Code Review (on open)" @@ -995,6 +1006,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_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }} + GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }} GH_AW_GROUP_REPORTS: "false" GH_AW_FAILURE_REPORT_AS_ISSUE: "true" GH_AW_TIMEOUT_MINUTES: "60" @@ -1002,7 +1014,7 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); await main(); @@ -1021,7 +1033,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1047,7 +1059,7 @@ jobs: persist-credentials: false # --- Threat Detection --- - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.18 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.18 ghcr.io/github/gh-aw-firewall/squid:0.25.18 - name: Check if detection needed id: detection_guard if: always() @@ -1084,7 +1096,7 @@ jobs: ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: WORKFLOW_NAME: "Expert Code Review (on open)" WORKFLOW_DESCRIPTION: "Automatically runs the expert-reviewer agent when a non-draft PR is opened." @@ -1092,7 +1104,7 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); await main(); - name: Ensure threat-detection directory and log @@ -1101,11 +1113,11 @@ jobs: mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - name: Install GitHub Copilot CLI - run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 env: GH_HOST: github.com - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.18 - name: Execute GitHub Copilot CLI if: always() && steps.detection_guard.outputs.run_detection == 'true' id: detection_agentic_execution @@ -1114,16 +1126,17 @@ jobs: run: | set -o pipefail touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) # shellcheck disable=SC1003 - sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.18 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.67.1 + GH_AW_VERSION: v0.68.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -1146,13 +1159,13 @@ jobs: - name: Parse and conclude threat detection id: detection_conclusion if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); await main(); @@ -1168,20 +1181,20 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} - name: Check team membership for workflow id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_REQUIRED_ROLES: "admin,maintainer,write" with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs'); await main(); - name: Checkout the select-copilot-pat action folder @@ -1238,7 +1251,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1268,7 +1281,7 @@ jobs: echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" - name: Process Safe Outputs id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} 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,www.googleapis.com" @@ -1279,14 +1292,14 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); await main(); - - name: Upload Safe Output Items + - name: Upload Safe Outputs Items if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: - name: safe-output-items + name: safe-outputs-items path: /tmp/gh-aw/safe-output-items.jsonl if-no-files-found: ignore diff --git a/src/msbuild/.github/workflows/review.agent.lock.yml b/src/msbuild/.github/workflows/review.agent.lock.yml index 1c01eefa5dbb..c796ce7fff7d 100644 --- a/src/msbuild/.github/workflows/review.agent.lock.yml +++ b/src/msbuild/.github/workflows/review.agent.lock.yml @@ -1,4 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"443b3b2227d168c089515b75f23840a65d3c78a6aab0abfe08e20a4c89c98dd7","compiler_version":"v0.67.1","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"443b3b2227d168c089515b75f23840a65d3c78a6aab0abfe08e20a4c89c98dd7","compiler_version":"v0.68.1","strict":true,"agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","COPILOT_GITHUB_TOKEN_1","COPILOT_GITHUB_TOKEN_2","COPILOT_GITHUB_TOKEN_3","COPILOT_GITHUB_TOKEN_4","COPILOT_GITHUB_TOKEN_5","COPILOT_GITHUB_TOKEN_6","COPILOT_GITHUB_TOKEN_7","COPILOT_GITHUB_TOKEN_8","COPILOT_GITHUB_TOKEN_9","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"},{"repo":"actions/upload-artifact","sha":"bbbca2ddaa5d8feaa63e36b76fdaad77386f024f","version":"v7"},{"repo":"github/gh-aw-actions/setup","sha":"2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc","version":"v0.68.1"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -13,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.67.1). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.68.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -45,9 +46,9 @@ # Custom actions used: # - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 -# - actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 +# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 # - actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 -# - github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 +# - github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 name: "Expert Code Review (command)" "on": @@ -95,6 +96,7 @@ jobs: if: "needs.pre_activation.outputs.activated == 'true' && (github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/review ') || startsWith(github.event.comment.body, '/review\n') || github.event.comment.body == '/review') && github.event.issue.pull_request != null || !(github.event_name == 'issue_comment'))" runs-on: ubuntu-slim permissions: + actions: read contents: read discussions: write issues: write @@ -109,12 +111,13 @@ jobs: secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} slash_command: ${{ needs.pre_activation.outputs.matched_command }} + stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }} text: ${{ steps.sanitized.outputs.text }} title: ${{ steps.sanitized.outputs.title }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -125,42 +128,42 @@ jobs: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} - GH_AW_INFO_VERSION: "latest" - GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.67.1" + GH_AW_INFO_VERSION: "1.0.21" + GH_AW_INFO_AGENT_VERSION: "1.0.21" + GH_AW_INFO_CLI_VERSION: "v0.68.1" GH_AW_INFO_WORKFLOW_NAME: "Expert Code Review (command)" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.13" + GH_AW_INFO_AWF_VERSION: "v0.25.18" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "true" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Add eyes reaction for immediate feedback id: react if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.id == github.repository_id - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_REACTION: "eyes" with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs'); await main(); - name: Validate COPILOT_GITHUB_TOKEN secret id: validate-secret - run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default env: COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} - name: Checkout .github and .agents folders @@ -173,45 +176,46 @@ jobs: sparse-checkout-cone-mode: true fetch-depth: 1 - name: Check workflow lock file - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + id: check-lock-file + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_WORKFLOW_FILE: "review.agent.lock.yml" GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); await main(); - name: Check compile-agentic version - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: - GH_AW_COMPILED_VERSION: "v0.67.1" + GH_AW_COMPILED_VERSION: "v0.68.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); await main(); - name: Compute current body text id: sanitized - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/compute_text.cjs'); await main(); - name: Add comment with workflow run link id: add-comment if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.id == github.repository_id - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_WORKFLOW_NAME: "Expert Code Review (command)" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/add_workflow_run_comment.cjs'); await main(); - name: Create prompt with built-in context @@ -229,7 +233,7 @@ jobs: GH_AW_IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || '' }} # poutine:ignore untrusted_checkout_exec run: | - bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh + bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { cat << 'GH_AW_PROMPT_a26aed7c6595e707_EOF' @@ -282,17 +286,17 @@ jobs: GH_AW_PROMPT_a26aed7c6595e707_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); await main(); - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -309,7 +313,7 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); @@ -334,12 +338,12 @@ jobs: env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt # poutine:ignore untrusted_checkout_exec - run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt # poutine:ignore untrusted_checkout_exec - run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" - name: Upload activation artifact if: success() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 @@ -377,7 +381,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -393,9 +397,9 @@ jobs: with: persist-credentials: false - name: Create gh-aw temp directory - run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" - name: Configure gh CLI for GitHub Enterprise - run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh" env: GH_TOKEN: ${{ github.token }} - name: Configure Git credentials @@ -415,25 +419,25 @@ jobs: id: checkout-pr if: | github.event.pull_request || github.event.issue.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); await main(); - name: Install GitHub Copilot CLI - run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 env: GH_HOST: github.com - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.18 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} @@ -442,179 +446,183 @@ jobs: const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 ghcr.io/github/gh-aw-mcpg:v0.2.14 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.18 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.18 ghcr.io/github/gh-aw-firewall/squid:0.25.18 ghcr.io/github/gh-aw-mcpg:v0.2.17 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine - name: Write Safe Outputs Config run: | - mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs + 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_67b7486fe65698e1_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_67b7486fe65698e1_EOF' {"add_comment":{"max":5},"create_pull_request_review_comment":{"max":30,"side":"RIGHT"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{},"submit_pull_request_review":{"max":1}} GH_AW_SAFE_OUTPUTS_CONFIG_67b7486fe65698e1_EOF - name: Write Safe Outputs Tools - run: | - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_5b457cd1003a5398_EOF' - { - "description_suffixes": { - "add_comment": " CONSTRAINTS: Maximum 5 comment(s) can be added.", - "create_pull_request_review_comment": " CONSTRAINTS: Maximum 30 review comment(s) can be created. Comments will be on the RIGHT side of the diff.", - "submit_pull_request_review": " CONSTRAINTS: Maximum 1 review(s) can be submitted." - }, - "repo_params": {}, - "dynamic_tools": [] - } - GH_AW_SAFE_OUTPUTS_TOOLS_META_5b457cd1003a5398_EOF - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_91ee8748b6398e3c_EOF' - { - "add_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "item_number": { - "issueOrPRNumber": true - }, - "repo": { - "type": "string", - "maxLength": 256 - } - } - }, - "create_pull_request_review_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "line": { - "required": true, - "positiveInteger": true - }, - "path": { - "required": true, - "type": "string" - }, - "pull_request_number": { - "optionalPositiveInteger": true - }, - "repo": { - "type": "string", - "maxLength": 256 - }, - "side": { - "type": "string", - "enum": [ - "LEFT", - "RIGHT" - ] - }, - "start_line": { - "optionalPositiveInteger": true + env: + GH_AW_TOOLS_META_JSON: | + { + "description_suffixes": { + "add_comment": " CONSTRAINTS: Maximum 5 comment(s) can be added.", + "create_pull_request_review_comment": " CONSTRAINTS: Maximum 30 review comment(s) can be created. Comments will be on the RIGHT side of the diff.", + "submit_pull_request_review": " CONSTRAINTS: Maximum 1 review(s) can be submitted." + }, + "repo_params": {}, + "dynamic_tools": [] + } + GH_AW_VALIDATION_JSON: | + { + "add_comment": { + "defaultMax": 1, + "fields": { + "body": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "item_number": { + "issueOrPRNumber": true + }, + "repo": { + "type": "string", + "maxLength": 256 + } } }, - "customValidation": "startLineLessOrEqualLine" - }, - "missing_data": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "context": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "data_type": { - "type": "string", - "sanitize": true, - "maxLength": 128 + "create_pull_request_review_comment": { + "defaultMax": 1, + "fields": { + "body": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "line": { + "required": true, + "positiveInteger": true + }, + "path": { + "required": true, + "type": "string" + }, + "pull_request_number": { + "optionalPositiveInteger": true + }, + "repo": { + "type": "string", + "maxLength": 256 + }, + "side": { + "type": "string", + "enum": [ + "LEFT", + "RIGHT" + ] + }, + "start_line": { + "optionalPositiveInteger": true + } }, - "reason": { - "type": "string", - "sanitize": true, - "maxLength": 256 + "customValidation": "startLineLessOrEqualLine" + }, + "missing_data": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "context": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "data_type": { + "type": "string", + "sanitize": true, + "maxLength": 128 + }, + "reason": { + "type": "string", + "sanitize": true, + "maxLength": 256 + } } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 + }, + "missing_tool": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 512 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "tool": { + "type": "string", + "sanitize": true, + "maxLength": 128 + } } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 + }, + "noop": { + "defaultMax": 1, + "fields": { + "message": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + } } - } - }, - "report_incomplete": { - "defaultMax": 5, - "fields": { - "details": { - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 1024 + }, + "report_incomplete": { + "defaultMax": 5, + "fields": { + "details": { + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 1024 + } } - } - }, - "submit_pull_request_review": { - "defaultMax": 1, - "fields": { - "body": { - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "event": { - "type": "string", - "enum": [ - "APPROVE", - "REQUEST_CHANGES", - "COMMENT" - ] + }, + "submit_pull_request_review": { + "defaultMax": 1, + "fields": { + "body": { + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "event": { + "type": "string", + "enum": [ + "APPROVE", + "REQUEST_CHANGES", + "COMMENT" + ] + } } } } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_91ee8748b6398e3c_EOF - node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + await main(); - name: Generate Safe Outputs MCP Server Config id: safe-outputs-config run: | @@ -653,7 +661,7 @@ jobs: export GH_AW_SAFE_OUTPUTS_CONFIG_PATH export GH_AW_MCP_LOG_DIR - bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh + bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh" - name: Start MCP Gateway id: start-mcp-gateway @@ -680,10 +688,10 @@ jobs: export DEBUG="*" export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.14' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.17' mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_83efb810ab46085f_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh + cat << GH_AW_MCP_CONFIG_83efb810ab46085f_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh" { "mcpServers": { "github": { @@ -732,7 +740,7 @@ jobs: path: /tmp/gh-aw - name: Clean git credentials continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh" - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): @@ -740,9 +748,10 @@ jobs: run: | set -o pipefail touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 - sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-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,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-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,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.18 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} @@ -751,7 +760,7 @@ jobs: GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.67.1 + GH_AW_VERSION: v0.68.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -769,7 +778,7 @@ jobs: id: detect-inference-error if: always() continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh" - name: Configure Git credentials env: REPO_NAME: ${{ github.repository }} @@ -786,7 +795,7 @@ jobs: - name: Copy Copilot session state files to logs if: always() continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh" - name: Stop MCP Gateway if: always() continue-on-error: true @@ -795,14 +804,14 @@ jobs: MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} run: | - bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" + bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID" - name: Redact secrets in logs if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); await main(); env: @@ -822,7 +831,7 @@ jobs: SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Append agent step summary if: always() - run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh + run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh" - name: Copy Safe Outputs if: always() env: @@ -833,7 +842,7 @@ jobs: - name: Ingest agent output id: collect_output if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} 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,www.googleapis.com" @@ -843,28 +852,28 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); await main(); - name: Parse agent logs for step summary if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); await main(); - name: Parse MCP Gateway logs for step summary if: always() id: parse-mcp-gateway - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); await main(); - name: Print firewall logs @@ -885,11 +894,11 @@ jobs: - name: Parse token usage for step summary if: always() continue-on-error: true - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); await main(); - name: Write agent output placeholder if missing @@ -935,7 +944,9 @@ jobs: - agent - detection - safe_outputs - if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true') + if: > + always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || + needs.activation.outputs.stale_lock_file_failed == 'true') runs-on: ubuntu-slim permissions: contents: read @@ -953,7 +964,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -974,7 +985,7 @@ jobs: echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - name: Process No-Op Messages id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_NOOP_MAX: "1" @@ -986,12 +997,12 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); await main(); - - name: Record Missing Tool + - name: Record missing tool id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_MISSING_TOOL_CREATE_ISSUE: "true" @@ -1000,12 +1011,12 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); await main(); - - name: Record Incomplete + - name: Record incomplete id: report_incomplete - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true" @@ -1014,13 +1025,13 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); await main(); - - name: Handle Agent Failure + - name: Handle agent failure id: handle_agent_failure if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_WORKFLOW_NAME: "Expert Code Review (command)" @@ -1032,6 +1043,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_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }} + GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }} GH_AW_GROUP_REPORTS: "false" GH_AW_FAILURE_REPORT_AS_ISSUE: "true" GH_AW_TIMEOUT_MINUTES: "60" @@ -1039,12 +1051,12 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); await main(); - name: Update reaction comment with completion status id: conclusion - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} @@ -1057,7 +1069,7 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/notify_comment_error.cjs'); await main(); @@ -1076,7 +1088,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1102,7 +1114,7 @@ jobs: persist-credentials: false # --- Threat Detection --- - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.18 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.18 ghcr.io/github/gh-aw-firewall/squid:0.25.18 - name: Check if detection needed id: detection_guard if: always() @@ -1139,7 +1151,7 @@ jobs: ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: WORKFLOW_NAME: "Expert Code Review (command)" WORKFLOW_DESCRIPTION: "Runs the expert-reviewer agent on a pull request when a contributor comments /review." @@ -1147,7 +1159,7 @@ jobs: with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); await main(); - name: Ensure threat-detection directory and log @@ -1156,11 +1168,11 @@ jobs: mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - name: Install GitHub Copilot CLI - run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 env: GH_HOST: github.com - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.13 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.18 - name: Execute GitHub Copilot CLI if: always() && steps.detection_guard.outputs.run_detection == 'true' id: detection_agentic_execution @@ -1169,16 +1181,17 @@ jobs: run: | set -o pipefail touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) # shellcheck disable=SC1003 - sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.18 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number == '0', secrets.COPILOT_GITHUB_TOKEN, needs.pre_activation.outputs.copilot_pat_number == '1', secrets.COPILOT_GITHUB_TOKEN_1, needs.pre_activation.outputs.copilot_pat_number == '2', secrets.COPILOT_GITHUB_TOKEN_2, needs.pre_activation.outputs.copilot_pat_number == '3', secrets.COPILOT_GITHUB_TOKEN_3, needs.pre_activation.outputs.copilot_pat_number == '4', secrets.COPILOT_GITHUB_TOKEN_4, needs.pre_activation.outputs.copilot_pat_number == '5', secrets.COPILOT_GITHUB_TOKEN_5, needs.pre_activation.outputs.copilot_pat_number == '6', secrets.COPILOT_GITHUB_TOKEN_6, needs.pre_activation.outputs.copilot_pat_number == '7', secrets.COPILOT_GITHUB_TOKEN_7, needs.pre_activation.outputs.copilot_pat_number == '8', secrets.COPILOT_GITHUB_TOKEN_8, needs.pre_activation.outputs.copilot_pat_number == '9', secrets.COPILOT_GITHUB_TOKEN_9, secrets.COPILOT_GITHUB_TOKEN) }} COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.67.1 + GH_AW_VERSION: v0.68.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -1201,13 +1214,13 @@ jobs: - name: Parse and conclude threat detection id: detection_conclusion if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); await main(); @@ -1223,31 +1236,31 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} - name: Check team membership for command workflow id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_REQUIRED_ROLES: "admin,maintainer,write" with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs'); await main(); - name: Check command position id: check_command_position - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_COMMANDS: "[\"review\"]" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_command_position.cjs'); await main(); - name: Checkout the select-copilot-pat action folder @@ -1304,7 +1317,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@80471a493be8c528dd27daf73cd644242a7965e0 # v0.67.1 + uses: github/gh-aw-actions/setup@2fe53acc038ba01c3bbdc767d4b25df31ca5bdfc # v0.68.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1334,7 +1347,7 @@ jobs: echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" - name: Process Safe Outputs id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} 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,www.googleapis.com" @@ -1345,14 +1358,14 @@ jobs: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); + setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); await main(); - - name: Upload Safe Output Items + - name: Upload Safe Outputs Items if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: - name: safe-output-items + name: safe-outputs-items path: /tmp/gh-aw/safe-output-items.jsonl if-no-files-found: ignore diff --git a/src/msbuild/Coverage.config b/src/msbuild/Coverage.config new file mode 100644 index 000000000000..412f9cc8bd0b --- /dev/null +++ b/src/msbuild/Coverage.config @@ -0,0 +1,33 @@ + + + True + true + MissingAll + + + + .*doc\.dll$ + .*customlogger\.dll$ + .*invalidcustomcheck\.dll$ + .*portabletask\.dll$ + .*faultylogger\.dll$ + .*customcheck\.dll$ + .*customcheck2\.dll$ + .*errorcustomcheck\.dll$ + + + + + .*\.g\.cs$ + .*\.sr\.cs$ + + + 120000 + 1270 + False + True + False + False + True + + diff --git a/src/msbuild/Coverage.runsettings b/src/msbuild/Coverage.runsettings deleted file mode 100644 index 4c48352ed698..000000000000 --- a/src/msbuild/Coverage.runsettings +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - True - true - MissingAll - - - - .*doc\.dll$ - .*customlogger\.dll$ - .*invalidcustomcheck\.dll$ - .*portabletask\.dll$ - .*faultylogger\.dll$ - .*customcheck\.dll$ - .*customcheck2\.dll$ - .*errorcustomcheck\.dll$ - - - - - .*\.g\.cs$ - .*\.sr\.cs$ - - - 120000 - 1270 - False - True - False - False - True - - - - - - diff --git a/src/msbuild/CoverageWindowsFull.config b/src/msbuild/CoverageWindowsFull.config new file mode 100644 index 000000000000..3d1d6234965d --- /dev/null +++ b/src/msbuild/CoverageWindowsFull.config @@ -0,0 +1,42 @@ + + + True + true + MissingAll + + + + .*doc\.dll$ + .*net472.* + .*microsoft\.build\.buildcheck\.unittests\.dll$ + .*microsoft\.build\.tasks\.unittests\.dll$ + + + .*microsoft\.build\.engine\.unittests\.dll$ + .*microsoft\.build\.engine\.om\.unittests\.dll$ + .*microsoft\.build\.framework\.dll$ + .*microsoft\.build\.framework\.unittests\.dll$ + .*microsoft\.build\.commandline\.unittests\.dll$ + + + + + .*microsoft\.net\.stringtools\.dll$ + .*microsoft\.net\.stringtools\.unittests\.dll$ + + + + + .*\.g\.cs$ + .*\.sr\.cs$ + + + 120000 + 1270 + False + True + False + False + True + + diff --git a/src/msbuild/CoverageWindowsFull.runsettings b/src/msbuild/CoverageWindowsFull.runsettings deleted file mode 100644 index 145ce8360c20..000000000000 --- a/src/msbuild/CoverageWindowsFull.runsettings +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - True - true - MissingAll - - - - .*doc\.dll$ - .*net472.* - .*microsoft\.build\.buildcheck\.unittests\.dll$ - .*microsoft\.build\.tasks\.unittests\.dll$ - - - .*microsoft\.build\.engine\.unittests\.dll$ - .*microsoft\.build\.engine\.om\.unittests\.dll$ - .*microsoft\.build\.framework\.dll$ - .*microsoft\.build\.framework\.unittests\.dll$ - .*microsoft\.build\.commandline\.unittests\.dll$ - - - - - .*microsoft\.net\.stringtools\.dll$ - .*microsoft\.net\.stringtools\.unittests\.dll$ - - - - - .*\.g\.cs$ - .*\.sr\.cs$ - - - 120000 - 1270 - False - True - False - False - True - - - - - - \ No newline at end of file diff --git a/src/msbuild/Directory.Build.props b/src/msbuild/Directory.Build.props index c0fdacba18a5..4698f8dc7216 100644 --- a/src/msbuild/Directory.Build.props +++ b/src/msbuild/Directory.Build.props @@ -13,6 +13,15 @@ + XUnitV3 + 3.2.2 + 1.9.1 + Exe + + + + $(NoWarn);xUnit1051 + net472 diff --git a/src/msbuild/eng/Version.Details.props b/src/msbuild/eng/Version.Details.props index 1f14525dfd5e..2be33bf33fb7 100644 --- a/src/msbuild/eng/Version.Details.props +++ b/src/msbuild/eng/Version.Details.props @@ -7,27 +7,27 @@ This file should be imported by eng/Versions.props 10.0.0-beta.26164.1 - 10.0.0-beta.26164.1 + 10.0.0-beta.26164.1 5.6.0-2.26151.2 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 - 10.0.3 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 + 10.0.4 7.5.0-rc.36 @@ -35,7 +35,7 @@ This file should be imported by eng/Versions.props $(MicrosoftDotNetArcadeSdkPackageVersion) - $(MicrosoftDotNetXUnitExtensionsPackageVersion) + $(MicrosoftDotNetXUnitV3ExtensionsPackageVersion) $(MicrosoftNetCompilersToolsetPackageVersion) diff --git a/src/msbuild/eng/Version.Details.xml b/src/msbuild/eng/Version.Details.xml index 08ffe42d7e8c..6b137db754d4 100644 --- a/src/msbuild/eng/Version.Details.xml +++ b/src/msbuild/eng/Version.Details.xml @@ -3,103 +3,103 @@ - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime - + https://github.com/dotnet/runtime @@ -118,9 +118,9 @@ https://github.com/dotnet/roslyn 6bdca1d6466c2f9ef46f8e5d3422fbe3568d503c - + https://github.com/dotnet/arcade e365cfcb58176841c2fb80d1a40926f394776970 - \ No newline at end of file + diff --git a/src/msbuild/eng/Versions.props b/src/msbuild/eng/Versions.props index 8a600b58d3ad..6079380920f5 100644 --- a/src/msbuild/eng/Versions.props +++ b/src/msbuild/eng/Versions.props @@ -1,4 +1,4 @@ - + diff --git a/src/msbuild/eng/dependabot/Directory.Packages.props b/src/msbuild/eng/dependabot/Directory.Packages.props index f1ab6ce820ac..553cee36c745 100644 --- a/src/msbuild/eng/dependabot/Directory.Packages.props +++ b/src/msbuild/eng/dependabot/Directory.Packages.props @@ -49,6 +49,9 @@ + + + @@ -56,8 +59,8 @@ - - + + diff --git a/src/msbuild/global.json b/src/msbuild/global.json index df2fbacae9a1..c1dbac05e50e 100644 --- a/src/msbuild/global.json +++ b/src/msbuild/global.json @@ -15,5 +15,8 @@ }, "msbuild-sdks": { "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26164.1" + }, + "test": { + "runner": "Microsoft.Testing.Platform" } } diff --git a/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectFormatting_Tests.cs b/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectFormatting_Tests.cs index 678577ef4a0f..0d51bf6a6eae 100644 --- a/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectFormatting_Tests.cs +++ b/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectFormatting_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.Build.Shared; using Microsoft.Build.UnitTests; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectMetadataElement_Tests.cs b/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectMetadataElement_Tests.cs index 27b52869ac21..dd679f2c3a01 100644 --- a/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectMetadataElement_Tests.cs +++ b/src/msbuild/src/Build.OM.UnitTests/Construction/ProjectMetadataElement_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.Construction; using Microsoft.Build.Evaluation; using Xunit; -using Xunit.Abstractions; using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; #nullable disable diff --git a/src/msbuild/src/Build.OM.UnitTests/Definition/ProjectCollection_Tests.cs b/src/msbuild/src/Build.OM.UnitTests/Definition/ProjectCollection_Tests.cs index 360edefcac27..f1c5834ee821 100644 --- a/src/msbuild/src/Build.OM.UnitTests/Definition/ProjectCollection_Tests.cs +++ b/src/msbuild/src/Build.OM.UnitTests/Definition/ProjectCollection_Tests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; #nullable disable diff --git a/src/msbuild/src/Build.OM.UnitTests/Definition/Project_Tests.cs b/src/msbuild/src/Build.OM.UnitTests/Definition/Project_Tests.cs index 021fdd8780c7..ad02494ee14d 100644 --- a/src/msbuild/src/Build.OM.UnitTests/Definition/Project_Tests.cs +++ b/src/msbuild/src/Build.OM.UnitTests/Definition/Project_Tests.cs @@ -17,7 +17,6 @@ using Microsoft.Build.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; using GlobResultList = System.Collections.Generic.List<(string, string[], System.Collections.Immutable.ImmutableHashSet, System.Collections.Immutable.ImmutableHashSet)>; using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; // can't use an actual ProvenanceResult because it points to a ProjectItemElement which is hard to mock. diff --git a/src/msbuild/src/Build.OM.UnitTests/Instance/ProjectInstance_Tests.cs b/src/msbuild/src/Build.OM.UnitTests/Instance/ProjectInstance_Tests.cs index c7278144daec..5fd3942551f1 100644 --- a/src/msbuild/src/Build.OM.UnitTests/Instance/ProjectInstance_Tests.cs +++ b/src/msbuild/src/Build.OM.UnitTests/Instance/ProjectInstance_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.Framework; using Microsoft.Build.Shared; using Xunit; -using Xunit.Abstractions; using ForwardingLoggerRecord = Microsoft.Build.Logging.ForwardingLoggerRecord; #nullable disable diff --git a/src/msbuild/src/Build.OM.UnitTests/Microsoft.Build.Engine.OM.UnitTests.csproj b/src/msbuild/src/Build.OM.UnitTests/Microsoft.Build.Engine.OM.UnitTests.csproj index c50c47b30475..41e769b7a8b0 100644 --- a/src/msbuild/src/Build.OM.UnitTests/Microsoft.Build.Engine.OM.UnitTests.csproj +++ b/src/msbuild/src/Build.OM.UnitTests/Microsoft.Build.Engine.OM.UnitTests.csproj @@ -7,6 +7,7 @@ Microsoft.Build.Engine.OM.UnitTests true + $(DefineConstants);IS_OM_TESTS diff --git a/src/msbuild/src/Build.OM.UnitTests/NugetRestoreTests.cs b/src/msbuild/src/Build.OM.UnitTests/NugetRestoreTests.cs index 61d2d5b65169..651bd508f51d 100644 --- a/src/msbuild/src/Build.OM.UnitTests/NugetRestoreTests.cs +++ b/src/msbuild/src/Build.OM.UnitTests/NugetRestoreTests.cs @@ -7,7 +7,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.OM.UnitTests { diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/AppHostSupport_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/AppHostSupport_Tests.cs index 87de6e545c29..9666bd0406ae 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/AppHostSupport_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/AppHostSupport_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable @@ -92,6 +91,12 @@ public void ClearBootstrapDotnetRootEnvironment_ClearsVariablesNotInOriginalEnvi env.SetEnvironmentVariable("DOTNET_ROOT", @"C:\TestDotnet"); env.SetEnvironmentVariable("DOTNET_ROOT_X64", @"C:\TestDotnetX64"); + // This might seem redundant, but it's not. + // ClearBootstrapDotnetRootEnvironment is a production method that alters env variables directly via Environment class. + // This clears DOTNET_ROOT_X86 which might have been originally set. + // To ensure that DOTNET_ROOT_X86 is restored, we set it to itself so that TestEnvironment.Dispose restores it back. + env.SetEnvironmentVariable("DOTNET_ROOT_X86", Environment.GetEnvironmentVariable("DOTNET_ROOT_X86")); + // Original environment does NOT have these variables var originalEnvironment = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/AssemblyTaskFactory_E2E_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/AssemblyTaskFactory_E2E_Tests.cs index 9d86a0eaf47c..610c6aca7609 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/AssemblyTaskFactory_E2E_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/AssemblyTaskFactory_E2E_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests { diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Logging_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Logging_Tests.cs index b1db9f4d0404..03abb4b1890e 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Logging_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Logging_Tests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.UnitTests.ObjectModelHelpers; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Tests.cs index 60b95abb4465..961abd28ffe1 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/BuildManager_Tests.cs @@ -24,7 +24,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.UnitTests.ObjectModelHelpers; using Constants = Microsoft.Build.Framework.Constants; diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs index c35fc6a2b3f7..1b9f67bedcc4 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs @@ -16,7 +16,6 @@ using Microsoft.Build.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/DebugUtils_tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/DebugUtils_tests.cs index 24a34de7b814..ead2ac6302b7 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/DebugUtils_tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/DebugUtils_tests.cs @@ -20,7 +20,8 @@ public class DebugUtils_Tests public void DumpExceptionToFileShouldWriteInDebugDumpPath() { DebugUtils.ResetDebugDumpPathInRunningTests = true; - var exceptionFilesBefore = Directory.GetFiles(DebugUtils.DebugDumpPath, "MSBuild_*failure.txt"); + var exceptionFilesBefore = + Directory.Exists(DebugUtils.DebugDumpPath) ? Directory.GetFiles(DebugUtils.DebugDumpPath, "MSBuild_*failure.txt") : Array.Empty(); string[] exceptionFiles = null; diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/LoggingContext_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/LoggingContext_Tests.cs index 020d527ab3fd..435f06a0369c 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/LoggingContext_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/LoggingContext_Tests.cs @@ -5,7 +5,6 @@ using Microsoft.Build.Framework; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs index ff5005502601..6a50d6d43854 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/MockHost.cs b/src/msbuild/src/Build.UnitTests/BackEnd/MockHost.cs index 3326ddfd49e6..dbe06caf8164 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/MockHost.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/MockHost.cs @@ -65,7 +65,7 @@ internal sealed class MockHost : MockLoggingService, IBuildComponentHost, IBuild private IBuildCheckManagerProvider _buildCheckManagerProvider; - private TelemetryForwarderProvider _telemetryForwarder; + private TelemetryCollectorProvider _telemetryCollector; #region SystemParameterFields @@ -136,8 +136,8 @@ public MockHost(BuildParameters buildParameters, ConfigCache overrideConfigCache _buildCheckManagerProvider = new NullBuildCheckManagerProvider(); ((IBuildComponent)_buildCheckManagerProvider).InitializeComponent(this); - _telemetryForwarder = new TelemetryForwarderProvider(); - ((IBuildComponent)_telemetryForwarder).InitializeComponent(this); + _telemetryCollector = new TelemetryCollectorProvider(); + ((IBuildComponent)_telemetryCollector).InitializeComponent(this); } /// @@ -207,7 +207,7 @@ public IBuildComponent GetComponent(BuildComponentType type) BuildComponentType.RequestBuilder => (IBuildComponent)_requestBuilder, BuildComponentType.SdkResolverService => (IBuildComponent)_sdkResolverService, BuildComponentType.BuildCheckManagerProvider => (IBuildComponent)_buildCheckManagerProvider, - BuildComponentType.TelemetryForwarder => (IBuildComponent)_telemetryForwarder, + BuildComponentType.TelemetryCollector => (IBuildComponent)_telemetryCollector, _ => throw new ArgumentException("Unexpected type " + type), }; } diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/SdkResolverLoader_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/SdkResolverLoader_Tests.cs index b310fa1bd2a7..a3fb0b03274d 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/SdkResolverLoader_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/SdkResolverLoader_Tests.cs @@ -15,7 +15,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; using Exception = System.Exception; using SdkResolverBase = Microsoft.Build.Framework.SdkResolver; using SdkResolverContextBase = Microsoft.Build.Framework.SdkResolverContext; diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/SdkResultOutOfProc_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/SdkResultOutOfProc_Tests.cs index 0baca3b2dade..59de4dcc5275 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/SdkResultOutOfProc_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/SdkResultOutOfProc_Tests.cs @@ -16,7 +16,6 @@ using Microsoft.Build.Unittest; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.UnitTests.ObjectModelHelpers; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TargetEntry_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TargetEntry_Tests.cs index 8607e64e5725..140cbaa94dcd 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TargetEntry_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TargetEntry_Tests.cs @@ -17,7 +17,6 @@ using Microsoft.Build.Framework; using Microsoft.Build.Shared; using Xunit; -using Xunit.Abstractions; using ElementLocation = Microsoft.Build.Construction.ElementLocation; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TargetUpToDateChecker_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TargetUpToDateChecker_Tests.cs index a9f0d72ff3a0..37b31c7cd0a7 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TargetUpToDateChecker_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TargetUpToDateChecker_Tests.cs @@ -15,7 +15,6 @@ using Microsoft.Build.Shared; using Microsoft.Win32.SafeHandles; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TaskBuilder_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TaskBuilder_Tests.cs index cd7a3910c9fa..068ec160be6c 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TaskBuilder_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TaskBuilder_Tests.cs @@ -18,7 +18,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; using ElementLocation = Microsoft.Build.Construction.ElementLocation; using ILoggingService = Microsoft.Build.BackEnd.Logging.ILoggingService; using LegacyThreadingData = Microsoft.Build.Execution.LegacyThreadingData; diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostCallback_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostCallback_Tests.cs index f54cde2470ea..6ef2d14d91b4 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostCallback_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostCallback_Tests.cs @@ -9,7 +9,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.UnitTests.BackEnd { diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostFactory_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostFactory_Tests.cs index 22178bbe6186..a11f04725719 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostFactory_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TaskHostFactory_Tests.cs @@ -13,7 +13,6 @@ using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable @@ -25,7 +24,9 @@ namespace Microsoft.Build.Engine.UnitTests.BackEnd /// public sealed class TaskHostFactory_Tests { - private static string AssemblyLocation { get; } = Path.Combine(Path.GetDirectoryName(typeof(TaskHostFactory_Tests).Assembly.Location) ?? AppContext.BaseDirectory, "Microsoft.Build.Engine.UnitTests.dll"); + private static string AssemblyLocation { get; } = + typeof(TaskHostFactory_Tests).Assembly.Location + ?? Path.Combine(AppContext.BaseDirectory, "Microsoft.Build.Engine.UnitTests.dll"); private ITestOutputHelper _output; diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TaskHost_MultiThreadableTask_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TaskHost_MultiThreadableTask_Tests.cs index f1e59ba557b8..ccd50d62cabb 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TaskHost_MultiThreadableTask_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TaskHost_MultiThreadableTask_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests.BackEnd { diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TaskRegistry_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TaskRegistry_Tests.cs index 6c4b7461b8ae..b751aef46886 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TaskRegistry_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TaskRegistry_Tests.cs @@ -20,7 +20,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/TaskRouter_IntegrationTests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/TaskRouter_IntegrationTests.cs index fa508369b3df..a5b1b7627520 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/TaskRouter_IntegrationTests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/TaskRouter_IntegrationTests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/BinaryLogger_Tests.cs b/src/msbuild/src/Build.UnitTests/BinaryLogger_Tests.cs index 3edb919e6956..82d9c9194f42 100644 --- a/src/msbuild/src/Build.UnitTests/BinaryLogger_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BinaryLogger_Tests.cs @@ -18,7 +18,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable @@ -102,6 +101,17 @@ public enum BinlogRoundtripTestReplayMode [InlineData(s_testProject2, BinlogRoundtripTestReplayMode.RawEvents)] public void TestBinaryLoggerRoundtrip(string projectText, BinlogRoundtripTestReplayMode replayMode) { + // NOTE: + // We want both loggers to see the same value of EnableTargetOutputLogging, otherwise, the last assertion will fail. + // See logic around showTargetOutputs. + // In short, this controls whether or not the "Target output items:" part is shown. + // Traits.Instance is weird, it's not always a singleton, depending on whether or not BuildEnvironmentState.s_runningTests is true. + // In this case s_runningTests is true. + // When s_runningTests is true, we don't use a singleton, and in this case, what matters is the env variable value. + // So we set the env variable to 1 and clear at the end of test. + using var env = TestEnvironment.Create(); + env.SetEnvironmentVariable("MSBUILDTARGETOUTPUTLOGGING", "1"); + var binaryLogger = new BinaryLogger(); binaryLogger.Parameters = _logFile; diff --git a/src/msbuild/src/Build.UnitTests/CLR2TaskHost_E2E_Tests.cs b/src/msbuild/src/Build.UnitTests/CLR2TaskHost_E2E_Tests.cs index 25dc52fff899..2380c4b2879c 100644 --- a/src/msbuild/src/Build.UnitTests/CLR2TaskHost_E2E_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/CLR2TaskHost_E2E_Tests.cs @@ -6,7 +6,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests; diff --git a/src/msbuild/src/Build.UnitTests/ChangeWaves_Tests.cs b/src/msbuild/src/Build.UnitTests/ChangeWaves_Tests.cs index d81e765c3abb..7f5b8d69936d 100644 --- a/src/msbuild/src/Build.UnitTests/ChangeWaves_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/ChangeWaves_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/ConsoleLogger_Tests.cs b/src/msbuild/src/Build.UnitTests/ConsoleLogger_Tests.cs index 139e461cc401..3456745feb2a 100644 --- a/src/msbuild/src/Build.UnitTests/ConsoleLogger_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/ConsoleLogger_Tests.cs @@ -17,7 +17,6 @@ using Microsoft.Build.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; using TaskItem = Microsoft.Build.Execution.ProjectItemInstance.TaskItem; #nullable disable @@ -1220,15 +1219,23 @@ public void DoNotDisplayEnvironmentInDetailed() [Fact] public void DisplayEnvironmentInDetailed() { - SimulatedConsole sc = new SimulatedConsole(); + var logAllOriginal = Traits.LogAllEnvironmentVariables; + try + { + SimulatedConsole sc = new SimulatedConsole(); - ParallelConsoleLogger cl2 = new ParallelConsoleLogger(LoggerVerbosity.Detailed, sc.Write, null, null); - EventSourceSink es = new EventSourceSink(); - cl2.Initialize(es); - cl2.Parameters = "ShowEnvironment"; - cl2.ParseParameters(); + ParallelConsoleLogger cl2 = new ParallelConsoleLogger(LoggerVerbosity.Detailed, sc.Write, null, null); + EventSourceSink es = new EventSourceSink(); + cl2.Initialize(es); + cl2.Parameters = "ShowEnvironment"; + cl2.ParseParameters(); - WriteEnvironment(cl2, sc, true); + WriteEnvironment(cl2, sc, true); + } + finally + { + Traits.LogAllEnvironmentVariables = logAllOriginal; + } } /// @@ -1264,15 +1271,23 @@ public void DoNotDisplayEnvironmentInMinimal() [Fact] public void DisplayEnvironmentInMinimal() { - SimulatedConsole sc = new SimulatedConsole(); - - ParallelConsoleLogger cl2 = new ParallelConsoleLogger(LoggerVerbosity.Minimal, sc.Write, null, null); - EventSourceSink es = new EventSourceSink(); - cl2.Initialize(es); - cl2.Parameters = "ShowEnvironment"; - cl2.ParseParameters(); + var logAllOriginal = Traits.LogAllEnvironmentVariables; + try + { + SimulatedConsole sc = new SimulatedConsole(); - WriteEnvironment(cl2, sc, true); + ParallelConsoleLogger cl2 = new ParallelConsoleLogger(LoggerVerbosity.Minimal, sc.Write, null, null); + EventSourceSink es = new EventSourceSink(); + cl2.Initialize(es); + cl2.Parameters = "ShowEnvironment"; + cl2.ParseParameters(); + + WriteEnvironment(cl2, sc, true); + } + finally + { + Traits.LogAllEnvironmentVariables = logAllOriginal; + } } /// diff --git a/src/msbuild/src/Build.UnitTests/Construction/ProjectRootElement_Tests.cs b/src/msbuild/src/Build.UnitTests/Construction/ProjectRootElement_Tests.cs index 13ab48079a49..677322633af6 100644 --- a/src/msbuild/src/Build.UnitTests/Construction/ProjectRootElement_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Construction/ProjectRootElement_Tests.cs @@ -115,6 +115,12 @@ public void ProjectLoadedStrippingCommentsAndWhiteSpaceIsReadOnly() Assert.Equal(2, children[0].ChildNodes.Count); Assert.Equal(string.Empty, children[0].ChildNodes[0].Value); Assert.Equal(string.Empty, children[0].ChildNodes[1].Value); + + // We cleared at the beginning, but then we set MSBUILDLOADALLFILESASREADONLY to 1. + // This means that opening the project will cache s_readOnlyFlags as ReadOnlyLoadFlags.LoadAllReadOnly + // Keeping the cached ReadOnlyLoadFlags.LoadAllReadOnly can impact subsequent tests that are running in the same process. + // So ensure to re-clear. + XmlDocumentWithLocation.ClearReadOnlyFlags_UnitTestsOnly(); } } diff --git a/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_NewParser_Tests.cs b/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_NewParser_Tests.cs index 873cd2d1b5c4..3abae4d9a6f2 100644 --- a/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_NewParser_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_NewParser_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.VisualStudio.SolutionPersistence.Serializer; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_OldParser_Tests.cs b/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_OldParser_Tests.cs index e471c0373ceb..1a58f4ba1c5d 100644 --- a/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_OldParser_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Construction/SolutionFile_OldParser_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.Build.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/Construction/SolutionFilter_Tests.cs b/src/msbuild/src/Build.UnitTests/Construction/SolutionFilter_Tests.cs index 593dc8bf5c0a..a779efcc5b1a 100644 --- a/src/msbuild/src/Build.UnitTests/Construction/SolutionFilter_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Construction/SolutionFilter_Tests.cs @@ -20,7 +20,6 @@ using Microsoft.VisualStudio.SolutionPersistence.Serializer; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests.Construction { diff --git a/src/msbuild/src/Build.UnitTests/Construction/SolutionProjectGenerator_Tests.cs b/src/msbuild/src/Build.UnitTests/Construction/SolutionProjectGenerator_Tests.cs index c57f5ebedb96..6f1a3f1ae91e 100644 --- a/src/msbuild/src/Build.UnitTests/Construction/SolutionProjectGenerator_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Construction/SolutionProjectGenerator_Tests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; using FrameworkLocationHelper = Microsoft.Build.Shared.FrameworkLocationHelper; using ILoggingService = Microsoft.Build.BackEnd.Logging.ILoggingService; using InternalUtilities = Microsoft.Build.Internal.Utilities; diff --git a/src/msbuild/src/Build.UnitTests/EndToEndCondition_Tests.cs b/src/msbuild/src/Build.UnitTests/EndToEndCondition_Tests.cs index 042f448a6554..cb2925a1e86e 100644 --- a/src/msbuild/src/Build.UnitTests/EndToEndCondition_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/EndToEndCondition_Tests.cs @@ -5,7 +5,6 @@ using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/EscapingInProjects_Tests.cs b/src/msbuild/src/Build.UnitTests/EscapingInProjects_Tests.cs index 90095b266e02..06556aeb12d0 100644 --- a/src/msbuild/src/Build.UnitTests/EscapingInProjects_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/EscapingInProjects_Tests.cs @@ -22,7 +22,6 @@ using ResourceUtilities = Microsoft.Build.Shared.ResourceUtilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #if FEATURE_COMPILE_IN_TESTS using Microsoft.Build.Shared; #endif diff --git a/src/msbuild/src/Build.UnitTests/Evaluation/ExpanderFunction_Tests.cs b/src/msbuild/src/Build.UnitTests/Evaluation/ExpanderFunction_Tests.cs index 4b69b86fe02d..6cc460778a75 100644 --- a/src/msbuild/src/Build.UnitTests/Evaluation/ExpanderFunction_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Evaluation/ExpanderFunction_Tests.cs @@ -7,7 +7,6 @@ using Shouldly; using Xunit; -using Xunit.Abstractions; using ParseArgs = Microsoft.Build.Evaluation.Expander.ArgumentParser; namespace Microsoft.Build.Engine.UnitTests.Evaluation diff --git a/src/msbuild/src/Build.UnitTests/Evaluation/Expander_Tests.cs b/src/msbuild/src/Build.UnitTests/Evaluation/Expander_Tests.cs index 4a9364feb78b..017537189f2f 100644 --- a/src/msbuild/src/Build.UnitTests/Evaluation/Expander_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Evaluation/Expander_Tests.cs @@ -26,7 +26,6 @@ using Microsoft.Win32; using Shouldly; using Xunit; -using Xunit.Abstractions; using Xunit.NetCore.Extensions; using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; using ProjectHelpers = Microsoft.Build.UnitTests.BackEnd.ProjectHelpers; @@ -5133,6 +5132,7 @@ public void ExpandItem_ConvertToStringUsingInvariantCultureForNumberData_Respect using (var env = TestEnvironment.Create()) { env.SetEnvironmentVariable("MSBUILDDISABLEFEATURESFROMVERSION", ChangeWaves.Wave17_12.ToString()); + ChangeWaves.ResetStateForTests(); currentThread.CurrentCulture = svSECultureInfo; currentThread.CurrentUICulture = svSECultureInfo; var root = env.CreateFolder(); diff --git a/src/msbuild/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs b/src/msbuild/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs index 9632dce86b33..4c71ffaeedc0 100644 --- a/src/msbuild/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.Unittest; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/EvaluationProfiler_Tests.cs b/src/msbuild/src/Build.UnitTests/EvaluationProfiler_Tests.cs index d78f804d41ad..3b780a8c3b70 100644 --- a/src/msbuild/src/Build.UnitTests/EvaluationProfiler_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/EvaluationProfiler_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.Build.Logging; using Microsoft.Build.UnitTests; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.UnitTests.ObjectModelHelpers; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/ExpressionTreeExpression_Tests.cs b/src/msbuild/src/Build.UnitTests/ExpressionTreeExpression_Tests.cs index bd9f5ac973ba..250bee586014 100644 --- a/src/msbuild/src/Build.UnitTests/ExpressionTreeExpression_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/ExpressionTreeExpression_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.Build.Execution; using Microsoft.Build.Shared.FileSystem; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs b/src/msbuild/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs index 77e4ffded51c..66a0a7b9fc40 100644 --- a/src/msbuild/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs +++ b/src/msbuild/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.Graph.UnitTests.GraphTestingUtilities; using static Microsoft.Build.UnitTests.Helpers; diff --git a/src/msbuild/src/Build.UnitTests/Graph/IsolateProjects_Tests.cs b/src/msbuild/src/Build.UnitTests/Graph/IsolateProjects_Tests.cs index 1da40fe77d38..131d658473b7 100644 --- a/src/msbuild/src/Build.UnitTests/Graph/IsolateProjects_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Graph/IsolateProjects_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; using ExpectedNodeBuildOutput = System.Collections.Generic.Dictionary; using OutputCacheDictionary = System.Collections.Generic.Dictionary; diff --git a/src/msbuild/src/Build.UnitTests/Graph/ProjectGraph_Tests.cs b/src/msbuild/src/Build.UnitTests/Graph/ProjectGraph_Tests.cs index e275395f5f3a..5bf891c47076 100644 --- a/src/msbuild/src/Build.UnitTests/Graph/ProjectGraph_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Graph/ProjectGraph_Tests.cs @@ -17,7 +17,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; using Xunit.NetCore.Extensions; using static Microsoft.Build.Graph.UnitTests.GraphTestingUtilities; diff --git a/src/msbuild/src/Build.UnitTests/Graph/ResultCacheBasedBuilds_Tests.cs b/src/msbuild/src/Build.UnitTests/Graph/ResultCacheBasedBuilds_Tests.cs index 11033d78af87..fe19764230ce 100644 --- a/src/msbuild/src/Build.UnitTests/Graph/ResultCacheBasedBuilds_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Graph/ResultCacheBasedBuilds_Tests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.UnitTests.Helpers; using ExpectedNodeBuildOutput = System.Collections.Generic.Dictionary; diff --git a/src/msbuild/src/Build.UnitTests/Instance/ProjectInstance_Internal_Tests.cs b/src/msbuild/src/Build.UnitTests/Instance/ProjectInstance_Internal_Tests.cs index fd8ba8841d0c..2aea8c3eff24 100644 --- a/src/msbuild/src/Build.UnitTests/Instance/ProjectInstance_Internal_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Instance/ProjectInstance_Internal_Tests.cs @@ -16,7 +16,6 @@ using Microsoft.Build.UnitTests.BackEnd; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.Engine.UnitTests.TestComparers.ProjectInstanceModelTestComparers; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/InvalidProjectFileException_Tests.cs b/src/msbuild/src/Build.UnitTests/InvalidProjectFileException_Tests.cs index 7a1d62aab197..069a77f41f55 100644 --- a/src/msbuild/src/Build.UnitTests/InvalidProjectFileException_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/InvalidProjectFileException_Tests.cs @@ -6,7 +6,6 @@ using Microsoft.Build.Exceptions; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Build.UnitTests/MSBuildTaskHostTests.cs b/src/msbuild/src/Build.UnitTests/MSBuildTaskHostTests.cs index 2891387495f9..0521804c0469 100644 --- a/src/msbuild/src/Build.UnitTests/MSBuildTaskHostTests.cs +++ b/src/msbuild/src/Build.UnitTests/MSBuildTaskHostTests.cs @@ -9,7 +9,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests; diff --git a/src/msbuild/src/Build.UnitTests/Microsoft.Build.Engine.UnitTests.csproj b/src/msbuild/src/Build.UnitTests/Microsoft.Build.Engine.UnitTests.csproj index 39c496de0b34..223f751a3679 100644 --- a/src/msbuild/src/Build.UnitTests/Microsoft.Build.Engine.UnitTests.csproj +++ b/src/msbuild/src/Build.UnitTests/Microsoft.Build.Engine.UnitTests.csproj @@ -27,7 +27,7 @@ - + all diff --git a/src/msbuild/src/Build.UnitTests/NetTaskHost_E2E_Tests.cs b/src/msbuild/src/Build.UnitTests/NetTaskHost_E2E_Tests.cs index 4e52d3243b0c..8098e34353ae 100644 --- a/src/msbuild/src/Build.UnitTests/NetTaskHost_E2E_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/NetTaskHost_E2E_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests { diff --git a/src/msbuild/src/Build.UnitTests/NodeStatus_SizeChange_Tests.cs b/src/msbuild/src/Build.UnitTests/NodeStatus_SizeChange_Tests.cs index de0a9c3210db..6465582ad902 100644 --- a/src/msbuild/src/Build.UnitTests/NodeStatus_SizeChange_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/NodeStatus_SizeChange_Tests.cs @@ -14,7 +14,6 @@ namespace Microsoft.Build.CommandLine.UnitTests; -[UsesVerify] [UseInvariantCulture] public class NodeStatus_SizeChange_Tests { diff --git a/src/msbuild/src/Build.UnitTests/NodeStatus_Transition_Tests.cs b/src/msbuild/src/Build.UnitTests/NodeStatus_Transition_Tests.cs index 0eb6857ee3eb..73d0298a184d 100644 --- a/src/msbuild/src/Build.UnitTests/NodeStatus_Transition_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/NodeStatus_Transition_Tests.cs @@ -17,7 +17,6 @@ namespace Microsoft.Build.CommandLine.UnitTests; -[UsesVerify] [UseInvariantCulture] public class NodeStatus_Transition_Tests { diff --git a/src/msbuild/src/Build.UnitTests/ProjectCache/ProjectCacheTests.cs b/src/msbuild/src/Build.UnitTests/ProjectCache/ProjectCacheTests.cs index f7e7bd70711c..05d05fde2ddf 100644 --- a/src/msbuild/src/Build.UnitTests/ProjectCache/ProjectCacheTests.cs +++ b/src/msbuild/src/Build.UnitTests/ProjectCache/ProjectCacheTests.cs @@ -22,7 +22,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; using Task = System.Threading.Tasks.Task; namespace Microsoft.Build.Engine.UnitTests.ProjectCache diff --git a/src/msbuild/src/Build.UnitTests/Resources_Tests.cs b/src/msbuild/src/Build.UnitTests/Resources_Tests.cs index acd1d6039bee..ecc78f548728 100644 --- a/src/msbuild/src/Build.UnitTests/Resources_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Resources_Tests.cs @@ -9,7 +9,6 @@ using System.Xml.Linq; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.UnitTests { diff --git a/src/msbuild/src/Build.UnitTests/TaskHostFactoryLifecycle_E2E_Tests.cs b/src/msbuild/src/Build.UnitTests/TaskHostFactoryLifecycle_E2E_Tests.cs index 464ca7672dac..2fe46bf490d7 100644 --- a/src/msbuild/src/Build.UnitTests/TaskHostFactoryLifecycle_E2E_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/TaskHostFactoryLifecycle_E2E_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests { diff --git a/src/msbuild/src/Build.UnitTests/Telemetry/Telemetry_Tests.cs b/src/msbuild/src/Build.UnitTests/Telemetry/Telemetry_Tests.cs index 0361e99ca0d6..59dd45747a34 100644 --- a/src/msbuild/src/Build.UnitTests/Telemetry/Telemetry_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Telemetry/Telemetry_Tests.cs @@ -16,7 +16,6 @@ using Microsoft.Build.UnitTests.BackEnd; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.Framework.Telemetry.BuildInsights; using static Microsoft.Build.Framework.Telemetry.TelemetryDataUtils; @@ -486,39 +485,35 @@ public void IsEmpty_TrueForDefault_FalseAfterAdd() } [Fact] - public void FinalizeProcessing_AfterMerge_ResetsState() + public void TelemetryCollector_AccumulatesAndSendsOnFinalize() { - var forwarder = new TelemetryForwarderProvider.TelemetryForwarder(); + var collector = new TelemetryCollectorProvider.TelemetryCollector(); var loggingService = new EventRecordingLoggingService(); var loggingContext = new MockLoggingContext( loggingService, new BuildEventContext(1, 2, BuildEventContext.InvalidProjectContextId, 4)); - // Merge some data. - var localData = new WorkerNodeTelemetryData(); + // Add data via the collector API. var key = new TaskOrTargetTelemetryKey("TestTarget", isCustom: true, isFromNugetCache: false, isFromMetaProject: false); - localData.AddTarget(key, wasExecuted: true); - forwarder.MergeWorkerData(localData); + collector.AddTarget(key, wasExecuted: true); // First FinalizeProcessing should emit a telemetry event. - forwarder.FinalizeProcessing(loggingContext); + collector.FinalizeProcessing(loggingContext); var telemetryEvents = loggingService.RecordedEvents.OfType().ToList(); telemetryEvents.Count.ShouldBe(1); telemetryEvents[0].WorkerNodeTelemetryData.TargetsExecutionData.ShouldContainKey(key); - // Second FinalizeProcessing on an empty forwarder should be a no-op (state was reset). - forwarder.FinalizeProcessing(loggingContext); + // Second FinalizeProcessing on an empty collector should be a no-op (state was reset). + collector.FinalizeProcessing(loggingContext); loggingService.RecordedEvents.OfType().Count().ShouldBe(1, "No new event should be emitted after reset"); - // Merge new data after reset — forwarder should still work. - var localData2 = new WorkerNodeTelemetryData(); + // Add new data after reset — collector should still work. var key2 = new TaskOrTargetTelemetryKey("TestTarget2", isCustom: false, isFromNugetCache: false, isFromMetaProject: false); - localData2.AddTarget(key2, wasExecuted: false, skipReason: TargetSkipReason.ConditionWasFalse); - forwarder.MergeWorkerData(localData2); + collector.AddTarget(key2, wasExecuted: false, skipReason: TargetSkipReason.ConditionWasFalse); // Third FinalizeProcessing should emit only the new data. - forwarder.FinalizeProcessing(loggingContext); + collector.FinalizeProcessing(loggingContext); var allTelemetryEvents = loggingService.RecordedEvents.OfType().ToList(); allTelemetryEvents.Count.ShouldBe(2); allTelemetryEvents[1].WorkerNodeTelemetryData.TargetsExecutionData.ShouldContainKey(key2); diff --git a/src/msbuild/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs b/src/msbuild/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs index 5a7fe9c2b3de..9242de9c48dd 100644 --- a/src/msbuild/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.UnitTests; diff --git a/src/msbuild/src/Build.UnitTests/TerminalLogger_Tests.cs b/src/msbuild/src/Build.UnitTests/TerminalLogger_Tests.cs index 68928d9b783b..9790afa31404 100644 --- a/src/msbuild/src/Build.UnitTests/TerminalLogger_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/TerminalLogger_Tests.cs @@ -18,7 +18,6 @@ using VerifyTests; using VerifyXunit; using Xunit; -using Xunit.Abstractions; using Xunit.NetCore.Extensions; using static VerifyXunit.Verifier; @@ -132,7 +131,6 @@ void IBuildEventSink.ShutDown() public void InvokeCustomEventRaised(CustomBuildEventArgs args) => CustomEventRaised?.Invoke(_eventSender, args); } - [UsesVerify] [UseInvariantCulture] public class TerminalLogger_Tests { diff --git a/src/msbuild/src/Build.UnitTests/Utilities_Tests.cs b/src/msbuild/src/Build.UnitTests/Utilities_Tests.cs index 880fbe49e590..18e908472c91 100644 --- a/src/msbuild/src/Build.UnitTests/Utilities_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/Utilities_Tests.cs @@ -6,7 +6,6 @@ using System.IO; using Shouldly; using Xunit; -using Xunit.Abstractions; using InternalUtilities = Microsoft.Build.Internal.Utilities; using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; using MSBuildApp = Microsoft.Build.CommandLine.MSBuildApp; diff --git a/src/msbuild/src/Build.UnitTests/WarningsAsMessagesAndErrors_Tests.cs b/src/msbuild/src/Build.UnitTests/WarningsAsMessagesAndErrors_Tests.cs index 10ce4eba75b8..1d588fda3d50 100644 --- a/src/msbuild/src/Build.UnitTests/WarningsAsMessagesAndErrors_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/WarningsAsMessagesAndErrors_Tests.cs @@ -9,7 +9,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable @@ -19,9 +18,11 @@ public sealed class WarningsAsMessagesAndErrorsTests { private const string ExpectedEventMessage = "03767942CDB147B98D0ECDBDE1436DA3"; private const string ExpectedEventCode = "0BF68998"; - private static string TestAssemblyLocation { get; } = Path.Combine( - Path.GetDirectoryName(typeof(WarningsAsMessagesAndErrorsTests).Assembly.Location) ?? AppContext.BaseDirectory, - "Microsoft.Build.Engine.UnitTests.dll"); + + private static string TestAssemblyLocation { get; } = + typeof(WarningsAsMessagesAndErrorsTests).Assembly.Location + ?? Path.Combine(AppContext.BaseDirectory, $"Microsoft.Build.Engine.UnitTests.dll"); + private ITestOutputHelper _output; public WarningsAsMessagesAndErrorsTests(ITestOutputHelper output) diff --git a/src/msbuild/src/Build/BackEnd/Components/BuildComponentFactoryCollection.cs b/src/msbuild/src/Build/BackEnd/Components/BuildComponentFactoryCollection.cs index 5e255466d52c..872b2a62ab98 100644 --- a/src/msbuild/src/Build/BackEnd/Components/BuildComponentFactoryCollection.cs +++ b/src/msbuild/src/Build/BackEnd/Components/BuildComponentFactoryCollection.cs @@ -82,7 +82,7 @@ public void RegisterDefaultFactories() _componentEntriesByType[BuildComponentType.RequestBuilder] = new BuildComponentEntry(BuildComponentType.RequestBuilder, RequestBuilder.CreateComponent, CreationPattern.CreateAlways); // Following two conditionally registers real or no-op implementation based on BuildParameters _componentEntriesByType[BuildComponentType.BuildCheckManagerProvider] = new BuildComponentEntry(BuildComponentType.BuildCheckManagerProvider, BuildCheckManagerProvider.CreateComponent, CreationPattern.Singleton); - _componentEntriesByType[BuildComponentType.TelemetryForwarder] = new BuildComponentEntry(BuildComponentType.TelemetryForwarder, TelemetryForwarderProvider.CreateComponent, CreationPattern.Singleton); + _componentEntriesByType[BuildComponentType.TelemetryCollector] = new BuildComponentEntry(BuildComponentType.TelemetryCollector, TelemetryCollectorProvider.CreateComponent, CreationPattern.Singleton); _componentEntriesByType[BuildComponentType.TargetBuilder] = new BuildComponentEntry(BuildComponentType.TargetBuilder, TargetBuilder.CreateComponent, CreationPattern.CreateAlways); _componentEntriesByType[BuildComponentType.TaskBuilder] = new BuildComponentEntry(BuildComponentType.TaskBuilder, TaskBuilder.CreateComponent, CreationPattern.CreateAlways); _componentEntriesByType[BuildComponentType.RegisteredTaskObjectCache] = new BuildComponentEntry(BuildComponentType.RegisteredTaskObjectCache, RegisteredTaskObjectCache.CreateComponent, CreationPattern.Singleton); diff --git a/src/msbuild/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs b/src/msbuild/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs index 5675721fbf8a..baccd0cdf143 100644 --- a/src/msbuild/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs +++ b/src/msbuild/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs @@ -208,6 +208,11 @@ public void InitializeForBuild(NodeLoggingContext loggingContext) _nodeLoggingContext = loggingContext; + // Create a per-BuildRequestEngine telemetry collector via the provider. + // Each BuildRequestEngine owns its collector — no cross-engine sharing, no singleton contention. + var telemetryProvider = (TelemetryCollectorProvider)_componentHost.GetComponent(BuildComponentType.TelemetryCollector); + _nodeLoggingContext.TelemetryCollector = telemetryProvider.CreateCollector(); + // Create a work queue that will take an action and invoke it. The generic parameter is the type which ActionBlock.Post() will // take (an Action in this case) and the parameter to this constructor is a function which takes that parameter of type Action // (which we have named action) and does something with it (in this case calls invoke on it.) @@ -302,9 +307,8 @@ public void CleanupForBuild() IBuildCheckManagerProvider buildCheckProvider = (_componentHost.GetComponent(BuildComponentType.BuildCheckManagerProvider) as IBuildCheckManagerProvider); var buildCheckManager = buildCheckProvider!.Instance; buildCheckManager.FinalizeProcessing(_nodeLoggingContext); - // Flush and send the final telemetry data if they are being collected - ITelemetryForwarder telemetryForwarder = (_componentHost.GetComponent(BuildComponentType.TelemetryForwarder) as TelemetryForwarderProvider)!.Instance; - telemetryForwarder.FinalizeProcessing(_nodeLoggingContext); + // Flush and send the per-BuildRequestEngine telemetry data if any was collected. + _nodeLoggingContext.TelemetryCollector?.FinalizeProcessing(_nodeLoggingContext); // Clears the instance so that next call (on node reuse) to 'GetComponent' leads to reinitialization. buildCheckProvider.ShutdownComponent(); }, diff --git a/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs b/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs index 95cf4815134d..360b60d70b8b 100644 --- a/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs +++ b/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs @@ -475,6 +475,12 @@ void CreateNodeContext(int nodeId, Process nodeToReuse, Stream nodeStream, byte bool isNativeHost = msbuildLocation != null && Path.GetFileName(msbuildLocation).Equals(Constants.MSBuildExecutableName, StringComparison.OrdinalIgnoreCase); string expectedProcessName = Path.GetFileNameWithoutExtension(isNativeHost ? msbuildLocation : (CurrentHost.GetCurrentHost() ?? msbuildLocation)); +#if NETFRAMEWORK + // Fall back to the standard executable name for most nodes + // on .NET Framework, to function in `ShutdownAllNodes()` + expectedProcessName ??= Constants.MSBuildAppName; +#endif + Process[] processes; try { diff --git a/src/msbuild/src/Build/BackEnd/Components/IBuildComponentHost.cs b/src/msbuild/src/Build/BackEnd/Components/IBuildComponentHost.cs index 5c46a8ef8073..d87cfd648539 100644 --- a/src/msbuild/src/Build/BackEnd/Components/IBuildComponentHost.cs +++ b/src/msbuild/src/Build/BackEnd/Components/IBuildComponentHost.cs @@ -151,7 +151,7 @@ internal enum BuildComponentType /// /// The component which collects telemetry data in worker node and forwards it to the main node. /// - TelemetryForwarder, + TelemetryCollector, } /// diff --git a/src/msbuild/src/Build/BackEnd/Components/Logging/NodeLoggingContext.cs b/src/msbuild/src/Build/BackEnd/Components/Logging/NodeLoggingContext.cs index e03c8ed13e7c..cad9599829ad 100644 --- a/src/msbuild/src/Build/BackEnd/Components/Logging/NodeLoggingContext.cs +++ b/src/msbuild/src/Build/BackEnd/Components/Logging/NodeLoggingContext.cs @@ -4,6 +4,7 @@ using Microsoft.Build.Execution; using Microsoft.Build.Framework; using Microsoft.Build.Shared; +using Microsoft.Build.TelemetryInfra; #nullable disable @@ -34,6 +35,12 @@ internal NodeLoggingContext(ILoggingService loggingService, int nodeId, bool inP this.IsValid = true; } + /// + /// Per- telemetry collector. + /// Null when telemetry collection is disabled. + /// + internal ITelemetryCollector TelemetryCollector { get; set; } + /// /// Log the completion of a build /// diff --git a/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/RequestBuilder.cs b/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/RequestBuilder.cs index 5f337c991488..d3ea99d4dff6 100644 --- a/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/RequestBuilder.cs +++ b/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/RequestBuilder.cs @@ -1297,11 +1297,9 @@ BuildResult CopyTargetResultsFromProxyTargetsToRealTargets(BuildResult resultFro private void UpdateStatisticsPostBuild() { - ITelemetryForwarder telemetryForwarder = - ((TelemetryForwarderProvider)_componentHost.GetComponent(BuildComponentType.TelemetryForwarder)) - ?.Instance; + ITelemetryCollector telemetryCollector = _nodeLoggingContext?.TelemetryCollector; - if (telemetryForwarder == null || !telemetryForwarder.IsTelemetryCollected) + if (telemetryCollector is null || !telemetryCollector.IsTelemetryCollected) { return; } @@ -1316,9 +1314,6 @@ private void UpdateStatisticsPostBuild() return; } - // Accumulate all telemetry into a local instance, then merge into the shared singleton once. - WorkerNodeTelemetryData telemetryData = new(); - foreach (var projectTargetInstance in _requestEntry.RequestConfiguration.Project.Targets) { bool wasExecuted = @@ -1351,14 +1346,12 @@ private void UpdateStatisticsPostBuild() var key = new TaskOrTargetTelemetryKey( projectTargetInstance.Key, isCustom, isFromNuget, isMetaprojTarget); - telemetryData.AddTarget(key, wasExecuted, skipReason); + telemetryCollector.AddTarget(key, wasExecuted, skipReason); } TaskRegistry taskReg = _requestEntry.RequestConfiguration.Project.TaskRegistry; CollectTasksStats(taskReg); - telemetryForwarder.MergeWorkerData(telemetryData); - void CollectTasksStats(TaskRegistry taskRegistry) { if (taskRegistry == null) @@ -1373,7 +1366,7 @@ void CollectTasksStats(TaskRegistry taskRegistry) registeredTaskRecord.ComputeIfCustom(), registeredTaskRecord.IsFromNugetCache, isFromMetaProject: false); - telemetryData.AddTask( + telemetryCollector.AddTask( key, registeredTaskRecord.Statistics.ExecutedTime, registeredTaskRecord.Statistics.ExecutedCount, diff --git a/src/msbuild/src/Build/BackEnd/Node/OutOfProcServerNode.cs b/src/msbuild/src/Build/BackEnd/Node/OutOfProcServerNode.cs index afda1281ee09..bd7e295104ca 100644 --- a/src/msbuild/src/Build/BackEnd/Node/OutOfProcServerNode.cs +++ b/src/msbuild/src/Build/BackEnd/Node/OutOfProcServerNode.cs @@ -340,7 +340,7 @@ private void HandleServerShutdownCommand(NodeBuildComplete buildComplete) private void HandleBuildCancel() { - CommunicationsUtilities.Trace("Received request to cancel build running on MSBuild Server. MSBuild server will shutdown.}"); + CommunicationsUtilities.Trace("Received request to cancel build running on MSBuild Server. MSBuild server will shutdown."); _cancelRequested = true; BuildManager.DefaultBuildManager.CancelAllSubmissions(); } diff --git a/src/msbuild/src/Build/Microsoft.Build.csproj b/src/msbuild/src/Build/Microsoft.Build.csproj index 570acca36835..1ba4d5053e32 100644 --- a/src/msbuild/src/Build/Microsoft.Build.csproj +++ b/src/msbuild/src/Build/Microsoft.Build.csproj @@ -181,8 +181,8 @@ - - + + diff --git a/src/msbuild/src/Build/TelemetryInfra/ITelemetryCollector.cs b/src/msbuild/src/Build/TelemetryInfra/ITelemetryCollector.cs new file mode 100644 index 000000000000..7593f345e970 --- /dev/null +++ b/src/msbuild/src/Build/TelemetryInfra/ITelemetryCollector.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Microsoft.Build.BackEnd.Logging; +using Microsoft.Build.Framework; +using Microsoft.Build.Framework.Telemetry; + +namespace Microsoft.Build.TelemetryInfra; + +/// +/// Collects task and target telemetry for a single BuildRequestEngine's lifetime. +/// Not thread-safe: only one RequestBuilder is active at a time per +/// BuildRequestEngine, so and +/// are always called from a single thread. +/// Created per BuildRequestEngine by . +/// +internal interface ITelemetryCollector +{ + bool IsTelemetryCollected { get; } + + void AddTarget(TaskOrTargetTelemetryKey key, bool wasExecuted, TargetSkipReason skipReason = TargetSkipReason.None); + + void AddTask( + TaskOrTargetTelemetryKey key, + TimeSpan cumulativeExecutionTime, + int executionsCount, + long totalMemoryConsumed, + string? taskFactoryName, + string? taskHostRuntime); + + /// + /// Sends accumulated telemetry as a and resets for the next build. + /// + void FinalizeProcessing(LoggingContext loggingContext); +} diff --git a/src/msbuild/src/Build/TelemetryInfra/ITelemetryForwarder.cs b/src/msbuild/src/Build/TelemetryInfra/ITelemetryForwarder.cs deleted file mode 100644 index 18000c482804..000000000000 --- a/src/msbuild/src/Build/TelemetryInfra/ITelemetryForwarder.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Build.BackEnd.Logging; -using Microsoft.Build.Framework.Telemetry; - -namespace Microsoft.Build.TelemetryInfra; - -/// -/// A build component responsible for accumulating telemetry data from worker node and then sending it to main node -/// at the end of the build. -/// -internal interface ITelemetryForwarder -{ - bool IsTelemetryCollected { get; } - - /// - /// Merges a batch of telemetry data into this forwarder's accumulated state. - /// - void MergeWorkerData(IWorkerNodeTelemetryData data); - - /// - /// Sends accumulated telemetry and resets internal state. - /// - void FinalizeProcessing(LoggingContext loggingContext); -} diff --git a/src/msbuild/src/Build/TelemetryInfra/TelemetryCollectorProvider.cs b/src/msbuild/src/Build/TelemetryInfra/TelemetryCollectorProvider.cs new file mode 100644 index 000000000000..0c5aa8b958c6 --- /dev/null +++ b/src/msbuild/src/Build/TelemetryInfra/TelemetryCollectorProvider.cs @@ -0,0 +1,93 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Microsoft.Build.BackEnd; +using Microsoft.Build.BackEnd.Logging; +using Microsoft.Build.Framework; +using Microsoft.Build.Framework.Telemetry; +using Microsoft.Build.Shared; + +namespace Microsoft.Build.TelemetryInfra; + +/// +/// Build component that creates per-BuildRequestEngine instances. +/// Registered as a singleton, but holds no mutable state — each BuildRequestEngine gets its own +/// collector via . +/// +internal class TelemetryCollectorProvider : IBuildComponent +{ + private bool _telemetryEnabled; + + /// + /// Creates a new scoped to one 's build lifetime. + /// Returns a no-op collector when telemetry is disabled. + /// + internal ITelemetryCollector CreateCollector() + => _telemetryEnabled ? new TelemetryCollector() : NullTelemetryCollector.Instance; + + internal static IBuildComponent CreateComponent(BuildComponentType type) + { + ErrorUtilities.VerifyThrow(type == BuildComponentType.TelemetryCollector, "Cannot create components of type {0}", type); + return new TelemetryCollectorProvider(); + } + + public void InitializeComponent(IBuildComponentHost host) + { + ErrorUtilities.VerifyThrow(host != null, "BuildComponentHost was null"); + _telemetryEnabled = host!.BuildParameters.IsTelemetryEnabled; + } + + public void ShutdownComponent() + { + } + + /// + /// Collects task/target telemetry for one BuildRequestEngine. Not thread-safe — + /// only one RequestBuilder is active at a time per BuildRequestEngine. + /// + internal class TelemetryCollector : ITelemetryCollector + { + private WorkerNodeTelemetryData _data = new(); + + public bool IsTelemetryCollected => true; + + public void AddTarget(TaskOrTargetTelemetryKey key, bool wasExecuted, TargetSkipReason skipReason = TargetSkipReason.None) + { + _data.AddTarget(key, wasExecuted, skipReason); + } + + public void AddTask(TaskOrTargetTelemetryKey key, TimeSpan cumulativeExecutionTime, int executionsCount, long totalMemoryConsumed, string? taskFactoryName, string? taskHostRuntime) + { + _data.AddTask(key, cumulativeExecutionTime, executionsCount, totalMemoryConsumed, taskFactoryName, taskHostRuntime); + } + + public void FinalizeProcessing(LoggingContext loggingContext) + { + if (_data.IsEmpty) + { + return; + } + + WorkerNodeTelemetryData snapshot = _data; + _data = new(); + + WorkerNodeTelemetryEventArgs telemetryArgs = new(snapshot) + { BuildEventContext = loggingContext.BuildEventContext }; + loggingContext.LogBuildEvent(telemetryArgs); + } + } + + internal class NullTelemetryCollector : ITelemetryCollector + { + internal static readonly NullTelemetryCollector Instance = new(); + + public bool IsTelemetryCollected => false; + + public void AddTarget(TaskOrTargetTelemetryKey key, bool wasExecuted, TargetSkipReason skipReason = TargetSkipReason.None) { } + + public void AddTask(TaskOrTargetTelemetryKey key, TimeSpan cumulativeExecutionTime, int executionsCount, long totalMemoryConsumed, string? taskFactoryName, string? taskHostRuntime) { } + + public void FinalizeProcessing(LoggingContext loggingContext) { } + } +} diff --git a/src/msbuild/src/Build/TelemetryInfra/TelemetryForwarderProvider.cs b/src/msbuild/src/Build/TelemetryInfra/TelemetryForwarderProvider.cs deleted file mode 100644 index dd851779bd93..000000000000 --- a/src/msbuild/src/Build/TelemetryInfra/TelemetryForwarderProvider.cs +++ /dev/null @@ -1,105 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Build.BackEnd; -using Microsoft.Build.BackEnd.Logging; -using Microsoft.Build.Framework.Telemetry; -using Microsoft.Build.Shared; - -namespace Microsoft.Build.TelemetryInfra; - -/// -/// A build component responsible for accumulating telemetry data from worker node and then sending it to main node -/// at the end of the build. -/// -internal class TelemetryForwarderProvider : IBuildComponent -{ - private ITelemetryForwarder? _instance; - - public ITelemetryForwarder Instance => _instance ?? new NullTelemetryForwarder(); - - internal static IBuildComponent CreateComponent(BuildComponentType type) - { - ErrorUtilities.VerifyThrow(type == BuildComponentType.TelemetryForwarder, "Cannot create components of type {0}", type); - return new TelemetryForwarderProvider(); - } - - public void InitializeComponent(IBuildComponentHost host) - { - ErrorUtilities.VerifyThrow(host != null, "BuildComponentHost was null"); - - if (_instance == null) - { - if (host!.BuildParameters.IsTelemetryEnabled) - { - _instance = new TelemetryForwarder(); - } - else - { - _instance = new NullTelemetryForwarder(); - } - } - } - - public void ShutdownComponent() - { - /* Too late here for any communication to the main node or for logging anything. Just cleanup. */ - _instance = null; - } - - /// - /// Active telemetry forwarder that accumulates worker node telemetry. - /// - /// - /// Thread-safe: in /m /mt mode, multiple instances share a single - /// singleton, so and - /// may be called concurrently from different node threads. - /// - public class TelemetryForwarder : ITelemetryForwarder - { - private WorkerNodeTelemetryData _workerNodeTelemetryData = new(); - private readonly LockType _lock = new(); - - // in future, this might be per event type - public bool IsTelemetryCollected => true; - - public void MergeWorkerData(IWorkerNodeTelemetryData data) - { - lock (_lock) - { - _workerNodeTelemetryData.Add(data); - } - } - - - public void FinalizeProcessing(LoggingContext loggingContext) - { - WorkerNodeTelemetryData snapshot; - - lock (_lock) - { - // Nothing accumulated since the last call — skip sending. - if (_workerNodeTelemetryData.IsEmpty) - { - return; - } - - snapshot = _workerNodeTelemetryData; - _workerNodeTelemetryData = new(); - } - - WorkerNodeTelemetryEventArgs telemetryArgs = new(snapshot) - { BuildEventContext = loggingContext.BuildEventContext }; - loggingContext.LogBuildEvent(telemetryArgs); - } - } - - public class NullTelemetryForwarder : ITelemetryForwarder - { - public bool IsTelemetryCollected => false; - - public void MergeWorkerData(IWorkerNodeTelemetryData data) { } - - public void FinalizeProcessing(LoggingContext loggingContext) { } - } -} diff --git a/src/msbuild/src/Build/Utilities/Utilities.cs b/src/msbuild/src/Build/Utilities/Utilities.cs index e1ad5e06aae6..19ca4e2aa3ce 100644 --- a/src/msbuild/src/Build/Utilities/Utilities.cs +++ b/src/msbuild/src/Build/Utilities/Utilities.cs @@ -194,12 +194,21 @@ internal static string GetXmlNodeInnerContents(XmlElementWithLocation node) // XmlNode.InnerXml is much more expensive than InnerText. Don't use it for trivial cases. // (single child node with a trivial value or no child nodes) - if (!node.HasChildNodes || (node.ChildNodes.Count == 1 && node.FirstChild.NodeType == XmlNodeType.Whitespace)) + // Avoid accessing node.ChildNodes -- it allocates a new XmlChildNodes wrapper on every call. + // Use FirstChild/NextSibling linked-list traversal instead (allocation-free). + XmlNode firstChild = node.FirstChild; + if (firstChild is null) { return String.Empty; } - if (node.ChildNodes.Count == 1 && (node.FirstChild.NodeType == XmlNodeType.Text || node.FirstChild.NodeType == XmlNodeType.CDATA)) + bool isSingleChild = firstChild.NextSibling is null; + if (isSingleChild && firstChild.NodeType == XmlNodeType.Whitespace) + { + return String.Empty; + } + + if (isSingleChild && (firstChild.NodeType == XmlNodeType.Text || firstChild.NodeType == XmlNodeType.CDATA)) { return node.InnerText; } diff --git a/src/msbuild/src/BuildCheck.UnitTests/BuildCheckManagerProviderTests.cs b/src/msbuild/src/BuildCheck.UnitTests/BuildCheckManagerProviderTests.cs index 1cd861e4c980..1f24fe1934fd 100644 --- a/src/msbuild/src/BuildCheck.UnitTests/BuildCheckManagerProviderTests.cs +++ b/src/msbuild/src/BuildCheck.UnitTests/BuildCheckManagerProviderTests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.Experimental.BuildCheck.Infrastructure.BuildCheckManagerProvider; namespace Microsoft.Build.BuildCheck.UnitTests; diff --git a/src/msbuild/src/BuildCheck.UnitTests/EndToEndTests.cs b/src/msbuild/src/BuildCheck.UnitTests/EndToEndTests.cs index 82472057d0f7..646dc27984f6 100644 --- a/src/msbuild/src/BuildCheck.UnitTests/EndToEndTests.cs +++ b/src/msbuild/src/BuildCheck.UnitTests/EndToEndTests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.BuildCheck.UnitTests; diff --git a/src/msbuild/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs b/src/msbuild/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs index 10e6a9fcf9c2..12b3f4e3a82c 100644 --- a/src/msbuild/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs +++ b/src/msbuild/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; using static Microsoft.Build.Experimental.BuildCheck.Infrastructure.BuildCheckManagerProvider; namespace Microsoft.Build.BuildCheck.UnitTests diff --git a/src/msbuild/src/Directory.Build.targets b/src/msbuild/src/Directory.Build.targets index 6314d701be8b..7e0d7109693e 100644 --- a/src/msbuild/src/Directory.Build.targets +++ b/src/msbuild/src/Directory.Build.targets @@ -2,8 +2,6 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - true @@ -18,32 +16,28 @@ - - Exe - false + + $(XunitOptions) --filter-not-trait Category=nonwindowstests - - $(XunitOptions) + $(XunitOptions) --filter-not-trait Category=nonlinuxtests + $(XunitOptions) --filter-not-trait Category=netcore-linux-failing + + $(XunitOptions) --filter-not-trait Category=nonosxtests + $(XunitOptions) --filter-not-trait Category=netcore-osx-failing - - $(XunitOptions) --filter "Category!=nonwindowstests - $(XunitOptions) --filter "Category!=nonlinuxtests - --filter "Category!=nonlinuxtests&Category!=netcore-linux-failing - $(XunitOptions) --filter "Category!=nonosxtests - --filter "Category!=nonosxtests&Category!=netcore-osx-failing - $(XunitOptions) --filter "Category!=nonfreebsdtests + $(XunitOptions) --filter-not-trait Category=nonfreebsdtests - $(XunitOptions)&Category!=nonnetcoreapptests - $(XunitOptions)&Category!=nonnetfxtests + $(XunitOptions) --filter-not-trait Category=nonnetcoreapptests + $(XunitOptions) --filter-not-trait Category=nonnetfxtests - $(XunitOptions)&Category!=failing" --Diag $(TargetName).log + $(XunitOptions) --filter-not-trait Category=failing - - $(XunitOptions) --settings $(RepoRoot)Coverage.runsettings --test-adapter-path $(NuGetPackageRoot)microsoft.codecoverage/18.0.0-preview-25479-103/build/netstandard2.0 + + $(XunitOptions) --coverage --coverage-settings $(RepoRoot)Coverage.config $(XunitOptions) @@ -59,13 +53,13 @@ 9.0.1, causing it to be downloaded and flagged by component governance --> - + + - @@ -85,10 +79,6 @@ netstandard - - - - diff --git a/src/msbuild/src/Framework.UnitTests/AbsolutePath_Tests.cs b/src/msbuild/src/Framework.UnitTests/AbsolutePath_Tests.cs index a78f6c17b370..09a87b60b096 100644 --- a/src/msbuild/src/Framework.UnitTests/AbsolutePath_Tests.cs +++ b/src/msbuild/src/Framework.UnitTests/AbsolutePath_Tests.cs @@ -236,13 +236,11 @@ public void AbsolutePath_UnixPathValidation_ShouldAcceptOnlyTrueAbsolutePaths(st } [Fact] - public void GetCanonicalForm_NullPath_ShouldReturnSameInstance() + public void GetCanonicalForm_NullPath_ShouldThrow() { var absolutePath = new AbsolutePath(null!, null!, ignoreRootedCheck: true); - var result = absolutePath.GetCanonicalForm(); - // Should return the same struct values when no normalization is needed - result.ShouldBe(absolutePath); + Should.Throw(() => absolutePath.GetCanonicalForm()); } @@ -283,6 +281,26 @@ private static void ValidateGetCanonicalFormMatchesSystem(string inputPath) result.OriginalValue.ShouldBe(absolutePath.OriginalValue); } + [Fact] + public void GetCanonicalForm_InvalidPathCharacters_ShouldThrowSameAsPathGetFullPath() + { + // A path containing a null character is invalid on all platforms. + // Path.GetFullPath throws for this input; GetCanonicalForm should too. + // Construct the path string directly to avoid Path.Combine throwing on .NET Framework. + string invalidPath = Path.GetTempPath() + "foo\0bar"; + var absolutePath = new AbsolutePath(invalidPath, ignoreRootedCheck: true); + + // Capture the exception that Path.GetFullPath would throw + Exception? getFullPathException = Record.Exception(() => Path.GetFullPath(invalidPath)); + + getFullPathException.ShouldNotBeNull("Path.GetFullPath should throw for a path with null character"); + + // GetCanonicalForm should throw the same exception type + Should.Throw( + () => absolutePath.GetCanonicalForm(), + getFullPathException.GetType()); + } + [WindowsOnlyFact] [UseInvariantCulture] public void AbsolutePath_NotRooted_ShouldThrowWithLocalizedMessage() diff --git a/src/msbuild/src/Framework.UnitTests/FileMatcher_Tests.cs b/src/msbuild/src/Framework.UnitTests/FileMatcher_Tests.cs index c0bea9729652..1ec9c7750a80 100644 --- a/src/msbuild/src/Framework.UnitTests/FileMatcher_Tests.cs +++ b/src/msbuild/src/Framework.UnitTests/FileMatcher_Tests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Framework.UnitTests/FileUtilities_Tests.cs b/src/msbuild/src/Framework.UnitTests/FileUtilities_Tests.cs index e276e9ebad4f..4160ab4551ac 100644 --- a/src/msbuild/src/Framework.UnitTests/FileUtilities_Tests.cs +++ b/src/msbuild/src/Framework.UnitTests/FileUtilities_Tests.cs @@ -549,11 +549,14 @@ public void FileOrDirectoryExistsNoThrow() } #if FEATURE_ENVIRONMENT_SYSTEMDIRECTORY - // These tests will need to be redesigned for Linux - - [ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))] + [Fact] public void FileOrDirectoryExistsNoThrowTooLongWithDots() { + if (!RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241()) + { + Assert.Skip("These tests will need to be redesigned for Linux"); + } + int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3)).Length; string longPart = new string('x', 260 - length); // We want the shortest that is > max path. @@ -566,9 +569,14 @@ public void FileOrDirectoryExistsNoThrowTooLongWithDots() Assert.False(FileUtilities.FileOrDirectoryExistsNoThrow(inputPath.Replace('\\', 'X'))); } - [ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))] + [Fact] public void FileOrDirectoryExistsNoThrowTooLongWithDotsRelative() { + if (!RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241()) + { + Assert.Skip("These tests will need to be redesigned for Linux"); + } + int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3)).Length; string longPart = new string('x', 260 - length); // We want the shortest that is > max path. @@ -619,9 +627,14 @@ public void DirectoryExistsNoThrowTooLongWithDots() Assert.True(FileUtilities.DirectoryExistsNoThrow(inputPath)); } - [ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))] + [Fact] public void DirectoryExistsNoThrowTooLongWithDotsRelative() { + if (!RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241()) + { + Assert.Skip("These tests will need to be redesigned for Linux"); + } + int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3)).Length; string longPart = new string('x', 260 - length); // We want the shortest that is > max path. @@ -655,9 +668,14 @@ public static bool RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241() NativeMethodsShared.IsMaxPathLegacyWindows(); } - [ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))] + [Fact] public void FileExistsNoThrowTooLongWithDots() { + if (!RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241()) + { + Assert.Skip("These tests will need to be redesigned for Linux"); + } + int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe").Length; string longPart = new string('x', 260 - length); // We want the shortest that is > max path. @@ -670,9 +688,14 @@ public void FileExistsNoThrowTooLongWithDots() Assert.True(FileUtilities.FileExistsNoThrow(inputPath)); } - [ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))] + [Fact] public void FileExistsNoThrowTooLongWithDotsRelative() { + if (!RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241()) + { + Assert.Skip("These tests will need to be redesigned for Linux"); + } + int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe").Length; string longPart = new string('x', 260 - length); // We want the shortest that is > max path. diff --git a/src/msbuild/src/Framework/PathHelpers/AbsolutePath.cs b/src/msbuild/src/Framework/PathHelpers/AbsolutePath.cs index 24a3a9266157..59d08dc102f1 100644 --- a/src/msbuild/src/Framework/PathHelpers/AbsolutePath.cs +++ b/src/msbuild/src/Framework/PathHelpers/AbsolutePath.cs @@ -120,74 +120,28 @@ public AbsolutePath(string path, AbsolutePath basePath) public static implicit operator string(AbsolutePath path) => path.Value; /// - /// Returns the canonical form of this path. + /// Returns the canonical form of this path, equivalent to calling . /// /// /// An representing the canonical form of the path. /// /// /// - /// The canonical form of a path is exactly what would produce, + /// The canonical form of a path is exactly what would produce, /// with the following properties: /// /// All relative path segments ("." and "..") are resolved. /// Directory separators are normalized to the platform convention (backslash on Windows). + /// Invalid path characters are rejected. /// /// /// - /// If the path is already in canonical form, returns the current instance to avoid unnecessary allocations. /// Preserves the OriginalValue of the current instance. /// /// internal AbsolutePath GetCanonicalForm() { - if (string.IsNullOrEmpty(Value)) - { - return this; - } - - if (ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave18_6)) - { - // Note: this is a quick check to avoid calling Path.GetFullPath when it's not necessary, since it can be expensive. - // It should cover the most common cases and avoid the overhead of Path.GetFullPath in those cases. - - // Check for relative path segments "." and ".." - // In absolute path those segments can not appear in the beginning of the path, only after a path separator. - // This is not a precise full detection of relative segments. There is no false negatives as this might affect correctenes, but it may have false positives: - // like when there is a hidden file or directory starting with a dot, or on linux the backslash and dot can be part of the file name. - // In case of false positives we would call Path.GetFullPath and the result would still be correct. - - bool hasRelativeSegment = Value.Contains("/.") || Value.Contains("\\."); - - // Check if directory separator normalization is required (only on Windows: "/" to "\") - // On unix "\" is not a valid path separator, but is a part of the file/directory name, so no normalization is needed. - bool needsSeparatorNormalization = NativeMethods.IsWindows && Value.IndexOf(Path.AltDirectorySeparatorChar) >= 0; - - // Check for consecutive directory separators (e.g., "\\") which Path.GetFullPath would collapse. - // On Windows, consecutive backslashes in the middle of a path (not at the start for UNC) should be collapsed. - // On Unix, consecutive forward slashes should be collapsed. - bool hasConsecutiveSeparators; - if (NativeMethods.IsWindows) - { - // On Windows, search from offset 1 to skip position 0 where UNC paths legitimately start with "\\". - // This still catches cases like "C:\\foo" (positions 2-3) or "D:\foo\\bar". - // Length > 3 guard: searching for 2-char match from offset 1 needs at least 4 chars. - hasConsecutiveSeparators = Value.Length > 3 && Value.IndexOf("\\\\", 1, StringComparison.Ordinal) >= 0; - } - else - { - hasConsecutiveSeparators = Value.Contains("//"); - } - - if (!hasRelativeSegment && !needsSeparatorNormalization && !hasConsecutiveSeparators) - { - return this; - } - } - - // Use Path.GetFullPath to resolve relative segments and normalize separators. - // Skip validation since Path.GetFullPath already ensures the result is absolute. - return new AbsolutePath(Path.GetFullPath(Value), OriginalValue, ignoreRootedCheck: true); + return new AbsolutePath(System.IO.Path.GetFullPath(Value), OriginalValue, ignoreRootedCheck: true); } /// diff --git a/src/msbuild/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs b/src/msbuild/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs index 3e81301cd915..139bf827117d 100644 --- a/src/msbuild/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs +++ b/src/msbuild/src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs @@ -1133,6 +1133,7 @@ public void ParameterizedSwitchTargetQuotedChangeWaveTest() using (TestEnvironment env = TestEnvironment.Create()) { env.SetEnvironmentVariable("MSBUILDDISABLEFEATURESFROMVERSION", "17.10"); + ChangeWaves.ResetStateForTests(); CommandLineSwitches switches = new CommandLineSwitches(); switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:Clean;Build", "\"Clean;Build\"", true, true, false); diff --git a/src/msbuild/src/MSBuild.UnitTests/MSBuildMultithreaded_Tests.cs b/src/msbuild/src/MSBuild.UnitTests/MSBuildMultithreaded_Tests.cs index 3b932d389247..4557bdddab88 100644 --- a/src/msbuild/src/MSBuild.UnitTests/MSBuildMultithreaded_Tests.cs +++ b/src/msbuild/src/MSBuild.UnitTests/MSBuildMultithreaded_Tests.cs @@ -10,7 +10,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Engine.UnitTests { diff --git a/src/msbuild/src/MSBuild.UnitTests/MSBuildServer_Tests.cs b/src/msbuild/src/MSBuild.UnitTests/MSBuildServer_Tests.cs index 6272a8743893..1531c665f546 100644 --- a/src/msbuild/src/MSBuild.UnitTests/MSBuildServer_Tests.cs +++ b/src/msbuild/src/MSBuild.UnitTests/MSBuildServer_Tests.cs @@ -20,7 +20,6 @@ #endif using Shouldly; using Xunit; -using Xunit.Abstractions; using Path = System.IO.Path; namespace Microsoft.Build.Engine.UnitTests diff --git a/src/msbuild/src/MSBuild.UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj b/src/msbuild/src/MSBuild.UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj index c6926ff83b08..2e85ead1777b 100644 --- a/src/msbuild/src/MSBuild.UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj +++ b/src/msbuild/src/MSBuild.UnitTests/Microsoft.Build.CommandLine.UnitTests.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/msbuild/src/MSBuild.UnitTests/PerfLog_Tests.cs b/src/msbuild/src/MSBuild.UnitTests/PerfLog_Tests.cs index eadb3226199d..87b2ae9bf10c 100644 --- a/src/msbuild/src/MSBuild.UnitTests/PerfLog_Tests.cs +++ b/src/msbuild/src/MSBuild.UnitTests/PerfLog_Tests.cs @@ -5,7 +5,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/MSBuild.UnitTests/XMake_BinlogSwitch_Tests.cs b/src/msbuild/src/MSBuild.UnitTests/XMake_BinlogSwitch_Tests.cs index af764f80e36a..a6aba9a1f5fa 100644 --- a/src/msbuild/src/MSBuild.UnitTests/XMake_BinlogSwitch_Tests.cs +++ b/src/msbuild/src/MSBuild.UnitTests/XMake_BinlogSwitch_Tests.cs @@ -9,7 +9,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/MSBuild.UnitTests/XMake_Tests.cs b/src/msbuild/src/MSBuild.UnitTests/XMake_Tests.cs index 0941af26946b..9ba8009acbd0 100644 --- a/src/msbuild/src/MSBuild.UnitTests/XMake_Tests.cs +++ b/src/msbuild/src/MSBuild.UnitTests/XMake_Tests.cs @@ -22,10 +22,8 @@ using Microsoft.Build.Tasks; using Microsoft.Build.UnitTests.Shared; using Microsoft.Build.Utilities; -using Microsoft.VisualStudio.TestPlatform.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/MSBuild/app.amd64.config b/src/msbuild/src/MSBuild/app.amd64.config index 33d92cceb94b..12e9051dbf9a 100644 --- a/src/msbuild/src/MSBuild/app.amd64.config +++ b/src/msbuild/src/MSBuild/app.amd64.config @@ -1,4 +1,4 @@ - +
@@ -62,18 +62,18 @@ - - + + - - + + - - + + @@ -103,8 +103,8 @@ - - + + @@ -122,18 +122,18 @@ - - + + - - + + - - + + @@ -142,23 +142,23 @@ - - + + - - + + - - + + - - + + diff --git a/src/msbuild/src/MSBuild/app.config b/src/msbuild/src/MSBuild/app.config index c323abcf1b25..75e98e2a2d58 100644 --- a/src/msbuild/src/MSBuild/app.config +++ b/src/msbuild/src/MSBuild/app.config @@ -1,4 +1,4 @@ - +
@@ -33,7 +33,7 @@ - + @@ -58,15 +58,15 @@ - + - + - + @@ -78,15 +78,15 @@ - + - + - + @@ -94,19 +94,19 @@ - + - + - + - + diff --git a/src/msbuild/src/Shared/UnitTests/TestAssemblyInfo.cs b/src/msbuild/src/Shared/UnitTests/TestAssemblyInfo.cs index 2654f8f55c8f..785e8243aa81 100644 --- a/src/msbuild/src/Shared/UnitTests/TestAssemblyInfo.cs +++ b/src/msbuild/src/Shared/UnitTests/TestAssemblyInfo.cs @@ -2,9 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using Microsoft.Build.Framework; @@ -13,39 +17,179 @@ using Microsoft.Build.UnitTests; using Microsoft.Build.UnitTests.Shared; using Xunit; +using Xunit.NetCore.Extensions; +using Xunit.Sdk; +using Xunit.v3; #nullable disable [assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] -// Register test framework for assembly fixture -[assembly: TestFramework("Xunit.NetCore.Extensions.XunitTestFrameworkWithAssemblyFixture", "Xunit.NetCore.Extensions")] - -[assembly: AssemblyFixture(typeof(MSBuildTestAssemblyFixture))] +[assembly: TestPipelineStartup(typeof(MSBuildTestPipelineStartup))] // Wrap a TestEnvironment around each test method and class so if invariants have changed we will know where -[assembly: AssemblyFixture(typeof(MSBuildTestEnvironmentFixture), LifetimeScope = AssemblyFixtureAttribute.Scope.Class)] -[assembly: AssemblyFixture(typeof(MSBuildTestEnvironmentFixture), LifetimeScope = AssemblyFixtureAttribute.Scope.Method)] +[assembly: TestFramework(typeof(MSBuildTestFramework))] namespace Microsoft.Build.UnitTests { - public class MSBuildTestAssemblyFixture : IDisposable + public class MSBuildTestFramework : XunitTestFramework + { + private sealed class MSBuildDiscoverer : ITestFrameworkDiscoverer + { + private readonly ITestFrameworkDiscoverer _wrapped; + + public MSBuildDiscoverer(ITestFrameworkDiscoverer wrapped) + => _wrapped = wrapped; + + public ITestAssembly TestAssembly => _wrapped.TestAssembly; + + public ValueTask Find(Func> callback, ITestFrameworkDiscoveryOptions discoveryOptions, Type[] types = null, CancellationToken? cancellationToken = null) + => _wrapped.Find(testCase => callback(new MSBuildTestCase((IXunitTestCase)testCase)), discoveryOptions, types, cancellationToken); + } + + private sealed class MSBuildTestCase : IXunitTestCase, ISelfExecutingXunitTestCase, IXunitSerializable + { + private IXunitTestCase _wrapped; + + [Obsolete("Called by the de-serializer; should only be called for de-serialization purposes")] + public MSBuildTestCase() + { + } + + public MSBuildTestCase(IXunitTestCase wrapped) + => _wrapped = wrapped; + + public Type[] SkipExceptions => _wrapped.SkipExceptions; + + public string SkipReason => _wrapped.SkipReason; + + public Type SkipType => _wrapped.SkipType; + + public string SkipUnless => _wrapped.SkipUnless; + + public string SkipWhen => _wrapped.SkipWhen; + + public IXunitTestClass TestClass => _wrapped.TestClass; + + public int TestClassMetadataToken => _wrapped.TestClassMetadataToken; + + public string TestClassName => _wrapped.TestClassName; + + public string TestClassSimpleName => _wrapped.TestClassSimpleName; + + public IXunitTestCollection TestCollection => _wrapped.TestCollection; + + public IXunitTestMethod TestMethod => _wrapped.TestMethod; + + public int TestMethodMetadataToken => _wrapped.TestMethodMetadataToken; + + public string TestMethodName => _wrapped.TestMethodName; + + public string[] TestMethodParameterTypesVSTest => _wrapped.TestMethodParameterTypesVSTest; + + public string TestMethodReturnTypeVSTest => _wrapped.TestMethodReturnTypeVSTest; + + public int Timeout => _wrapped.Timeout; + + public bool Explicit => _wrapped.Explicit; + + public string SourceFilePath => _wrapped.SourceFilePath; + + public int? SourceLineNumber => _wrapped.SourceLineNumber; + + public string TestCaseDisplayName => _wrapped.TestCaseDisplayName; + + public string TestClassNamespace => _wrapped.TestClassNamespace; + + public int? TestMethodArity => _wrapped.TestMethodArity; + + public IReadOnlyDictionary> Traits => _wrapped.Traits; + + public string UniqueID => _wrapped.UniqueID; + + ITestClass ITestCase.TestClass => TestClass; + + ITestCollection ITestCase.TestCollection => TestCollection; + + ITestMethod ITestCase.TestMethod => TestMethod; + + int? ITestCaseMetadata.TestClassMetadataToken => TestClassMetadataToken; + + int? ITestCaseMetadata.TestMethodMetadataToken => TestMethodMetadataToken; + + public ValueTask> CreateTests() => _wrapped.CreateTests(); + + public void PostInvoke() + { + Assert.True(BuildEnvironmentState.s_runningTests); + _wrapped.PostInvoke(); + Assert.True(BuildEnvironmentState.s_runningTests); + } + + public void PreInvoke() + { + Assert.True(BuildEnvironmentState.s_runningTests); + _wrapped.PreInvoke(); + Assert.True(BuildEnvironmentState.s_runningTests); + } + + public async ValueTask Run(ExplicitOption explicitOption, IMessageBus messageBus, object[] constructorArguments, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) + { + using var _ = TestEnvironment.Create(); +#if !IS_OM_TESTS + string initialHandshakeSalt = Framework.Traits.MSBuildNodeHandshakeSalt; + bool initialLogAllEnvVariables = Framework.Traits.LogAllEnvironmentVariables; +#endif + Assert.True(BuildEnvironmentState.s_runningTests); + try + { + return await XunitRunnerHelper.RunXunitTestCase( + this, + messageBus, + cancellationTokenSource, + aggregator, + explicitOption, + constructorArguments); + } + finally + { + Assert.True(BuildEnvironmentState.s_runningTests); +#if !IS_OM_TESTS + Assert.Equal(initialHandshakeSalt, Framework.Traits.MSBuildNodeHandshakeSalt); + Assert.Equal(initialLogAllEnvVariables, Framework.Traits.LogAllEnvironmentVariables); +#endif + } + } + + public void Serialize(IXunitSerializationInfo info) + => info.AddValue("wr", _wrapped); + + public void Deserialize(IXunitSerializationInfo info) + => _wrapped = info.GetValue("wr"); + } + + protected override ITestFrameworkDiscoverer CreateDiscoverer(Assembly assembly) => new MSBuildDiscoverer(base.CreateDiscoverer(assembly)); + + protected override ITestFrameworkExecutor CreateExecutor(Assembly assembly) => base.CreateExecutor(assembly); + } + + public class MSBuildTestPipelineStartup : ITestPipelineStartup { private bool _disposed; private TestEnvironment _testEnvironment; - public MSBuildTestAssemblyFixture() + public MSBuildTestPipelineStartup() { // Set field to indicate tests are running in the TestInfo class in Microsoft.Build.Framework. // See the comments on the TestInfo class for an explanation of why it works this way. - var frameworkAssembly = typeof(Microsoft.Build.Framework.ITask).Assembly; + var frameworkAssembly = typeof(ITask).Assembly; var testInfoType = frameworkAssembly.GetType("Microsoft.Build.Framework.TestInfo"); - var runningTestsField = testInfoType.GetField("s_runningTests", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); + var runningTestsField = testInfoType.GetField("s_runningTests", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); runningTestsField.SetValue(null, true); // Set the field in BuildEnvironmentState - as it might have been already preintialized by the data preparation of data driven tests testInfoType = frameworkAssembly.GetType("Microsoft.Build.Framework.BuildEnvironmentState"); - runningTestsField = testInfoType.GetField("s_runningTests", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); + runningTestsField = testInfoType.GetField("s_runningTests", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); runningTestsField.SetValue(null, true); // BuildEnvironment instance may be initialized in some tests' static members before s_runningTests is set @@ -110,8 +254,8 @@ public MSBuildTestAssemblyFixture() fileName: "Directory.Build.targets", contents: ""); } - - public void Dispose() + + public ValueTask StopAsync() { if (!_disposed) { @@ -119,27 +263,10 @@ public void Dispose() _disposed = true; } - } - } - - public class MSBuildTestEnvironmentFixture : IDisposable - { - private bool _disposed; - private TestEnvironment _testEnvironment; - public MSBuildTestEnvironmentFixture() - { - _testEnvironment = TestEnvironment.Create(); + return default; } - public void Dispose() - { - if (!_disposed) - { - _testEnvironment.Dispose(); - - _disposed = true; - } - } + public ValueTask StartAsync(IMessageSink diagnosticMessageSink) => default; } } diff --git a/src/msbuild/src/Shared/UnitTests/TestProgram.cs b/src/msbuild/src/Shared/UnitTests/TestProgram.cs deleted file mode 100644 index ecfb57805621..000000000000 --- a/src/msbuild/src/Shared/UnitTests/TestProgram.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; - -internal sealed class Program -{ - public static int Main(string[] args) - { -#if RUNTIME_TYPE_NETCORE - var newArgs = new List(args); - newArgs.Insert(0, typeof(Program).Assembly.Location); - - int returnCode = Xunit.ConsoleClient.Program.Main(newArgs.ToArray()); - - // if (showHelp) - // { - // TestCommandLine.ShowHelp(); - // } - - return returnCode; -#else - throw new NotImplementedException(); -#endif - } -} diff --git a/src/msbuild/src/Shared/UnitTests/TypeLoader_Tests.cs b/src/msbuild/src/Shared/UnitTests/TypeLoader_Tests.cs index 048ba6ceebd0..e691716847ee 100644 --- a/src/msbuild/src/Shared/UnitTests/TypeLoader_Tests.cs +++ b/src/msbuild/src/Shared/UnitTests/TypeLoader_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Shared/UnitTests/xunit.runner.json b/src/msbuild/src/Shared/UnitTests/xunit.runner.json index 2677ff464a7d..63779c51164a 100644 --- a/src/msbuild/src/Shared/UnitTests/xunit.runner.json +++ b/src/msbuild/src/Shared/UnitTests/xunit.runner.json @@ -1,7 +1,5 @@ { "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", - "shadowCopy": false, - "appDomain": "required", "longRunningTestSeconds": 60, "maxParallelThreads": 1, "parallelizeTestCollections": false, diff --git a/src/msbuild/src/StringTools.UnitTests/InterningTestData.cs b/src/msbuild/src/StringTools.UnitTests/InterningTestData.cs index 28fc95ac0e25..19f303d02994 100644 --- a/src/msbuild/src/StringTools.UnitTests/InterningTestData.cs +++ b/src/msbuild/src/StringTools.UnitTests/InterningTestData.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; - -using Xunit.Abstractions; +using Xunit.Sdk; #nullable disable diff --git a/src/msbuild/src/StringTools.UnitTests/StringTools.UnitTests.net35.csproj b/src/msbuild/src/StringTools.UnitTests/StringTools.UnitTests.net35.csproj index 7e01392da195..dc64fa15f1e0 100644 --- a/src/msbuild/src/StringTools.UnitTests/StringTools.UnitTests.net35.csproj +++ b/src/msbuild/src/StringTools.UnitTests/StringTools.UnitTests.net35.csproj @@ -10,6 +10,7 @@ true true true + Exe false diff --git a/src/msbuild/src/Tasks.UnitTests/AddToWin32Manifest_Tests.cs b/src/msbuild/src/Tasks.UnitTests/AddToWin32Manifest_Tests.cs index 78a8b68d00a7..a8ebc64a2258 100644 --- a/src/msbuild/src/Tasks.UnitTests/AddToWin32Manifest_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AddToWin32Manifest_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Tasks.UnitTests { diff --git a/src/msbuild/src/Tasks.UnitTests/Al_Tests.cs b/src/msbuild/src/Tasks.UnitTests/Al_Tests.cs index 72960a64e597..faaeea637ae1 100644 --- a/src/msbuild/src/Tasks.UnitTests/Al_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/Al_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AspNetCompiler_Tests.cs b/src/msbuild/src/Tasks.UnitTests/AspNetCompiler_Tests.cs index 0162f95c94db..e69f076a3970 100644 --- a/src/msbuild/src/Tasks.UnitTests/AspNetCompiler_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AspNetCompiler_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.Evaluation; using Microsoft.Build.Tasks; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs index fdda7956108e..e493b7d9b119 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/AssemblyFoldersFromConfig_Tests.cs @@ -9,7 +9,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/FilePrimary.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/FilePrimary.cs index 5f0d4ad6f1aa..a81f24fc6352 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/FilePrimary.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/FilePrimary.cs @@ -9,7 +9,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/GlobalAssemblyCacheTests.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/GlobalAssemblyCacheTests.cs index f320ee47e70b..b08a9c21a22f 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/GlobalAssemblyCacheTests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/GlobalAssemblyCacheTests.cs @@ -10,7 +10,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; using SystemProcessorArchitecture = System.Reflection.ProcessorArchitecture; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/InstalledSDKResolverFixture.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/InstalledSDKResolverFixture.cs index cdacfae192e4..6a214b373d8f 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/InstalledSDKResolverFixture.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/InstalledSDKResolverFixture.cs @@ -6,7 +6,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Miscellaneous.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Miscellaneous.cs index 669d367e140d..32a57278a7b5 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Miscellaneous.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Miscellaneous.cs @@ -17,7 +17,6 @@ using Microsoft.Win32; using Shouldly; using Xunit; -using Xunit.Abstractions; using FrameworkNameVersioning = System.Runtime.Versioning.FrameworkName; using SystemProcessorArchitecture = System.Reflection.ProcessorArchitecture; diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Node/OutOfProcRarNode_Tests.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Node/OutOfProcRarNode_Tests.cs index d3427ddeb7f6..56a62f79a80a 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Node/OutOfProcRarNode_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Node/OutOfProcRarNode_Tests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.UnitTests; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.UnitTests.ResolveAssemblyReference_Tests { diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/NonSpecificVersionStrictPrimary.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/NonSpecificVersionStrictPrimary.cs index 230080b2f31d..e445209045a8 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/NonSpecificVersionStrictPrimary.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/NonSpecificVersionStrictPrimary.cs @@ -7,7 +7,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Perf.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Perf.cs index 57cea08b1291..dccccf6f98f7 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Perf.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/Perf.cs @@ -9,7 +9,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ReferenceTests.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ReferenceTests.cs index 800790125d18..830f41cdacf6 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ReferenceTests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ReferenceTests.cs @@ -5,7 +5,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ResolveAssemblyReferenceTestFixture.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ResolveAssemblyReferenceTestFixture.cs index e6b39fd0e940..ee85b41f3838 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ResolveAssemblyReferenceTestFixture.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/ResolveAssemblyReferenceTestFixture.cs @@ -14,7 +14,6 @@ using Microsoft.Build.Utilities; using Microsoft.Win32; using Xunit; -using Xunit.Abstractions; using FrameworkNameVersioning = System.Runtime.Versioning.FrameworkName; using NativeMethods = Microsoft.Build.Tasks.NativeMethods; using SystemProcessorArchitecture = System.Reflection.ProcessorArchitecture; diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SpecificVersionPrimary.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SpecificVersionPrimary.cs index c11fc53cfccc..a7fb899d4f89 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SpecificVersionPrimary.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SpecificVersionPrimary.cs @@ -8,7 +8,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependency.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependency.cs index 1ef6412f3557..64ec1d5dae62 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependency.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependency.cs @@ -10,7 +10,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAppConfig.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAppConfig.cs index c4f0bd345106..90b8ff8caea4 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAppConfig.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAppConfig.cs @@ -9,7 +9,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAutoUnify.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAutoUnify.cs index eff546bcd3d5..e336ef4febde 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAutoUnify.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/StronglyNamedDependencyAutoUnify.cs @@ -9,7 +9,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SuggestedRedirects.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SuggestedRedirects.cs index 2dc93f2fe56d..d45e0ff7f38d 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SuggestedRedirects.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/SuggestedRedirects.cs @@ -11,7 +11,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyIgnoreVersionForFrameworkReference.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyIgnoreVersionForFrameworkReference.cs index 52277dbbd1fd..e6e5f93dd52a 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyIgnoreVersionForFrameworkReference.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyIgnoreVersionForFrameworkReference.cs @@ -6,7 +6,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkAttribute.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkAttribute.cs index 7d92fe9e6309..ced2b80ac2a7 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkAttribute.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkAttribute.cs @@ -6,7 +6,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkHigherThanRedist.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkHigherThanRedist.cs index 6435b8cddaad..9490dca55593 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkHigherThanRedist.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/VerifyTargetFrameworkHigherThanRedist.cs @@ -7,7 +7,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/WinMDTests.cs b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/WinMDTests.cs index 285438b81813..2f949c261ec9 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/WinMDTests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssemblyDependency/WinMDTests.cs @@ -9,7 +9,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/AssignProjectConfiguration_Tests.cs b/src/msbuild/src/Tasks.UnitTests/AssignProjectConfiguration_Tests.cs index 5a84c242c919..f8fe46f30b44 100644 --- a/src/msbuild/src/Tasks.UnitTests/AssignProjectConfiguration_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/AssignProjectConfiguration_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/Copy_Tests.cs b/src/msbuild/src/Tasks.UnitTests/Copy_Tests.cs index ab10d6d2f95b..2f15765ec17a 100644 --- a/src/msbuild/src/Tasks.UnitTests/Copy_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/Copy_Tests.cs @@ -20,7 +20,6 @@ using Shouldly; using Xunit; -using Xunit.Abstractions; using Microsoft.Build.UnitTests.Shared; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/CreateCSharpManifestResourceName_Tests.cs b/src/msbuild/src/Tasks.UnitTests/CreateCSharpManifestResourceName_Tests.cs index a29f5b938fce..0d6ed50ad593 100644 --- a/src/msbuild/src/Tasks.UnitTests/CreateCSharpManifestResourceName_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/CreateCSharpManifestResourceName_Tests.cs @@ -10,7 +10,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/CreateItem_Tests.cs b/src/msbuild/src/Tasks.UnitTests/CreateItem_Tests.cs index 90a57722f308..d75da37b32b1 100644 --- a/src/msbuild/src/Tasks.UnitTests/CreateItem_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/CreateItem_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/CreateVisualBasicManifestResourceName_Tests.cs b/src/msbuild/src/Tasks.UnitTests/CreateVisualBasicManifestResourceName_Tests.cs index 567eea82ab6e..28c15eb8a90b 100644 --- a/src/msbuild/src/Tasks.UnitTests/CreateVisualBasicManifestResourceName_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/CreateVisualBasicManifestResourceName_Tests.cs @@ -10,7 +10,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs b/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs index 3a820e754217..87fc5dc829c0 100644 --- a/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs @@ -15,7 +15,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/FormatUrl_Tests.cs b/src/msbuild/src/Tasks.UnitTests/FormatUrl_Tests.cs index 8cc77f6358af..14d738e5e096 100644 --- a/src/msbuild/src/Tasks.UnitTests/FormatUrl_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/FormatUrl_Tests.cs @@ -6,7 +6,6 @@ using Microsoft.Build.Tasks; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.UnitTests { diff --git a/src/msbuild/src/Tasks.UnitTests/GenerateBindingRedirects_Tests.cs b/src/msbuild/src/Tasks.UnitTests/GenerateBindingRedirects_Tests.cs index 966c283b634c..a38fe19755ed 100644 --- a/src/msbuild/src/Tasks.UnitTests/GenerateBindingRedirects_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/GenerateBindingRedirects_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/GetAssembliesMetadata_Tests.cs b/src/msbuild/src/Tasks.UnitTests/GetAssembliesMetadata_Tests.cs index 1c8bcd0ccf33..c02b4a37678d 100644 --- a/src/msbuild/src/Tasks.UnitTests/GetAssembliesMetadata_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/GetAssembliesMetadata_Tests.cs @@ -13,7 +13,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; using Xunit.Sdk; namespace Microsoft.Build.Tasks.UnitTests diff --git a/src/msbuild/src/Tasks.UnitTests/GetCompatiblePlatform_Tests.cs b/src/msbuild/src/Tasks.UnitTests/GetCompatiblePlatform_Tests.cs index d9359ef1a6cf..cee0d2f4fa7d 100644 --- a/src/msbuild/src/Tasks.UnitTests/GetCompatiblePlatform_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/GetCompatiblePlatform_Tests.cs @@ -5,7 +5,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/GetFileHash_Tests.cs b/src/msbuild/src/Tasks.UnitTests/GetFileHash_Tests.cs index c2abb7f01688..119cf3976bcb 100644 --- a/src/msbuild/src/Tasks.UnitTests/GetFileHash_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/GetFileHash_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/GetReferencePaths_Tests.cs b/src/msbuild/src/Tasks.UnitTests/GetReferencePaths_Tests.cs index f4352c0322ad..dd95e6eef56b 100644 --- a/src/msbuild/src/Tasks.UnitTests/GetReferencePaths_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/GetReferencePaths_Tests.cs @@ -7,6 +7,7 @@ using Microsoft.Build.Shared; using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; +using Shouldly; using Xunit; using FrameworkNameVersioning = System.Runtime.Versioning.FrameworkName; @@ -20,6 +21,13 @@ namespace Microsoft.Build.UnitTests ///
public sealed class GetReferenceAssmeblyPath_Tests { + private readonly ITestOutputHelper _output; + + public GetReferenceAssmeblyPath_Tests(ITestOutputHelper output) + { + _output = output; + } + /// /// Test the case where there is a good target framework moniker passed in. /// @@ -328,6 +336,91 @@ public void TestGeneralFrameworkMonikerGoodWithFrameworkInFallbackPaths() Assert.Equal(".NET Framework 4.1", displayName); } } + + /// + /// Test that a relative RootPath resolved via TaskEnvironment produces the same result as an absolute RootPath. + /// + [Fact] + public void TestRelativeRootPathProducesSameResultAsAbsolute() + { + using TestEnvironment env = TestEnvironment.Create(_output); + + string baseDir = env.DefaultTestDirectory.Path; + string relativeDir = "framework-root"; + string absoluteDir = Path.Combine(baseDir, relativeDir); + var framework41Directory = env.CreateFolder(Path.Combine(absoluteDir, Path.Combine("MyFramework", "v4.1") + Path.DirectorySeparatorChar)); + var redistListDirectory = env.CreateFolder(Path.Combine(framework41Directory.Path, "RedistList")); + env.CreateFile(redistListDirectory, "FrameworkList.xml", + "" + + "" + + ""); + + // Baseline: absolute RootPath + MockEngine absoluteEngine = new MockEngine(); + GetReferenceAssemblyPaths absoluteTask = new GetReferenceAssemblyPaths(); + absoluteTask.BuildEngine = absoluteEngine; + absoluteTask.TargetFrameworkMoniker = "MyFramework, Version=v4.1"; + absoluteTask.RootPath = absoluteDir; + absoluteTask.Execute(); + + // Test: relative RootPath with TaskEnvironment + MockEngine relativeEngine = new MockEngine(); + GetReferenceAssemblyPaths relativeTask = new GetReferenceAssemblyPaths(); + relativeTask.BuildEngine = relativeEngine; + relativeTask.TargetFrameworkMoniker = "MyFramework, Version=v4.1"; + relativeTask.TaskEnvironment = TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(baseDir); + relativeTask.RootPath = relativeDir; + relativeTask.Execute(); + + relativeTask.ReferenceAssemblyPaths.ShouldBe(absoluteTask.ReferenceAssemblyPaths); + relativeTask.TargetFrameworkMonikerDisplayName.ShouldBe(absoluteTask.TargetFrameworkMonikerDisplayName); + relativeEngine.Errors.ShouldBe(0); + } + + /// + /// Test that a relative path in TargetFrameworkFallbackSearchPaths resolved via TaskEnvironment + /// produces the same result as an absolute fallback path. + /// + [Fact] + public void TestRelativeFallbackSearchPathProducesSameResultAsAbsolute() + { + using TestEnvironment env = TestEnvironment.Create(_output); + + string baseDir = env.DefaultTestDirectory.Path; + string relativeDir = "framework-root"; + string absoluteDir = Path.Combine(baseDir, relativeDir); + var framework41Directory = env.CreateFolder(Path.Combine(absoluteDir, Path.Combine("MyFramework", "v4.1") + Path.DirectorySeparatorChar)); + var redistListDirectory = env.CreateFolder(Path.Combine(framework41Directory.Path, "RedistList")); + env.CreateFile(redistListDirectory, "FrameworkList.xml", + "" + + "" + + ""); + + string nonExistentRoot = Path.Combine(baseDir, "nonexistent"); + + // Baseline: absolute fallback path + MockEngine absoluteEngine = new MockEngine(); + GetReferenceAssemblyPaths absoluteTask = new GetReferenceAssemblyPaths(); + absoluteTask.BuildEngine = absoluteEngine; + absoluteTask.TargetFrameworkMoniker = "MyFramework, Version=v4.1"; + absoluteTask.RootPath = nonExistentRoot; + absoluteTask.TargetFrameworkFallbackSearchPaths = absoluteDir; + absoluteTask.Execute(); + + // Test: relative fallback path with TaskEnvironment + MockEngine relativeEngine = new MockEngine(); + GetReferenceAssemblyPaths relativeTask = new GetReferenceAssemblyPaths(); + relativeTask.BuildEngine = relativeEngine; + relativeTask.TargetFrameworkMoniker = "MyFramework, Version=v4.1"; + relativeTask.TaskEnvironment = TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(baseDir); + relativeTask.RootPath = nonExistentRoot; + relativeTask.TargetFrameworkFallbackSearchPaths = relativeDir; + relativeTask.Execute(); + + relativeTask.ReferenceAssemblyPaths.ShouldBe(absoluteTask.ReferenceAssemblyPaths); + relativeTask.TargetFrameworkMonikerDisplayName.ShouldBe(absoluteTask.TargetFrameworkMonikerDisplayName); + relativeEngine.Errors.ShouldBe(0); + } } } #endif diff --git a/src/msbuild/src/Tasks.UnitTests/GetSDKReference_Tests.cs b/src/msbuild/src/Tasks.UnitTests/GetSDKReference_Tests.cs index f5ff062f87b0..eb76a457e9ad 100644 --- a/src/msbuild/src/Tasks.UnitTests/GetSDKReference_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/GetSDKReference_Tests.cs @@ -11,7 +11,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/HintPathResolver_Tests.cs b/src/msbuild/src/Tasks.UnitTests/HintPathResolver_Tests.cs index 7849b653fdbf..a40170b31525 100644 --- a/src/msbuild/src/Tasks.UnitTests/HintPathResolver_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/HintPathResolver_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/MSBuildInternalMessage_Tests.cs b/src/msbuild/src/Tasks.UnitTests/MSBuildInternalMessage_Tests.cs index cc020da89047..aa4bf96f0072 100644 --- a/src/msbuild/src/Tasks.UnitTests/MSBuildInternalMessage_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/MSBuildInternalMessage_Tests.cs @@ -7,7 +7,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Tasks.UnitTests { diff --git a/src/msbuild/src/Tasks.UnitTests/MSBuild_Tests.cs b/src/msbuild/src/Tasks.UnitTests/MSBuild_Tests.cs index 9a17e9b848fa..30923cc24f4f 100644 --- a/src/msbuild/src/Tasks.UnitTests/MSBuild_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/MSBuild_Tests.cs @@ -13,7 +13,6 @@ using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj b/src/msbuild/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj index 801e8c764830..1c1696e64408 100644 --- a/src/msbuild/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj +++ b/src/msbuild/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/msbuild/src/Tasks.UnitTests/OutputPathTests.cs b/src/msbuild/src/Tasks.UnitTests/OutputPathTests.cs index ea7cfbb1f33f..8ccccd3755ee 100644 --- a/src/msbuild/src/Tasks.UnitTests/OutputPathTests.cs +++ b/src/msbuild/src/Tasks.UnitTests/OutputPathTests.cs @@ -12,7 +12,6 @@ using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/PortableTasks_Tests.cs b/src/msbuild/src/Tasks.UnitTests/PortableTasks_Tests.cs index cd051c5a90e3..b8f3468388d0 100644 --- a/src/msbuild/src/Tasks.UnitTests/PortableTasks_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/PortableTasks_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/RegressionTests.cs b/src/msbuild/src/Tasks.UnitTests/RegressionTests.cs index 924a0adb84bd..e82e09f9445b 100644 --- a/src/msbuild/src/Tasks.UnitTests/RegressionTests.cs +++ b/src/msbuild/src/Tasks.UnitTests/RegressionTests.cs @@ -7,7 +7,6 @@ using Microsoft.Build.Shared; using Microsoft.Build.UnitTests; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/RemoveDir_Tests.cs b/src/msbuild/src/Tasks.UnitTests/RemoveDir_Tests.cs index 5e01b3a91de2..a4204ece5fc5 100644 --- a/src/msbuild/src/Tasks.UnitTests/RemoveDir_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/RemoveDir_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/ResolveAssemblyReference_CustomCultureTests.cs b/src/msbuild/src/Tasks.UnitTests/ResolveAssemblyReference_CustomCultureTests.cs index c1fc65403fd3..dd4ab6216fd0 100644 --- a/src/msbuild/src/Tasks.UnitTests/ResolveAssemblyReference_CustomCultureTests.cs +++ b/src/msbuild/src/Tasks.UnitTests/ResolveAssemblyReference_CustomCultureTests.cs @@ -7,7 +7,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; namespace Microsoft.Build.Tasks.UnitTests { diff --git a/src/msbuild/src/Tasks.UnitTests/ResolveNonMSBuildProjectOutput_Tests.cs b/src/msbuild/src/Tasks.UnitTests/ResolveNonMSBuildProjectOutput_Tests.cs index 5de1bfcf5fb8..7dae22e9b1cb 100644 --- a/src/msbuild/src/Tasks.UnitTests/ResolveNonMSBuildProjectOutput_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/ResolveNonMSBuildProjectOutput_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs index b9d1c4eae426..dd8eca60be1f 100644 --- a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs @@ -10,7 +10,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs index 70ac4f19f7ba..0f16e5f92876 100644 --- a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/MSBuildResXReader_Tests.cs b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/MSBuildResXReader_Tests.cs index 9ebe60a62eed..094891584d6d 100644 --- a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/MSBuildResXReader_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/MSBuildResXReader_Tests.cs @@ -9,7 +9,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/ResGenDependencies_Tests.cs b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/ResGenDependencies_Tests.cs index acd43836a7fa..aa5027a43299 100644 --- a/src/msbuild/src/Tasks.UnitTests/ResourceHandling/ResGenDependencies_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/ResourceHandling/ResGenDependencies_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.Build.UnitTests; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/RoslynCodeTaskFactory_Tests.cs b/src/msbuild/src/Tasks.UnitTests/RoslynCodeTaskFactory_Tests.cs index 4885e53ec8d9..eb8430cdfab1 100644 --- a/src/msbuild/src/Tasks.UnitTests/RoslynCodeTaskFactory_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/RoslynCodeTaskFactory_Tests.cs @@ -18,7 +18,6 @@ using VerifyTests; using VerifyXunit; using Xunit; -using Xunit.Abstractions; using static VerifyXunit.Verifier; @@ -26,7 +25,6 @@ namespace Microsoft.Build.Tasks.UnitTests { - [UsesVerify] public class RoslynCodeTaskFactory_Tests { private const string TaskName = "MyInlineTask"; diff --git a/src/msbuild/src/Tasks.UnitTests/TestResources/TestBinary.cs b/src/msbuild/src/Tasks.UnitTests/TestResources/TestBinary.cs index 411637d381ef..1a2f96a2e935 100644 --- a/src/msbuild/src/Tasks.UnitTests/TestResources/TestBinary.cs +++ b/src/msbuild/src/Tasks.UnitTests/TestResources/TestBinary.cs @@ -4,7 +4,7 @@ using System; using System.IO; using Xunit; -using Xunit.Abstractions; +using Xunit.Sdk; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/Unzip_Tests.cs b/src/msbuild/src/Tasks.UnitTests/Unzip_Tests.cs index 1b7de792757d..74efe833a409 100644 --- a/src/msbuild/src/Tasks.UnitTests/Unzip_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/Unzip_Tests.cs @@ -178,9 +178,14 @@ public static bool NotRunningAsRoot() return process.StandardOutput.ReadToEnd().Trim() != "0"; } - [ConditionalFact(nameof(NotRunningAsRoot))] // root can write to read-only files + [Fact] public void LogsErrorIfReadOnlyFileCannotBeOverwitten() { + if (!NotRunningAsRoot()) + { + Assert.Skip("root can write to read-only files"); + } + using (TestEnvironment testEnvironment = TestEnvironment.Create()) { TransientTestFolder source = testEnvironment.CreateFolder(createFolder: true); diff --git a/src/msbuild/src/Tasks.UnitTests/VerifyFileHash_Tests.cs b/src/msbuild/src/Tasks.UnitTests/VerifyFileHash_Tests.cs index 4cf2f372704a..2827a47fe9f2 100644 --- a/src/msbuild/src/Tasks.UnitTests/VerifyFileHash_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/VerifyFileHash_Tests.cs @@ -7,7 +7,6 @@ using Microsoft.Build.Tasks.UnitTests.TestResources; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/WriteLinesToFile_Tests.cs b/src/msbuild/src/Tasks.UnitTests/WriteLinesToFile_Tests.cs index 55f0efb9870e..2ea0830290a4 100644 --- a/src/msbuild/src/Tasks.UnitTests/WriteLinesToFile_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/WriteLinesToFile_Tests.cs @@ -14,7 +14,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks.UnitTests/XamlDataDrivenToolTask_Tests.cs b/src/msbuild/src/Tasks.UnitTests/XamlDataDrivenToolTask_Tests.cs index 060a42bb9a3f..ad62f4af2b8d 100644 --- a/src/msbuild/src/Tasks.UnitTests/XamlDataDrivenToolTask_Tests.cs +++ b/src/msbuild/src/Tasks.UnitTests/XamlDataDrivenToolTask_Tests.cs @@ -12,7 +12,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Tasks/GetReferenceAssemblyPaths.cs b/src/msbuild/src/Tasks/GetReferenceAssemblyPaths.cs index 81b02cdf5a03..fd2cf698a3e0 100644 --- a/src/msbuild/src/Tasks/GetReferenceAssemblyPaths.cs +++ b/src/msbuild/src/Tasks/GetReferenceAssemblyPaths.cs @@ -4,11 +4,12 @@ using System; using System.Collections.Generic; using Microsoft.Build.Framework; +using Microsoft.Build.Shared; using Microsoft.Build.Utilities; using FrameworkNameVersioning = System.Runtime.Versioning.FrameworkName; #if FEATURE_GAC -using Microsoft.Build.Shared; +using System.Threading; using SystemProcessorArchitecture = System.Reflection.ProcessorArchitecture; #endif @@ -19,8 +20,12 @@ namespace Microsoft.Build.Tasks /// /// Returns the reference assembly paths to the various frameworks /// - public class GetReferenceAssemblyPaths : TaskExtension + [MSBuildMultiThreadableTask] + public class GetReferenceAssemblyPaths : TaskExtension, IMultiThreadableTask { + /// + public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback; + #region Data #if FEATURE_GAC /// @@ -32,7 +37,23 @@ public class GetReferenceAssemblyPaths : TaskExtension /// /// Cache in a static whether or not we have found the 35sp1sentinel assembly. /// - private static bool? s_net35SP1SentinelAssemblyFound; + private static readonly Lazy s_net35SP1SentinelAssemblyFound = new Lazy(() => + { + // get an assemblyname from the string representation of the sentinel assembly name + var sentinelAssemblyName = new AssemblyNameExtension(NET35SP1SentinelAssemblyName); + string path = GlobalAssemblyCache.GetLocation( + sentinelAssemblyName, + SystemProcessorArchitecture.MSIL, + runtimeVersion => "v2.0.50727", + new Version("2.0.57027"), + false, + new FileExists(p => FileUtilities.FileExistsNoThrow(p)), + GlobalAssemblyCache.pathFromFusionName, + GlobalAssemblyCache.gacEnumerator, + false); + + return !string.IsNullOrEmpty(path); + }, LazyThreadSafetyMode.PublicationOnly); #endif /// @@ -144,6 +165,11 @@ public string TargetFrameworkFallbackSearchPaths /// public override bool Execute() { + AbsolutePath? absoluteRootPath = !string.IsNullOrEmpty(RootPath) + ? TaskEnvironment.GetAbsolutePath(RootPath) + : new AbsolutePath(RootPath, ignoreRootedCheck: true); + IList absoluteFallbackSearchPaths = ResolveAbsoluteFallbackSearchPaths(TargetFrameworkFallbackSearchPaths); + FrameworkNameVersioning moniker; FrameworkNameVersioning monikerWithNoProfile = null; @@ -169,16 +195,6 @@ public override bool Execute() if (!BypassFrameworkInstallChecks && moniker.Identifier.Equals(".NETFramework", StringComparison.OrdinalIgnoreCase) && moniker.Version.Major < 4) { - // We have not got a value for whether or not the 35 sentinel assembly has been found - if (!s_net35SP1SentinelAssemblyFound.HasValue) - { - // get an assemblyname from the string representation of the sentinel assembly name - var sentinelAssemblyName = new AssemblyNameExtension(NET35SP1SentinelAssemblyName); - - string path = GlobalAssemblyCache.GetLocation(sentinelAssemblyName, SystemProcessorArchitecture.MSIL, runtimeVersion => "v2.0.50727", new Version("2.0.57027"), false, new FileExists(p => FileUtilities.FileExistsNoThrow(p)), GlobalAssemblyCache.pathFromFusionName, GlobalAssemblyCache.gacEnumerator, false); - s_net35SP1SentinelAssemblyFound = !String.IsNullOrEmpty(path); - } - // We did not find the SP1 sentinel assembly in the GAC. Therefore we must assume that SP1 isn't installed if (!s_net35SP1SentinelAssemblyFound.Value) { @@ -195,7 +211,7 @@ public override bool Execute() try { - _tfmPaths = GetPaths(RootPath, TargetFrameworkFallbackSearchPaths, moniker); + _tfmPaths = GetPaths(absoluteRootPath, absoluteFallbackSearchPaths, moniker); if (_tfmPaths?.Count > 0) { @@ -206,7 +222,7 @@ public override bool Execute() // There is no point in generating the full framework paths if profile path could not be found. if (targetingProfile && _tfmPaths != null) { - _tfmPathsNoProfile = GetPaths(RootPath, TargetFrameworkFallbackSearchPaths, monikerWithNoProfile); + _tfmPathsNoProfile = GetPaths(absoluteRootPath, absoluteFallbackSearchPaths, monikerWithNoProfile); } // The path with out the profile is just the reference assembly paths. @@ -236,14 +252,16 @@ public override bool Execute() /// /// Generate the set of chained reference assembly paths /// - private IList GetPaths(string rootPath, string targetFrameworkFallbackSearchPaths, FrameworkNameVersioning frameworkmoniker) + private IList GetPaths(AbsolutePath? rootPath, IList fallbackSearchPaths, FrameworkNameVersioning frameworkmoniker) { + string fallbackSearchPathsJoined = string.Join(";", fallbackSearchPaths); + IList pathsToReturn = ToolLocationHelper.GetPathToReferenceAssemblies( frameworkmoniker.Identifier, frameworkmoniker.Version.ToString(), frameworkmoniker.Profile, - rootPath, - targetFrameworkFallbackSearchPaths); + rootPath?.Value, + fallbackSearchPathsJoined); if (!SuppressNotFoundError) { @@ -267,6 +285,26 @@ private IList GetPaths(string rootPath, string targetFrameworkFallbackSe return pathsToReturn; } + /// + /// Resolves each semicolon-separated fallback search path to absolute via TaskEnvironment. + /// + private IList ResolveAbsoluteFallbackSearchPaths(string fallbackSearchPaths) + { + if (string.IsNullOrEmpty(fallbackSearchPaths)) + { + return []; + } + + string[] parts = fallbackSearchPaths.Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries); + var result = new AbsolutePath[parts.Length]; + for (int i = 0; i < parts.Length; i++) + { + result[i] = TaskEnvironment.GetAbsolutePath(parts[i]); + } + + return result; + } + #endregion } } diff --git a/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets index 184e922ec49e..5c63581f44c0 100644 --- a/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -5165,6 +5165,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. + $(GetCopyToOutputDirectoryItemsDependsOn); AssignTargetPaths; $(_TargetsThatPrepareProjectReferences); _GetProjectReferenceTargetFrameworkProperties; diff --git a/src/msbuild/src/Tasks/System.Resources.Extensions.pkgdef b/src/msbuild/src/Tasks/System.Resources.Extensions.pkgdef index 5dbaee33e5c9..842e5aea699e 100644 --- a/src/msbuild/src/Tasks/System.Resources.Extensions.pkgdef +++ b/src/msbuild/src/Tasks/System.Resources.Extensions.pkgdef @@ -3,5 +3,5 @@ "codeBase"="$BaseInstallDir$\MSBuild\Current\Bin\System.Resources.Extensions.dll" "publicKeyToken"="cc7b13ffcd2ddd51" "culture"="neutral" -"oldVersion"="0.0.0.0-10.0.0.3" -"newVersion"="10.0.0.3" +"oldVersion"="0.0.0.0-10.0.0.4" +"newVersion"="10.0.0.4" diff --git a/src/msbuild/src/UnitTests.Shared/Microsoft.Build.UnitTests.Shared.csproj b/src/msbuild/src/UnitTests.Shared/Microsoft.Build.UnitTests.Shared.csproj index 73c968b3d22d..a10bd8886345 100644 --- a/src/msbuild/src/UnitTests.Shared/Microsoft.Build.UnitTests.Shared.csproj +++ b/src/msbuild/src/UnitTests.Shared/Microsoft.Build.UnitTests.Shared.csproj @@ -4,14 +4,11 @@ Microsoft.Build.UnitTests.Shared true false - false true - - - + + diff --git a/src/msbuild/src/UnitTests.Shared/MockEngine.cs b/src/msbuild/src/UnitTests.Shared/MockEngine.cs index 9b21b43cf90f..08b4cf2732fc 100644 --- a/src/msbuild/src/UnitTests.Shared/MockEngine.cs +++ b/src/msbuild/src/UnitTests.Shared/MockEngine.cs @@ -12,7 +12,7 @@ using Microsoft.Build.Logging; using Shouldly; -using Xunit.Abstractions; +using Xunit; #nullable disable diff --git a/src/msbuild/src/UnitTests.Shared/MockLogger.cs b/src/msbuild/src/UnitTests.Shared/MockLogger.cs index ba8c937e5984..bb3c4e72ab68 100644 --- a/src/msbuild/src/UnitTests.Shared/MockLogger.cs +++ b/src/msbuild/src/UnitTests.Shared/MockLogger.cs @@ -12,7 +12,6 @@ using Microsoft.Build.Framework; using Shouldly; using Xunit; -using Xunit.Abstractions; using ProjectCollection = Microsoft.Build.Evaluation.ProjectCollection; #nullable disable diff --git a/src/msbuild/src/UnitTests.Shared/ObjectModelHelpers.cs b/src/msbuild/src/UnitTests.Shared/ObjectModelHelpers.cs index f7867edce494..4d6aeb152d63 100644 --- a/src/msbuild/src/UnitTests.Shared/ObjectModelHelpers.cs +++ b/src/msbuild/src/UnitTests.Shared/ObjectModelHelpers.cs @@ -25,7 +25,6 @@ using Microsoft.Build.Shared.FileSystem; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/UnitTests.Shared/RunnerUtilities.cs b/src/msbuild/src/UnitTests.Shared/RunnerUtilities.cs index 0874b996907c..6bd047693ddf 100644 --- a/src/msbuild/src/UnitTests.Shared/RunnerUtilities.cs +++ b/src/msbuild/src/UnitTests.Shared/RunnerUtilities.cs @@ -9,7 +9,7 @@ using Microsoft.Build.Framework; using Microsoft.Build.Internal; using Microsoft.Build.Shared; -using Xunit.Abstractions; +using Xunit; using Constants = Microsoft.Build.Framework.Constants; #nullable disable diff --git a/src/msbuild/src/UnitTests.Shared/TestEnvironment.cs b/src/msbuild/src/UnitTests.Shared/TestEnvironment.cs index f031a0bd834c..f659c70b6c99 100644 --- a/src/msbuild/src/UnitTests.Shared/TestEnvironment.cs +++ b/src/msbuild/src/UnitTests.Shared/TestEnvironment.cs @@ -8,6 +8,7 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Text; using System.Text.RegularExpressions; using Microsoft.Build.Framework; using Microsoft.Build.Internal; @@ -17,7 +18,6 @@ using Microsoft.Build.UnitTests.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; using CommonWriterType = System.Action>; using TempPaths = System.Collections.Generic.Dictionary; @@ -396,6 +396,15 @@ public TransientDebugEngine WithTransientDebugEngineForNewProcesses(bool state) private sealed class DefaultOutput : ITestOutputHelper { + // Probably unreachable. Don't bother implementing it unless we hit this exception. + public string Output => throw new InvalidOperationException(); + + public void Write(string message) + => Console.Write(message); + + public void Write(string format, params object[] args) + => Console.Write(format, args); + public void WriteLine(string message) { Console.WriteLine(message); diff --git a/src/msbuild/src/Utilities.UnitTests/ProcessExtensions_Tests.cs b/src/msbuild/src/Utilities.UnitTests/ProcessExtensions_Tests.cs index 7f4bbc61950d..22a9e916a306 100644 --- a/src/msbuild/src/Utilities.UnitTests/ProcessExtensions_Tests.cs +++ b/src/msbuild/src/Utilities.UnitTests/ProcessExtensions_Tests.cs @@ -6,7 +6,6 @@ using Microsoft.Build.Shared; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Utilities.UnitTests/ToolLocationHelper_Tests.cs b/src/msbuild/src/Utilities.UnitTests/ToolLocationHelper_Tests.cs index d18d9a48ff61..c22a4d6e9d7b 100644 --- a/src/msbuild/src/Utilities.UnitTests/ToolLocationHelper_Tests.cs +++ b/src/msbuild/src/Utilities.UnitTests/ToolLocationHelper_Tests.cs @@ -22,7 +22,6 @@ using UtilitiesDotNetFrameworkArchitecture = Microsoft.Build.Utilities.DotNetFrameworkArchitecture; using SharedDotNetFrameworkArchitecture = Microsoft.Build.Shared.DotNetFrameworkArchitecture; using Xunit; -using Xunit.Abstractions; #nullable disable diff --git a/src/msbuild/src/Utilities.UnitTests/ToolTask_Tests.cs b/src/msbuild/src/Utilities.UnitTests/ToolTask_Tests.cs index 77af6815973e..183a1d7f56c7 100644 --- a/src/msbuild/src/Utilities.UnitTests/ToolTask_Tests.cs +++ b/src/msbuild/src/Utilities.UnitTests/ToolTask_Tests.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Resources; using System.Text.RegularExpressions; @@ -13,7 +14,6 @@ using Microsoft.Build.Utilities; using Shouldly; using Xunit; -using Xunit.Abstractions; #nullable disable @@ -21,7 +21,7 @@ namespace Microsoft.Build.UnitTests { public sealed class ToolTask_Tests { - private ITestOutputHelper _output; + private readonly ITestOutputHelper _output; public ToolTask_Tests(ITestOutputHelper testOutput) { @@ -995,50 +995,61 @@ public void SetsTerminationTimeoutCorrectly(int timeout, bool isInvalidValid) /// Verifies that a ToolTask instance can return correct results when executed multiple times with timeout. /// /// Specifies the number of repeats for external command execution. - /// Delay to generate on the first execution in milliseconds. - /// Delay to generate on follow-up execution in milliseconds. - /// Task timeout in milliseconds. + /// Whether the first execution should be forced to time out before later retries succeed. /// - /// These tests execute the same task instance multiple times, which will in turn run a shell command to sleep + /// These tests execute the same task instance multiple times, which will in turn run a command to sleep for a /// predefined amount of time. The first execution may time out, but all following ones won't. It is expected /// that all following executions return success. /// [Theory] - [InlineData(1, 1, 1, -1)] // Normal case, no repeat. - [InlineData(3, 1, 1, -1)] // Repeat without timeout. - [InlineData(3, 10000, 1, 1000)] // Repeat with timeout. - public void ToolTaskThatTimeoutAndRetry(int repeats, int initialDelay, int followupDelay, int timeout) + [InlineData(1, false)] + [InlineData(3, false)] + [InlineData(3, true)] + public void ToolTaskThatTimeoutAndRetry(int repeats, bool timeoutOnFirstExecution) { using var env = TestEnvironment.Create(_output); + int fastDelayMilliseconds = 100; + int slowDelayMilliseconds = 5_000; + int timeoutMilliseconds = 2_000; + MockEngine3 engine = new(); // Task under test: var task = new ToolTaskThatSleeps { BuildEngine = engine, - InitialDelay = initialDelay, - FollowupDelay = followupDelay, - Timeout = timeout + InitialDelay = timeoutOnFirstExecution ? slowDelayMilliseconds : fastDelayMilliseconds, + FollowupDelay = fastDelayMilliseconds, + Timeout = timeoutOnFirstExecution ? timeoutMilliseconds : System.Threading.Timeout.Infinite }; // Execute the same task instance multiple times. The index is one-based. - bool result; - for (int i = 1; i <= repeats; i++) + for (int attempt = 1; attempt <= repeats; attempt++) { - // Execute the task: - result = task.Execute(); + bool shouldSucceed = attempt > 1 || !timeoutOnFirstExecution; + bool result = task.Execute(); - _output.WriteLine(engine.Log); + _output.WriteLine( + $"Attempt {attempt}/{repeats}: expectedSuccess={shouldSucceed}, actualSuccess={result}, exitCode={task.ExitCode}."); + + if (!string.IsNullOrEmpty(engine.Log)) + { + _output.WriteLine(engine.Log); + engine.Log = string.Empty; + } - task.RepeatCount.ShouldBe(i); + task.RepeatCount.ShouldBe(attempt); + result.ShouldBe(shouldSucceed); - // The first execution may fail (timeout), but all following ones should succeed: - if (i > 1) + if (shouldSucceed) { - result.ShouldBeTrue(); task.ExitCode.ShouldBe(0); } + else + { + task.ExitCode.ShouldNotBe(0); + } } } @@ -1108,25 +1119,21 @@ public void ToolTaskCapturesAllOutputWithFix() /// A simple implementation of to sleep for a while. ///
/// - /// This task runs shell command to sleep for predefined, variable amount of time based on how many times the - /// instance has been executed. + /// This task invokes a direct sleep tool with a variable delay based on how many times the instance has been + /// executed, which avoids the flakiness of nesting the wait inside a shell. /// private sealed class ToolTaskThatSleeps : ToolTask { - // Windows prompt command to sleep: - private readonly string _windowsSleep = "/c start /wait timeout {0}"; - - // UNIX command to sleep: - private readonly string _unixSleep = "-c \"sleep {0}\""; - - // Full path to shell: - private readonly string _pathToShell; + private readonly string _pathToTool; public ToolTaskThatSleeps() : base() { - // Determines shell to use: cmd for Windows, sh for UNIX-like systems: - _pathToShell = NativeMethodsShared.IsUnixLike ? "/bin/sh" : "cmd.exe"; + // timeout.exe exits immediately when ToolTask redirects stdin on Windows, so use ping.exe + // as the built-in blocking process for the timeout/retry scenario. + _pathToTool = NativeMethodsShared.IsUnixLike + ? "sleep" + : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "ping.exe"); } /// @@ -1141,9 +1148,9 @@ public ToolTaskThatSleeps() /// Gets or sets the delay for the follow-up executions. /// /// - /// Defaults to 1 milliseconds. + /// Defaults to 100 milliseconds. /// - public Int32 FollowupDelay { get; set; } = 1; + public Int32 FollowupDelay { get; set; } = 100; /// /// Int32 output parameter for the repeat counter for test purpose. @@ -1152,22 +1159,26 @@ public ToolTaskThatSleeps() public Int32 RepeatCount { get; private set; } = 0; /// - /// Gets the tool name (shell). + /// Gets the tool name. /// - protected override string ToolName => Path.GetFileName(_pathToShell); + protected override string ToolName => Path.GetFileName(_pathToTool); /// - /// Gets the full path to shell. + /// Gets the full path to the sleep tool. /// - protected override string GenerateFullPathToTool() => _pathToShell; + protected override string GenerateFullPathToTool() => _pathToTool; /// - /// Generates a shell command to sleep different amount of time based on repeat counter. + /// Generates the arguments to sleep for a different amount of time based on repeat counter. /// - protected override string GenerateCommandLineCommands() => - NativeMethodsShared.IsUnixLike ? - string.Format(_unixSleep, RepeatCount < 2 ? InitialDelay / 1000.0 : FollowupDelay / 1000.0) : - string.Format(_windowsSleep, RepeatCount < 2 ? InitialDelay / 1000.0 : FollowupDelay / 1000.0); + protected override string GenerateCommandLineCommands() + { + int delay = RepeatCount < 2 ? InitialDelay : FollowupDelay; + + return NativeMethodsShared.IsUnixLike + ? (delay / 1000.0).ToString("0.###", CultureInfo.InvariantCulture) + : $"-n {Math.Max(2, (int)Math.Ceiling(delay / 1000.0) + 1).ToString(CultureInfo.InvariantCulture)} 127.0.0.1"; + } /// /// Ensures that test parameters make sense. diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/AssemblyFixtureAttribute.cs b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/AssemblyFixtureAttribute.cs deleted file mode 100644 index 42d05e95efa0..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/AssemblyFixtureAttribute.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -#nullable disable - -namespace Xunit -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - public class AssemblyFixtureAttribute : Attribute - { - public AssemblyFixtureAttribute(Type fixtureType) - { - FixtureType = fixtureType; - } - - public Type FixtureType { get; private set; } - - public Scope LifetimeScope { get; set; } - - public enum Scope - { - Assembly, - Class, - Method - } - } -} diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/README.md b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/README.md deleted file mode 100644 index a7cb5671dd5d..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Assembly Fixture support - -Originally copied from xunit samples, found here: https://github.com/xunit/samples.xunit/tree/master/AssemblyFixtureExample \ No newline at end of file diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestAssemblyRunnerWithAssemblyFixture.cs b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestAssemblyRunnerWithAssemblyFixture.cs deleted file mode 100644 index a74228cb0ec3..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestAssemblyRunnerWithAssemblyFixture.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -#nullable disable - -namespace Xunit.NetCore.Extensions -{ - public class XunitTestAssemblyRunnerWithAssemblyFixture : XunitTestAssemblyRunner - { - private readonly Dictionary assemblyFixtureMappings = new Dictionary(); - private List assemblyFixtureAttributes; - - public XunitTestAssemblyRunnerWithAssemblyFixture(ITestAssembly testAssembly, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageSink executionMessageSink, - ITestFrameworkExecutionOptions executionOptions) - : base(testAssembly, testCases, diagnosticMessageSink, executionMessageSink, executionOptions) - { } - - protected override async Task AfterTestAssemblyStartingAsync() - { - // Let everything initialize - await base.AfterTestAssemblyStartingAsync(); - - // Go find all the AssemblyFixtureAttributes adorned on the test assembly - Aggregator.Run(() => - { - var fixturesAttrs = ((IReflectionAssemblyInfo)TestAssembly.Assembly).Assembly - .GetCustomAttributes(typeof(AssemblyFixtureAttribute), false) - .Cast() - .ToList(); - - this.assemblyFixtureAttributes = fixturesAttrs; - - // Instantiate all the fixtures - foreach (var fixtureAttr in fixturesAttrs.Where(a => a.LifetimeScope == AssemblyFixtureAttribute.Scope.Assembly)) - { - assemblyFixtureMappings[fixtureAttr.FixtureType] = Activator.CreateInstance(fixtureAttr.FixtureType); - } - }); - } - - protected override Task BeforeTestAssemblyFinishedAsync() - { - // Make sure we clean up everybody who is disposable, and use Aggregator.Run to isolate Dispose failures - foreach (var disposable in assemblyFixtureMappings.Values.OfType()) - { - Aggregator.Run(disposable.Dispose); - } - - return base.BeforeTestAssemblyFinishedAsync(); - } - - protected override Task RunTestCollectionAsync(IMessageBus messageBus, - ITestCollection testCollection, - IEnumerable testCases, - CancellationTokenSource cancellationTokenSource) - => new XunitTestCollectionRunnerWithAssemblyFixture(assemblyFixtureMappings, assemblyFixtureAttributes, - testCollection, testCases, DiagnosticMessageSink, messageBus, TestCaseOrderer, new ExceptionAggregator(Aggregator), cancellationTokenSource).RunAsync(); - } -} diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestClassRunnerWithAssemblyFixture.cs b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestClassRunnerWithAssemblyFixture.cs deleted file mode 100644 index 44afc240a243..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestClassRunnerWithAssemblyFixture.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -#nullable disable - -namespace Xunit.NetCore.Extensions -{ - public class XunitTestClassRunnerWithAssemblyFixture : XunitTestClassRunner - { - private readonly Dictionary assemblyFixtureMappings = new Dictionary(); - private readonly List assemblyFixtureAttributes; - - public XunitTestClassRunnerWithAssemblyFixture( - List assemblyFixtureAttributes, - ITestClass testClass, IReflectionTypeInfo @class, IEnumerable testCases, - IMessageSink diagnosticMessageSink, IMessageBus messageBus, ITestCaseOrderer testCaseOrderer, ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource, IDictionary collectionFixtureMappings) - : base(testClass, @class, testCases, diagnosticMessageSink, messageBus, testCaseOrderer, aggregator, cancellationTokenSource, collectionFixtureMappings) - { - this.assemblyFixtureAttributes = assemblyFixtureAttributes; - } - - protected override async Task AfterTestClassStartingAsync() - { - await base.AfterTestClassStartingAsync(); - - Aggregator.Run(() => - { - // Instantiate all the fixtures - foreach (var fixtureAttr in assemblyFixtureAttributes.Where(a => a.LifetimeScope == AssemblyFixtureAttribute.Scope.Class)) - { - assemblyFixtureMappings[fixtureAttr.FixtureType] = Activator.CreateInstance(fixtureAttr.FixtureType); - } - }); - } - protected override Task BeforeTestClassFinishedAsync() - { - // Make sure we clean up everybody who is disposable, and use Aggregator.Run to isolate Dispose failures - foreach (var disposable in assemblyFixtureMappings.Values.OfType()) - { - Aggregator.Run(disposable.Dispose); - } - - return base.BeforeTestClassFinishedAsync(); - } - - protected override Task RunTestMethodAsync(ITestMethod testMethod, IReflectionMethodInfo method, IEnumerable testCases, object[] constructorArguments) - { - return new XunitTestMethodRunnerWithAssemblyFixture(assemblyFixtureAttributes, - testMethod, Class, method, testCases, DiagnosticMessageSink, MessageBus, - new ExceptionAggregator(Aggregator), CancellationTokenSource, constructorArguments).RunAsync(); - } - } -} diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestCollectionRunnerWithAssemblyFixture.cs b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestCollectionRunnerWithAssemblyFixture.cs deleted file mode 100644 index 6171ff3f9028..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestCollectionRunnerWithAssemblyFixture.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -#nullable disable - -namespace Xunit.NetCore.Extensions -{ - public class XunitTestCollectionRunnerWithAssemblyFixture : XunitTestCollectionRunner - { - private readonly Dictionary assemblyFixtureMappings; - private readonly IMessageSink diagnosticMessageSink; - private readonly List assemblyFixtureAttributes; - - public XunitTestCollectionRunnerWithAssemblyFixture(Dictionary assemblyFixtureMappings, - List assemblyFixtureAttributes, - ITestCollection testCollection, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ITestCaseOrderer testCaseOrderer, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(testCollection, testCases, diagnosticMessageSink, messageBus, testCaseOrderer, aggregator, cancellationTokenSource) - { - this.assemblyFixtureMappings = assemblyFixtureMappings; - this.assemblyFixtureAttributes = assemblyFixtureAttributes ?? throw new ArgumentNullException(nameof(assemblyFixtureAttributes)); - this.diagnosticMessageSink = diagnosticMessageSink; - } - - protected override Task RunTestClassAsync(ITestClass testClass, IReflectionTypeInfo @class, IEnumerable testCases) - { - // Don't want to use .Concat + .ToDictionary because of the possibility of overriding types, - // so instead we'll just let collection fixtures override assembly fixtures. - var combinedFixtures = new Dictionary(assemblyFixtureMappings); - foreach (var kvp in CollectionFixtureMappings) - { - combinedFixtures[kvp.Key] = kvp.Value; - } - - return new XunitTestClassRunnerWithAssemblyFixture(assemblyFixtureAttributes, testClass, @class, testCases, diagnosticMessageSink, MessageBus, TestCaseOrderer, new ExceptionAggregator(Aggregator), CancellationTokenSource, combinedFixtures).RunAsync(); - } - } -} diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestFrameworkExecutorWithAssemblyFixture.cs b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestFrameworkExecutorWithAssemblyFixture.cs deleted file mode 100644 index 605fa16786e4..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestFrameworkExecutorWithAssemblyFixture.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Reflection; -using Xunit.Abstractions; -using Xunit.Sdk; - -#nullable disable - -namespace Xunit.NetCore.Extensions -{ - public class XunitTestFrameworkExecutorWithAssemblyFixture : XunitTestFrameworkExecutor - { - public XunitTestFrameworkExecutorWithAssemblyFixture(AssemblyName assemblyName, ISourceInformationProvider sourceInformationProvider, IMessageSink diagnosticMessageSink) - : base(assemblyName, sourceInformationProvider, diagnosticMessageSink) - { } - - protected override async void RunTestCases(IEnumerable testCases, IMessageSink executionMessageSink, ITestFrameworkExecutionOptions executionOptions) - { - using (var assemblyRunner = new XunitTestAssemblyRunnerWithAssemblyFixture(TestAssembly, testCases, DiagnosticMessageSink, executionMessageSink, executionOptions)) - { - await assemblyRunner.RunAsync(); - } - } - } -} diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestFrameworkWithAssemblyFixture.cs b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestFrameworkWithAssemblyFixture.cs deleted file mode 100644 index de14792e09d8..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestFrameworkWithAssemblyFixture.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; -using Xunit.Abstractions; -using Xunit.Sdk; - -#nullable disable - -namespace Xunit.NetCore.Extensions -{ - public class XunitTestFrameworkWithAssemblyFixture : XunitTestFramework - { - public XunitTestFrameworkWithAssemblyFixture(IMessageSink messageSink) - : base(messageSink) - { } - - protected override ITestFrameworkExecutor CreateExecutor(AssemblyName assemblyName) - => new XunitTestFrameworkExecutorWithAssemblyFixture(assemblyName, SourceInformationProvider, DiagnosticMessageSink); - } -} diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestMethodRunnerWithAssemblyFixture.cs b/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestMethodRunnerWithAssemblyFixture.cs deleted file mode 100644 index 84307112d1d1..000000000000 --- a/src/msbuild/src/Xunit.NetCore.Extensions/AssemblyFixtureSupport/XunitTestMethodRunnerWithAssemblyFixture.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using Xunit.Abstractions; -using Xunit.Sdk; - -#nullable disable - -namespace Xunit.NetCore.Extensions -{ - public class XunitTestMethodRunnerWithAssemblyFixture : XunitTestMethodRunner - { - private readonly Dictionary assemblyFixtureMappings = new Dictionary(); - private readonly List assemblyFixtureAttributes; - - public XunitTestMethodRunnerWithAssemblyFixture(List assemblyFixtureAttributes, - ITestMethod testMethod, - IReflectionTypeInfo @class, - IReflectionMethodInfo method, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource, - object[] constructorArguments) - : base(testMethod, @class, method, testCases, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource, constructorArguments) - { - this.assemblyFixtureAttributes = assemblyFixtureAttributes; - } - - protected override void AfterTestMethodStarting() - { - base.AfterTestMethodStarting(); - - Aggregator.Run(() => - { - // Instantiate all the fixtures - foreach (var fixtureAttr in assemblyFixtureAttributes.Where(a => a.LifetimeScope == AssemblyFixtureAttribute.Scope.Method)) - { - assemblyFixtureMappings[fixtureAttr.FixtureType] = Activator.CreateInstance(fixtureAttr.FixtureType); - } - }); - } - - protected override void BeforeTestMethodFinished() - { - // Make sure we clean up everybody who is disposable, and use Aggregator.Run to isolate Dispose failures - foreach (var disposable in assemblyFixtureMappings.Values.OfType()) - { - Aggregator.Run(disposable.Dispose); - } - - base.BeforeTestMethodFinished(); - } - } -} diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/UseInvariantCultureAttribute.cs b/src/msbuild/src/Xunit.NetCore.Extensions/UseInvariantCultureAttribute.cs index adb3b05ca3a8..dabaebde0da7 100644 --- a/src/msbuild/src/Xunit.NetCore.Extensions/UseInvariantCultureAttribute.cs +++ b/src/msbuild/src/Xunit.NetCore.Extensions/UseInvariantCultureAttribute.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Threading; using Xunit.Sdk; +using Xunit.v3; namespace Xunit.NetCore.Extensions { @@ -15,7 +16,7 @@ public class UseInvariantCultureAttribute : BeforeAfterTestAttribute private CultureInfo? originalCulture; private CultureInfo? originalUICulture; - public override void Before(MethodInfo methodUnderTest) + public override void Before(MethodInfo methodUnderTest, IXunitTest test) { originalCulture = CultureInfo.CurrentCulture; originalUICulture = CultureInfo.CurrentUICulture; @@ -24,7 +25,7 @@ public override void Before(MethodInfo methodUnderTest) CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture; } - public override void After(MethodInfo methodUnderTest) + public override void After(MethodInfo methodUnderTest, IXunitTest test) { if (originalCulture != null) { diff --git a/src/msbuild/src/Xunit.NetCore.Extensions/Xunit.NetCore.Extensions.csproj b/src/msbuild/src/Xunit.NetCore.Extensions/Xunit.NetCore.Extensions.csproj index 01d47500a328..5380e6acb8b3 100644 --- a/src/msbuild/src/Xunit.NetCore.Extensions/Xunit.NetCore.Extensions.csproj +++ b/src/msbuild/src/Xunit.NetCore.Extensions/Xunit.NetCore.Extensions.csproj @@ -1,14 +1,12 @@ - $(LibraryTargetFrameworks) + $(RuntimeOutputTargetFrameworks) false true false - false + false - - + diff --git a/src/source-manifest.json b/src/source-manifest.json index 7d62dcadd8a4..9d514f7ee97a 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -55,10 +55,10 @@ "commitSha": "bd2823e2d07c84f987b4029bce12c19ac10d6a2b" }, { - "barId": 309861, + "barId": 310320, "path": "msbuild", "remoteUri": "https://github.com/dotnet/msbuild", - "commitSha": "e2ae90420b0fe3db1c9321470b2ef53eea9a0ba0" + "commitSha": "12afa005775ca93d50bb26130500785329836788" }, { "barId": 309081,