Bump gradle-wrapper from 9.0.0 to 9.6.1 #31
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
| name: Integration tests on demand | |
| # Manually triggered by commenting on an open PR with a slash-command on | |
| # the FIRST line of the comment body (everything after the first line is | |
| # ignored): | |
| # /integrationtest → JDK 17 only | |
| # /integrationtestfull → full matrix {17, 21, 25} | |
| # | |
| # The slash + first-line constraint prevents accidental triggers from | |
| # review comments that mention the workflow by name, quoted replies | |
| # (`> /integrationtest`), pasted documentation, or stack traces. The | |
| # Guard job below filters on `startsWith(... '/integrationtest')` and | |
| # then a strict bash `case` validates the exact command — anything that | |
| # slips through is rejected before any live-API request is made. | |
| # | |
| # Integration tests hit the live Market Data API, so we don't run them | |
| # automatically on every PR open/sync (saves API quota + CI minutes). | |
| # They ARE required for merge — branch protection on `main` should list | |
| # "Integration tests pass" as a required status check, which is the | |
| # aggregator job below. PRs cannot merge until a reviewer comments one | |
| # of the two slash-commands AND the resulting run is green. | |
| # | |
| # Important security note: workflows triggered by `issue_comment` always | |
| # run from the *default branch's* version of the workflow file, not from | |
| # the PR. Adding/changing this file on a feature branch has no effect | |
| # until it lands on main. | |
| on: | |
| issue_comment: | |
| types: [created] | |
| permissions: | |
| contents: read | |
| pull-requests: write # to react and post the result comment | |
| # Multiple trigger comments on the same PR cancel earlier runs. | |
| concurrency: | |
| group: pr-integration-on-demand-${{ github.event.issue.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| guard: | |
| name: Guard | |
| runs-on: ubuntu-latest | |
| # Only fire on PR comments whose body starts with `/integrationtest`. | |
| # `startsWith` rejects comments that merely mention the command in | |
| # passing (quoted replies start with `>`, prose with anything else, | |
| # so they don't match). The strict `case` in the matrix step below | |
| # rejects anything that slips through (e.g. `/integrationtest-foo`) | |
| # before any live-API request fires. | |
| if: | | |
| github.event.issue.pull_request != null && | |
| startsWith(github.event.comment.body, '/integrationtest') | |
| outputs: | |
| head_sha: ${{ steps.pr.outputs.head_sha }} | |
| jdks: ${{ steps.matrix.outputs.jdks }} | |
| mode: ${{ steps.matrix.outputs.mode }} | |
| steps: | |
| - name: Verify commenter has write permission | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| username: context.payload.comment.user.login, | |
| }); | |
| const allowed = ['write', 'maintain', 'admin'].includes(perm.permission); | |
| if (!allowed) { | |
| core.setFailed( | |
| `@${context.payload.comment.user.login} (${perm.permission}) ` + | |
| `cannot trigger integration tests; write access required.` | |
| ); | |
| } | |
| - name: React 👀 to the trigger comment | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.reactions.createForIssueComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| content: 'eyes', | |
| }); | |
| - name: Resolve PR head SHA | |
| id: pr | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.payload.issue.number, | |
| }); | |
| if (pr.state !== 'open') { | |
| core.setFailed(`PR #${pr.number} is ${pr.state}; refusing to run.`); | |
| return; | |
| } | |
| core.setOutput('head_sha', pr.head.sha); | |
| - name: Decide JDK matrix from comment body | |
| id: matrix | |
| env: | |
| BODY: ${{ github.event.comment.body }} | |
| run: | | |
| # The if: filter above only guarantees the body starts with | |
| # '/integrationtest'. We still need to disambiguate single vs | |
| # full and reject anything that just shares the prefix | |
| # (e.g. '/integrationtest-foo' or '/integrationtestlong'). | |
| # Match on the first line only — trailing context in the | |
| # comment body is ignored. | |
| first_line=$(printf '%s' "$BODY" | head -n 1 | tr -d '[:space:]') | |
| case "$first_line" in | |
| /integrationtest) | |
| echo 'jdks=["17"]' >> "$GITHUB_OUTPUT" | |
| echo 'mode=single' >> "$GITHUB_OUTPUT" | |
| echo "Trigger: /integrationtest → JDK 17" | |
| ;; | |
| /integrationtestfull) | |
| echo 'jdks=["17","21","25"]' >> "$GITHUB_OUTPUT" | |
| echo 'mode=full' >> "$GITHUB_OUTPUT" | |
| echo "Trigger: /integrationtestfull → matrix {17, 21, 25}" | |
| ;; | |
| *) | |
| echo "::error::Unrecognized command on first line: '$first_line' (expected '/integrationtest' or '/integrationtestfull')" | |
| exit 1 | |
| ;; | |
| esac | |
| integration-tests: | |
| name: Integration tests (JDK ${{ matrix.java }}) | |
| needs: guard | |
| runs-on: ubuntu-latest | |
| strategy: | |
| # Don't cancel siblings: if JDK 21 fails, we still want 17 and 25 | |
| # results to surface. | |
| fail-fast: false | |
| matrix: | |
| java: ${{ fromJSON(needs.guard.outputs.jdks) }} | |
| steps: | |
| # Check out exactly the PR's HEAD commit so we test the proposed | |
| # change, not the merge ref. | |
| - name: Checkout PR head | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.guard.outputs.head_sha }} | |
| # Order matters: JDK 17 must be last so JAVA_HOME=17 (Gradle 8.12 | |
| # only supports JDKs up to 23 as its daemon runtime). The matrix | |
| # JDK is still installed and registered as a toolchain target. | |
| - name: Set up JDKs (test=${{ matrix.java }}, compile/daemon=17) | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: | | |
| ${{ matrix.java }} | |
| 17 | |
| - name: Set up Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| - name: Run integration tests against live API | |
| env: | |
| MARKETDATA_TOKEN: ${{ secrets.MARKETDATA_TOKEN }} | |
| MARKETDATA_RUN_INTEGRATION_TESTS: 'true' | |
| run: | | |
| if [ -z "$MARKETDATA_TOKEN" ]; then | |
| echo "::error::MARKETDATA_TOKEN secret missing — cannot run integration tests." | |
| exit 1 | |
| fi | |
| ./gradlew integrationTest -PtestJdk=${{ matrix.java }} --stacktrace | |
| - name: Upload integration-test reports on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: integration-test-reports-jdk${{ matrix.java }} | |
| path: | | |
| build/reports/tests/integrationTest/ | |
| build/test-results/integrationTest/ | |
| retention-days: 14 | |
| # Aggregator job. Branch protection on `main` should require this | |
| # check name ("Integration tests pass") so a single required check | |
| # covers both `integrationtest` (matrix=[17]) and `integrationtestfull` | |
| # (matrix=[17,21,25]) modes uniformly. Without this, branch protection | |
| # would have to list the per-matrix-entry check names which only exist | |
| # in the `full` mode. | |
| required-check: | |
| name: Integration tests pass | |
| needs: [guard, integration-tests] | |
| if: always() && needs.guard.result == 'success' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Aggregate matrix outcome | |
| env: | |
| MATRIX_RESULT: ${{ needs.integration-tests.result }} | |
| MODE: ${{ needs.guard.outputs.mode }} | |
| run: | | |
| echo "Mode: $MODE" | |
| echo "Matrix outcome: $MATRIX_RESULT" | |
| if [[ "$MATRIX_RESULT" != "success" ]]; then | |
| echo "::error::One or more integration-test JDK entries failed." | |
| exit 1 | |
| fi | |
| echo "All integration tests passed." | |
| - name: Comment outcome on the PR | |
| if: always() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const ok = '${{ needs.integration-tests.result }}' === 'success'; | |
| const mode = '${{ needs.guard.outputs.mode }}'; | |
| const emoji = ok ? '✅' : '❌'; | |
| const status = ok ? 'passed' : 'failed'; | |
| const matrix = mode === 'full' ? '`{17, 21, 25}`' : '`17`'; | |
| const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.payload.issue.number, | |
| body: `${emoji} On-demand integration tests on JDK ${matrix} ${status}. [View run](${runUrl}).`, | |
| }); |