356 lines
12 KiB
YAML

# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Build and test
on:
workflow_call:
inputs:
timeout:
description: 'Timeout for runServer (seconds)'
required: false
default: 90
type: number
workspace:
description: 'setupCIWorkspace/setupDecompWorkspace'
required: false
default: "setupCIWorkspace"
type: string
client-only:
description: 'Do not execute runServer'
required: false
default: false
type: boolean
disable-server-auto-stop:
description: 'Do not automatically stop runServer by writing "stop" to stdin'
required: false
default: false
type: boolean
disable-spotless-pr:
description: 'Do not run spotless PR task'
required: false
default: false
type: boolean
horizonqa:
description: 'Run Horizon-QA in CI mode during runServer'
required: false
default: false
type: boolean
horizonqa-tests:
description: 'Optional -Dhorizonqa.tests selector'
required: false
default: ''
type: string
horizonqa-allow-no-tests:
description: 'Allow Horizon-QA CI to pass with no discovered tests'
required: false
default: false
type: boolean
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build-and-test:
runs-on: ubuntu-24.04
steps:
- name: Install Ubuntu dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y mesa-utils xvfb x11-xserver-utils
- name: Checkout mod repo
uses: actions/checkout@v5
with:
fetch-depth: 0
submodules: recursive
- name: Checkout workflows repo
uses: actions/checkout@v5
with:
repository: ${{ job.workflow_repository }}
ref: ${{ job.workflow_sha }}
path: .gtnh-workflows
fetch-depth: 0
- name: Determine JDK versions
id: list-jdk-versions
shell: bash
run: |
(
echo 'java-versions<<EOF'
echo 8
echo 17
echo 21
if [[ -f gradle/gradle-daemon-jvm.properties ]]; then
yq -pprops -oprops '.toolchainVersion' gradle/gradle-daemon-jvm.properties
fi
echo EOF
) | tee -a "${GITHUB_OUTPUT}"
- name: Set up JDK versions
uses: actions/setup-java@v5
with:
java-version: ${{ steps.list-jdk-versions.outputs.java-versions }}
distribution: 'zulu'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
with:
build-scan-publish: true
build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-use-agree: "yes"
validate-wrappers: true
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup the workspace
run: ./gradlew --build-cache --info --stacktrace ${{ inputs.workspace }}
- name: Compile the mod
run: ./gradlew --build-cache --info --stacktrace assemble
- name: Run post-build checks
id: build_mod
run: xvfb-run --server-args="-screen 0 1366x768x24" ./gradlew --build-cache --info --stacktrace build
- name: Attach gradle reports
if: failure() && steps.build_mod.conclusion == 'failure'
uses: actions/upload-artifact@v7
continue-on-error: true
with:
name: ${{ github.repository_id }}-reports
path: build/reports/
retention-days: 90
- name: Attempt to make a PR fixing spotless errors
if: >-
${{ !inputs.disable-spotless-pr &&
failure() && steps.build_mod.conclusion == 'failure' &&
github.event_name == 'pull_request' &&
!github.event.pull_request.draft &&
github.event.pull_request.head.repo.full_name == github.repository }}
run: |
git reset --hard
git checkout "${PR_BRANCH}"
./gradlew --build-cache --info --stacktrace spotlessApply || exit 1
git diff --exit-code && exit 1
git config user.name "GitHub GTNH Actions"
git config user.email "<>"
git switch -c "${FIXED_BRANCH}"
git commit -am "spotlessApply"
git push --force-with-lease origin "${FIXED_BRANCH}"
gh pr create \
--head "${FIXED_BRANCH}" \
--base "${PR_BRANCH}" \
--title "Spotless apply for branch ${PR_BRANCH} for #${{ github.event.pull_request.number }}" \
--body "Automatic spotless apply to fix formatting errors, applies to PR #${{ github.event.pull_request.number }}" \
2>&1 | tee pr-message.log || true
gh pr comment "${PR_BRANCH}" -F pr-message.log || true
shell: bash # ensures set -eo pipefail
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_BRANCH: ${{ github.head_ref }}
FIXED_BRANCH: ${{ github.head_ref }}-spotless-fixes
- name: Run server for up to ${{ inputs.timeout }} seconds
id: run_server
if: ${{ !inputs.client-only }}
shell: bash
env:
HORIZONQA: ${{ inputs.horizonqa }}
HORIZONQA_TESTS: ${{ inputs.horizonqa-tests }}
HORIZONQA_ALLOW_NO_TESTS: ${{ inputs.horizonqa-allow-no-tests }}
DISABLE_SERVER_AUTO_STOP: ${{ inputs.disable-server-auto-stop }}
run: |
mkdir -p run/server
echo "eula=true" > run/eula.txt
echo "eula=true" > run/server/eula.txt
# Set a constant seed with a village at spawn
echo "level-seed=-6202107849386030209\nonline-mode=true\n" > run/server.properties
echo "level-seed=-6202107849386030209\nonline-mode=true\n" > run/server/server.properties
gradle_args=(--build-cache --info --stacktrace runServer)
if [[ "${HORIZONQA}" == "true" ]]; then
horizonqa_jvm_args=(
"-Dhorizonqa.mode=ci"
"-Dhorizonqa.reportDir=${GITHUB_WORKSPACE}/build/horizonqa"
)
if [[ -n "${HORIZONQA_TESTS}" ]]; then
horizonqa_jvm_args+=("-Dhorizonqa.tests=${HORIZONQA_TESTS}")
fi
if [[ "${HORIZONQA_ALLOW_NO_TESTS}" == "true" ]]; then
horizonqa_jvm_args+=("-Dhorizonqa.allowNoTests=true")
fi
for jvm_arg in "${horizonqa_jvm_args[@]}"; do
gradle_args+=(--mcJvmArgs="${jvm_arg}")
done
fi
server_stdin=/dev/null
if [[ "${DISABLE_SERVER_AUTO_STOP}" != "true" && "${HORIZONQA}" != "true" ]]; then
echo "stop" > run/stop.txt
server_stdin=run/stop.txt
fi
timeout ${{ inputs.timeout }} ./gradlew "${gradle_args[@]}" 2>&1 < "${server_stdin}" | tee -a server.log || true
- name: Upload Horizon-QA reports
if: ${{ always() && !inputs.client-only && inputs.horizonqa && steps.run_server.conclusion != 'skipped' }}
uses: actions/upload-artifact@v7
continue-on-error: true
with:
name: ${{ github.repository_id }}-horizonqa
path: build/horizonqa/
retention-days: 90
- name: Summarize Horizon-QA result
if: ${{ always() && !inputs.client-only && inputs.horizonqa && steps.run_server.conclusion != 'skipped' }}
shell: bash
continue-on-error: true
run: |
chmod +x .gtnh-workflows/scripts/summarize_horizonqa_result
.gtnh-workflows/scripts/summarize_horizonqa_result
- name: Test no errors reported during server run
id: server_errors
if: ${{ !inputs.client-only }}
run: |
chmod +x .gtnh-workflows/scripts/test_no_error_reports
.gtnh-workflows/scripts/test_no_error_reports
- name: Test Horizon-QA result
if: ${{ always() && !inputs.client-only && inputs.horizonqa && steps.run_server.conclusion != 'skipped' && steps.server_errors.conclusion == 'success' }}
shell: bash
run: |
chmod +x .gtnh-workflows/scripts/test_horizonqa_result
.gtnh-workflows/scripts/test_horizonqa_result
- name: Test no prerelease dependencies used
run: |
! grep -P -- "-pre(?!shadow)" dependencies.gradle*
# See https://github.com/GTNewHorizons/GT5-Unofficial/pull/4880
- name: Make sure asset files are not overoptimized
run: |
echo "Checking for grayscale asset files which are not supported by the java8 image loader"
fail=0
set -o pipefail
while IFS= read -r -d $'\n' file; do
if $(file --brief -- "$file" | grep -q grayscale); then
printf "found grayscale image '%s'\n" "$file"
fail=1
fi
done < <(gh pr diff --name-only "${PR_NUMBER}" | grep 'src/main/resources/.*\.png$')
exit $fail
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
- name: Attach compilation artifacts as ZIP
uses: actions/upload-artifact@v7
with:
name: ${{ github.repository_id }}-build-libs
path: build/libs/
retention-days: 90
- name: Find individual compilation artifacts
id: find-artifacts
shell: bash
run: |
mapfile -t files < <(find build/libs -maxdepth 1 -type f -name '*.jar' | sort)
if (( ${#files[@]} > 10 )); then
echo "::warning::Found ${#files[@]} files in build/libs, but only the first 10 will be uploaded individually."
fi
for i in {0..9}; do
if [[ -n "${files[$i]:-}" ]]; then
echo "file_${i}=${files[$i]}" >> "$GITHUB_OUTPUT"
fi
done
- name: Upload individual compilation artifact 1
if: ${{ steps.find-artifacts.outputs.file_0 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_0 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 2
if: ${{ steps.find-artifacts.outputs.file_1 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_1 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 3
if: ${{ steps.find-artifacts.outputs.file_2 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_2 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 4
if: ${{ steps.find-artifacts.outputs.file_3 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_3 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 5
if: ${{ steps.find-artifacts.outputs.file_4 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_4 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 6
if: ${{ steps.find-artifacts.outputs.file_5 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_5 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 7
if: ${{ steps.find-artifacts.outputs.file_6 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_6 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 8
if: ${{ steps.find-artifacts.outputs.file_7 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_7 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 9
if: ${{ steps.find-artifacts.outputs.file_8 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_8 }}
retention-days: 90
archive: false
- name: Upload individual compilation artifact 10
if: ${{ steps.find-artifacts.outputs.file_9 != '' }}
uses: actions/upload-artifact@v7
with:
path: ${{ steps.find-artifacts.outputs.file_9 }}
retention-days: 90
archive: false