Skip to content

Bump com.vanniktech.maven.publish from 0.30.0 to 0.37.0 #43

Bump com.vanniktech.maven.publish from 0.30.0 to 0.37.0

Bump com.vanniktech.maven.publish from 0.30.0 to 0.37.0 #43

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@v9
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@v9
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@v9
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@v7
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@v9
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}).`,
});