🚀 ci: publish coverage badge and docs badge #68
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json | ||
| name: Unity EditMode Suite | ||
| on: | ||
| pull_request: | ||
| workflow_dispatch: | ||
| permissions: | ||
| contents: read | ||
| checks: write | ||
| issues: write | ||
| pull-requests: write | ||
| statuses: write | ||
| concurrency: | ||
| group: unity-editmode-${{ github.ref }} | ||
| cancel-in-progress: true | ||
| env: | ||
| UNITY_VERSION: 6000.2.5f1 | ||
| PROJECT_PATH: . | ||
| TEST_PLATFORM: EditMode | ||
| UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
| UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
| UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
| jobs: | ||
| editmode: | ||
| env: | ||
| UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
| UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
| UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
| name: EditMode Regression | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 40 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| lfs: true | ||
| fetch-depth: 0 | ||
| - name: Guard license secret | ||
| if: ${{ env.UNITY_LICENSE == '' }} | ||
| run: | | ||
| echo "::error::UNITY_LICENSE secret is required for EditMode automation." >&2 | ||
| exit 1 | ||
| - name: Cache Library | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: Library | ||
| key: ${{ runner.os }}-unity-${{ env.UNITY_VERSION }}-${{ hashFiles('Packages/packages-lock.json') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-unity-${{ env.UNITY_VERSION }}- | ||
| - name: Run EditMode Tests | ||
| id: run-tests | ||
| continue-on-error: true | ||
| uses: game-ci/unity-test-runner@v4 | ||
| env: | ||
| UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
| UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
| UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
| with: | ||
| githubToken: ${{ secrets.GITHUB_TOKEN }} | ||
| projectPath: ${{ env.PROJECT_PATH }} | ||
| unityVersion: ${{ env.UNITY_VERSION }} | ||
| testMode: ${{ env.TEST_PLATFORM }} | ||
| artifactsPath: Artifacts | ||
| coverageOptions: generateAdditionalMetrics;generateHtmlReport;generateBadgeReport | ||
| customImage: unityci/editor:ubuntu-6000.2.5f1-webgl-3.1 | ||
| customParameters: -enableCodeCoverage -coverageResultsPath Artifacts/coverage -coverageHistoryPath Artifacts/coverage-history -assemblyFilters +Soobak.Algo.* | ||
| - name: Publish Artifacts | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: editmode-suite | ||
| path: Artifacts | ||
| - name: Surface Test Results | ||
| id: summarize | ||
| if: always() | ||
| shell: pwsh | ||
| run: | | ||
| $resultFile = Get-ChildItem -Path Artifacts -Recurse -Filter editmode-results.xml -ErrorAction SilentlyContinue | Select-Object -First 1 | ||
| if ($resultFile) { | ||
| [xml]$report = Get-Content $resultFile.FullName | ||
| $node = $report.'test-run' | ||
| if ($node) { | ||
| $attrs = $node.Attributes | ||
| $total = $attrs['total'].Value | ||
| $passed = $attrs['passed'].Value | ||
| $failed = $attrs['failed'].Value | ||
| $skipped = $attrs['skipped'].Value | ||
| $result = $attrs['result'].Value | ||
| Write-Host "::notice::Tests Total=$total Passed=$passed Failed=$failed Skipped=$skipped Result=$result" | ||
| "total=$total" | Out-File -FilePath summary.env -Encoding utf8 | ||
| "passed=$passed" | Out-File -FilePath summary.env -Encoding utf8 -Append | ||
| "failed=$failed" | Out-File -FilePath summary.env -Encoding utf8 -Append | ||
| "skipped=$skipped" | Out-File -FilePath summary.env -Encoding utf8 -Append | ||
| "overall=$result" | Out-File -FilePath summary.env -Encoding utf8 -Append | ||
| } else { | ||
| Write-Host "::notice::editmode-results.xml located at $($resultFile.FullName)" | ||
| } | ||
| } else { | ||
| Write-Warning 'editmode-results.xml not generated.' | ||
| } | ||
| env: | ||
| ACTIONS_STEP_DEBUG: ${{ runner.debug }} | ||
| - name: Load summary | ||
| if: always() && ${{ hashFiles('summary.env') != '' }} | ||
| shell: pwsh | ||
| run: | | ||
| Get-Content summary.env | ForEach-Object { | ||
| if ($_ -match '^(.*?)=(.*)$') { | ||
| $name = $matches[1] | ||
| $value = $matches[2] | ||
| echo "$name=$value" >> $env:GITHUB_OUTPUT | ||
| } | ||
| } | ||
| id: summary | ||
| - name: Extract coverage percentage | ||
| if: always() | ||
| run: | | ||
| if [ -f Artifacts/coverage/Report/Summary.xml ]; then | ||
| percent=$(python - <<'PYCODE' | ||
| import xml.etree.ElementTree as ET | ||
| root = ET.parse('Artifacts/coverage/Report/Summary.xml').getroot() | ||
| node = root.find('.//coverage') | ||
| print(float(node.get('percent')) if node is not None else 0.0) | ||
| PYCODE | ||
| ) | ||
| echo "COVERAGE=$percent" >> $GITHUB_ENV | ||
| else | ||
| echo 'Coverage summary not found, defaulting to 0' | ||
| echo 'COVERAGE=0' >> $GITHUB_ENV | ||
| fi | ||
| - name: Upload coverage badge | ||
| if: always() | ||
| uses: schneegans/dynamic-badges-action@v1.7.0 | ||
| with: | ||
| auth: ${{ secrets.BADGE_GIST_TOKEN }} | ||
| gistID: 21437d3f33ae019a0b58a88a2bf90c56 | ||
| filename: sorting-algo-core-coverage.json | ||
| label: Coverage | ||
| message: "${{ env.COVERAGE }}%" | ||
| color: ${{ (env.COVERAGE >= 80 && 'brightgreen') || (env.COVERAGE >= 60 && 'yellow') || 'red' }} | ||
| - name: Post PR Comment | ||
| if: ${{ github.event_name == 'pull_request' && steps.summary.outputs.total != '' && github.event.pull_request.head.repo.full_name == github.repository }} | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| script: | | ||
| const {total, passed, failed, skipped, overall} = { | ||
| total: '${{ steps.summary.outputs.total }}', | ||
| passed: '${{ steps.summary.outputs.passed }}', | ||
| failed: '${{ steps.summary.outputs.failed }}', | ||
| skipped: '${{ steps.summary.outputs.skipped }}', | ||
| overall: '${{ steps.summary.outputs.overall }}', | ||
| }; | ||
| const body = `<!-- unity-editmode-suite -->\n### Unity EditMode Suite\nStatus: **${overall}**\nTotal=${total}, Passed=${passed}, Failed=${failed}, Skipped=${skipped}\n- Workflow: [View Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\n- Artifacts: \`editmode-suite\``; | ||
| const prNumber = context.payload.pull_request?.number; | ||
| if (!prNumber) { | ||
| core.warning('No PR number available to comment.'); | ||
| return; | ||
| } | ||
| const comments = await github.paginate(github.rest.issues.listComments, { | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| }, response => response.data); | ||
| const existing = comments.find(comment => comment.body && comment.body.includes('<!-- unity-editmode-suite -->')); | ||
| if (existing) { | ||
| await github.rest.issues.updateComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| comment_id: existing.id, | ||
| body, | ||
| }); | ||
| } else { | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| body, | ||
| }); | ||
| } | ||
| - name: Fail on Test Failure | ||
| if: ${{ steps.run-tests.outcome == 'failure' }} | ||
| run: | | ||
| echo "Unity EditMode tests failed." >&2 | ||
| exit 1 | ||