Skip to content

Derive supported versions from versions/, resolve deps from Modrinth #211

Derive supported versions from versions/, resolve deps from Modrinth

Derive supported versions from versions/, resolve deps from Modrinth #211

Workflow file for this run

name: build
on: push
permissions:
contents: write
pull-requests: write
jobs:
matrices:
name: compute matrices
runs-on: ubuntu-24.04
outputs:
build: ${{ steps.gen.outputs.build }}
launch: ${{ steps.gen.outputs.launch }}
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: generate matrices
id: gen
run: bash .github/scripts/generate-matrices.sh
build:
name: build mc${{ matrix.mc }}
runs-on: ubuntu-24.04
needs: matrices
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.matrices.outputs.build) }}
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: validate gradle wrapper
uses: gradle/actions/wrapper-validation@v6
- name: setup jdk ${{ matrix.java }}
uses: actions/setup-java@v5
with:
java-version: ${{ matrix.java }}
distribution: 'microsoft'
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: build :${{ matrix.mc }}:build
run: ./gradlew :${{ matrix.mc }}:build --stacktrace
- name: upload jar
uses: actions/upload-artifact@v7
with:
name: betterhud-mc${{ matrix.mc }}
path: versions/${{ matrix.mc }}/build/libs/*.jar
launch-test:
name: launch mc${{ matrix.mc }}
runs-on: ubuntu-24.04
needs: matrices
timeout-minutes: 40
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.matrices.outputs.launch) }}
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: validate gradle wrapper
uses: gradle/actions/wrapper-validation@v6
- name: setup jdk ${{ matrix.java }}
uses: actions/setup-java@v5
with:
java-version: ${{ matrix.java }}
distribution: 'microsoft'
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: install xvfb
run: sudo apt-get update && sudo apt-get install -y xvfb
- name: generate singleplayer test world
run: bash .github/scripts/generate-test-world.sh ${{ matrix.mc }}
- name: launch minecraft ${{ matrix.mc }} with mod
run: ./gradlew :launchtest:runLaunchTest -PtestMcVersion=${{ matrix.mc }} --stacktrace
- name: check survival world screenshot was taken
run: test -n "$(find src/launchtest/run/screenshots -name 'betterhud-survival-world.png' -print -quit 2>/dev/null)"
- name: upload screenshots
if: always()
uses: actions/upload-artifact@v7
with:
name: launch-screenshots-mc${{ matrix.mc }}
path: src/launchtest/run/screenshots/
if-no-files-found: ignore
- name: upload game logs
if: always()
uses: actions/upload-artifact@v7
with:
name: launch-logs-mc${{ matrix.mc }}
path: src/launchtest/run/logs/
if-no-files-found: ignore
screenshot-report:
name: screenshot report
runs-on: ubuntu-24.04
needs: launch-test
if: ${{ always() }}
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: publish screenshots to the ci-screenshots branch
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash .github/scripts/publish-screenshots.sh
- name: post screenshot grid to pull request and job summary
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const dir = `screenshots-publish/${context.sha}`;
const base = `https://raw.githubusercontent.com/${context.repo.owner}/${context.repo.repo}/ci-screenshots/${context.sha}`;
const versions = fs.existsSync(dir)
? fs.readdirSync(dir)
.filter(f => f.startsWith('mc-') && f.endsWith('-survival.png'))
.map(f => f.slice(3, -13))
.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))
: [];
const cells = versions.map(v => {
const file = `mc-${v}-survival.png`;
return `<td align="center"><b>${v}</b><br><a href="${base}/${file}"><img src="${base}/${file}" width="200" alt="BetterHUD on Minecraft ${v}"></a></td>`;
});
let rows = '';
for (let i = 0; i < cells.length; i += 4) {
rows += `<tr>${cells.slice(i, i + 4).join('')}</tr>\n`;
}
const marker = '<!-- betterhud-launch-screenshots -->';
const body = [
marker,
`The game launched and entered a survival singleplayer world with the HUD active, for \`${context.sha.slice(0, 7)}\`. A missing version means its launch test did not produce a screenshot — check its job. Game logs are in the run artifacts.`,
'',
`<table>\n${rows}</table>`,
].join('\n');
await core.summary.addRaw(body).write();
const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: context.sha,
});
const pr = prs.find(p => p.state === 'open');
if (!pr) {
core.info('No open pull request for this commit, skipping comment');
return;
}
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner, repo: context.repo.repo,
issue_number: pr.number, per_page: 100,
});
const existing = comments.find(c => c.body && c.body.includes(marker));
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: pr.number, body,
});
}
modrinth-bundle:
name: modrinth bundle
runs-on: ubuntu-24.04
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: validate gradle wrapper
uses: gradle/actions/wrapper-validation@v6
- name: setup jdk 21 and 25
uses: actions/setup-java@v5
with:
java-version: |
21
25
distribution: 'microsoft'
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: build all variants and write the upload guide
run: ./gradlew modrinthBundle --stacktrace "-Porg.gradle.java.installations.paths=$JAVA_HOME_21_X64,$JAVA_HOME_25_X64"
- name: upload modrinth bundle
uses: actions/upload-artifact@v7
with:
name: modrinth-upload
path: build/modrinth/