diff --git a/.github/workflows/dotnet-build-and-test.yml b/.github/workflows/dotnet-build-and-test.yml index 6a8b4c427b6..e9da557644e 100644 --- a/.github/workflows/dotnet-build-and-test.yml +++ b/.github/workflows/dotnet-build-and-test.yml @@ -26,7 +26,6 @@ concurrency: permissions: contents: read - id-token: "write" jobs: paths-filter: @@ -175,6 +174,9 @@ jobs: dotnet-test: needs: paths-filter if: needs.paths-filter.outputs.dotnetChanges == 'true' + permissions: + contents: read + id-token: "write" strategy: fail-fast: false matrix: @@ -351,7 +353,7 @@ jobs: with: reports: "./TestResults/Coverage/**/*.cobertura.xml" targetdir: "./TestResults/Reports" - reporttypes: "HtmlInline;JsonSummary" + reporttypes: "HtmlInline;JsonSummary;Cobertura" - name: Upload coverage report artifact if: matrix.targetFramework == env.COVERAGE_FRAMEWORK @@ -373,6 +375,31 @@ jobs: path: IntegrationTestResults/**/*.junit if-no-files-found: ignore + dotnet-upload-coverage: + needs: [paths-filter, dotnet-test] + if: needs.paths-filter.outputs.dotnetChanges == 'true' && github.event_name != 'merge_group' && ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]') || (github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch)) + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + code-quality: write + pull-requests: read + steps: + - name: Download coverage report artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: CoverageReport-ubuntu-latest-${{ env.COVERAGE_FRAMEWORK }}-Release + path: ./TestResults/Reports + - name: Upload coverage report to GitHub + uses: actions/upload-code-coverage@d8e329117199404bba6fc81efe8093dc7c015e34 # v1.4.2 + with: + file: ./TestResults/Reports/Cobertura.xml + language: CSharp + label: code-coverage/dotnet + fail-on-error: false + - name: Summarize GitHub coverage report + run: echo ".NET coverage is uploaded to GitHub's integrated coverage report with label \`code-coverage/dotnet\`." >> "$GITHUB_STEP_SUMMARY" + # The Foundry hosted-agent IT is costly (it builds a container, pushes to ACR, and provisions # live agents on a separate Foundry project). Running it in its own job keeps the overall # workflow time roughly flat: it executes in parallel to dotnet-build and dotnet-test and is @@ -380,6 +407,9 @@ jobs: dotnet-foundry-hosted-it: needs: paths-filter if: github.event_name != 'pull_request' && needs.paths-filter.outputs.foundryHostingChanges == 'true' + permissions: + contents: read + id-token: "write" runs-on: ubuntu-latest environment: integration env: diff --git a/.github/workflows/python-test-coverage-report.yml b/.github/workflows/python-test-coverage-report.yml deleted file mode 100644 index 770537001fc..00000000000 --- a/.github/workflows/python-test-coverage-report.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Python - Test Coverage Report - -on: - workflow_run: - workflows: ["Python - Test Coverage"] - types: - - completed - -permissions: - contents: read - actions: read - pull-requests: write - -jobs: - python-test-coverage-report: - runs-on: ubuntu-latest - if: github.event.workflow_run.conclusion == 'success' - continue-on-error: false - defaults: - run: - working-directory: python - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Download coverage report - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - github-token: ${{ github.token }} - run-id: ${{ github.event.workflow_run.id }} - path: ./python - merge-multiple: true - - name: Display structure of downloaded files - run: ls - - name: Read and validate PR number - # Keep the artifact handoff aligned with the workflow run that produced it. - env: - GH_TOKEN: ${{ github.token }} - REPO: ${{ github.repository }} - RUN_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} - run: | - if [ ! -s pr_number ]; then - echo "PR number file 'pr_number' is missing or empty" - exit 1 - fi - - ARTIFACT_PR_NUMBER=$(cat pr_number) - if ! [[ "$ARTIFACT_PR_NUMBER" =~ ^[0-9]+$ ]]; then - echo "::error::PR number file contains invalid content" - exit 1 - fi - - PR_HEAD_SHA=$(gh pr view "$ARTIFACT_PR_NUMBER" --repo "$REPO" --json headRefOid --jq '.headRefOid') - if [ "$PR_HEAD_SHA" != "$RUN_HEAD_SHA" ]; then - echo "::error::PR head SHA does not match the triggering workflow run" - exit 1 - fi - - echo "PR_NUMBER=$ARTIFACT_PR_NUMBER" >> "$GITHUB_ENV" - - name: Pytest coverage comment - id: coverageComment - uses: MishaKav/pytest-coverage-comment@dd5b80bde6d16941f336518e92929e89069d8451 # v1.7.2 - with: - github-token: ${{ github.token }} - issue-number: ${{ env.PR_NUMBER }} - pytest-xml-coverage-path: python/python-coverage.xml - title: "Python Test Coverage Report" - badge-title: "Python Test Coverage" - junitxml-title: "Python Unit Test Overview" - junitxml-path: python/pytest.xml - default-branch: "main" - report-only-changed-files: true diff --git a/.github/workflows/python-test-coverage.yml b/.github/workflows/python-test-coverage.yml index ea9b4efaec4..e1c38fabb1e 100644 --- a/.github/workflows/python-test-coverage.yml +++ b/.github/workflows/python-test-coverage.yml @@ -9,12 +9,23 @@ on: - "python/scripts/workspace_poe_tasks.py" - ".github/scripts/python_check_coverage.py" - ".github/workflows/python-test-coverage.yml" + push: + branches: ["main"] + paths: + - "python/packages/**" + - "python/tests/unit/**" + - "python/scripts/workspace_poe_tasks.py" + - ".github/scripts/python_check_coverage.py" + - ".github/workflows/python-test-coverage.yml" env: # Configure a constant location for the uv cache UV_CACHE_DIR: /tmp/.uv-cache # Coverage threshold percentage for enforced modules COVERAGE_THRESHOLD: 85 +permissions: + contents: read + jobs: python-tests-coverage: runs-on: ubuntu-latest @@ -26,11 +37,6 @@ jobs: UV_PYTHON: "3.11" steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - # Save the PR number to a file since the workflow_run event - # in the coverage report workflow does not have access to it - - name: Save PR number - run: | - echo ${{ github.event.number }} > ./pr_number - name: Set up python and install the project id: python-setup uses: ./.github/actions/python-setup @@ -41,16 +47,38 @@ jobs: # Configure a constant location for the uv cache UV_CACHE_DIR: /tmp/.uv-cache - name: Run aggregate tests with coverage report - run: uv run poe test -A -C --cov-report=xml:python-coverage.xml -q --junitxml=pytest.xml + run: uv run poe test -A -C --cov-report=xml:python-coverage.xml -q - name: Check coverage threshold run: python ${{ github.workspace }}/.github/scripts/python_check_coverage.py python-coverage.xml ${{ env.COVERAGE_THRESHOLD }} - name: Upload coverage report uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: + name: python-coverage-report path: | python/python-coverage.xml - python/pytest.xml - python/pr_number overwrite: true retention-days: 1 if-no-files-found: error + + python-upload-coverage: + needs: python-tests-coverage + if: github.event_name != 'merge_group' && ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]') || (github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch)) + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + code-quality: write + pull-requests: read + steps: + - name: Download coverage report + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: python-coverage-report + path: python + - name: Upload coverage report to GitHub + uses: actions/upload-code-coverage@d8e329117199404bba6fc81efe8093dc7c015e34 # v1.4.2 + with: + file: python/python-coverage.xml + language: Python + label: code-coverage/python + fail-on-error: false