Unity EditMode Suite #75
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: Calculate test success rate | |
| if: always() | |
| run: | | |
| if [ -n "${{ steps.summary.outputs.total }}" ] && [ "${{ steps.summary.outputs.total }}" != "0" ]; then | |
| total=${{ steps.summary.outputs.total }} | |
| passed=${{ steps.summary.outputs.passed }} | |
| success_rate=$((passed * 100 / total)) | |
| echo "SUCCESS_RATE=$success_rate" >> $GITHUB_ENV | |
| echo "Test success rate: $success_rate% ($passed/$total)" | |
| else | |
| echo "SUCCESS_RATE=0" >> $GITHUB_ENV | |
| echo "No test results available" | |
| fi | |
| - name: Upload test success 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: Tests | |
| message: "${{ env.SUCCESS_RATE }}%" | |
| color: ${{ (env.SUCCESS_RATE >= 95 && 'brightgreen') || (env.SUCCESS_RATE >= 80 && '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 |