Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/dependencies.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
791bc29301b4250a0f7ef3053a1999ace7e2ff0ddae8e79ff52bef0fee8034ed libs/vehicleframework-1.1.12.jar
0fedc530aaa9cd9e0a452d0bde95fb9fa0ecc31564ec625e3a0e2cef57c0aec8 libs/rpcharacters-1.1.7.jar
64ea06ea92bf22785e6d541dd1b5f550edcdc4610d7a9748a91d715876ac079d libs/advancedcrafting-1.2.1.jar
5185b9e0ea8653ab61da07304f1573c6a9a5af97cf55a5d970c5a25f16bc743d libs/simplefactions-2.8.7.jar
a3f86a50d38296dd0a91d375f0a9433192e6e8d3e9dcae2751c801e67d24d9cd libs/MythicLib-dist-1.7.1.jar
14850d7454374d7312305d3e84a391be720301e5964963f869b27ae97f6264eb libs/MMOCore-1.13.1.jar
12 changes: 12 additions & 0 deletions .github/scripts/prepare-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail
: "${GH_TOKEN:?Set DEPS_TOKEN with Contents read access to TF-Minecraft/ServerAssets}"
ref=8a44414cd5b74b7d1c7a258ccf5a86a5f6e0294b
mkdir -p libs
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/791bc29301b4/vehicleframework-1.1.12.jar?ref=$ref" > "libs/vehicleframework-1.1.12.jar"
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/0fedc530aaa9/rpcharacters-1.1.7.jar?ref=$ref" > "libs/rpcharacters-1.1.7.jar"
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/64ea06ea92bf/advancedcrafting-1.2.1.jar?ref=$ref" > "libs/advancedcrafting-1.2.1.jar"
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/5185b9e0ea86/simplefactions-2.8.7.jar?ref=$ref" > "libs/simplefactions-2.8.7.jar"
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/a3f86a50d382/MythicLib-dist-1.7.1.jar?ref=$ref" > "libs/MythicLib-dist-1.7.1.jar"
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/14850d745437/MMOCore-1.13.1.jar?ref=$ref" > "libs/MMOCore-1.13.1.jar"
sha256sum --check .github/dependencies.sha256
101 changes: 30 additions & 71 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,59 @@ name: Build

on:
push:
branches: ['**']
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

concurrency:
# Keep every push build, even when another commit is pushed immediately.
group: ${{ github.workflow }}-${{ github.run_id }}
cancel-in-progress: false

permissions:
contents: read

jobs:
build:
# Fork PRs and Dependabot do not receive the private dependency secret.
if: github.actor != 'dependabot[bot]' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
runs-on: ubuntu-latest
timeout-minutes: 15
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-java@v4
- uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '25'
cache: maven

- name: Install pinned TLibs in Maven
uses: TF-Minecraft/TLibs/.github/actions/setup@905a196217471252b96be5ecf8eeb16c9e85e41d
with:
token: ${{ secrets.DEPS_TOKEN }}

- name: Fetch private dependencies
- name: Prepare pinned dependencies
env:
GH_TOKEN: ${{ secrets.DEPS_TOKEN }}
run: bash .github/scripts/prepare-release.sh
- name: Set dated development version
id: dev
shell: bash
run: |
if [ -z "$GH_TOKEN" ]; then
echo "::error::Set DEPS_TOKEN to a token with Contents: read access to JustinasLa/tfmc-deps."
exit 1
fi
mkdir -p libs
gh release download v1 --repo JustinasLa/tfmc-deps --dir libs --clobber \
--pattern 'vehicleframework-1.1.11.jar' \
--pattern 'rpcharacters-1.1.6.jar' \
--pattern 'advancedcrafting-1.1.7.jar' \
--pattern 'simplefactions-2.8.7.jar' \
--pattern 'MMOCore-1.13.1.jar' \
--pattern 'MythicLib-dist-1.7.1.jar'

- name: Verify private dependencies
run: sha256sum -c libs/SHA256SUMS

- name: Build
run: mvn -B --no-transfer-progress -P'!deploy-live' clean package

- uses: actions/upload-artifact@v4
dev_version="DEV-$(date -u +%Y%m%d-%H%M)"
mvn -B --no-transfer-progress org.codehaus.mojo:versions-maven-plugin:2.22.0:set \
-DnewVersion="$dev_version" -DgenerateBackupPoms=false
mvn -B --no-transfer-progress help:evaluate \
-Dexpression=project.build.finalName -Doutput="$RUNNER_TEMP/final-name"
final_name=$(cat "$RUNNER_TEMP/final-name")
echo "name=$final_name" >> "$GITHUB_OUTPUT"
echo "jar=target/$final_name.jar" >> "$GITHUB_OUTPUT"

- name: Run unit tests and build
run: mvn -B --no-transfer-progress clean verify -DskipTests=false -Dmaven.test.skip=false
- uses: actions/upload-artifact@v7
with:
name: tfmccore-jar-${{ github.sha }}
path: target/*.jar
name: ${{ steps.dev.outputs.name }}-${{ github.run_id }}-${{ github.run_attempt }}
path: ${{ steps.dev.outputs.jar }}
if-no-files-found: error
retention-days: 90

publish:
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
concurrency:
group: publish-latest-release
steps:
- uses: actions/checkout@v4
- name: Upload unit test reports
if: ${{ !cancelled() && hashFiles('target/surefire-reports/*.xml') != '' }}
uses: actions/upload-artifact@v7
with:
persist-credentials: false

- uses: actions/download-artifact@v4
with:
name: tfmccore-jar-${{ github.sha }}
path: target

# --clobber only replaces an asset with the same filename; a pom.xml
# version bump changes the jar name, so old jars won't be pruned
# automatically and must be removed from the release manually.
- name: Publish latest release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if gh release view latest >/dev/null 2>&1; then
gh release upload latest target/*.jar --clobber
else
gh release create latest target/*.jar \
--title "Latest build" --notes "Auto-published from main" --latest=false
fi
name: unit-test-reports-${{ github.run_id }}-${{ github.run_attempt }}
path: target/surefire-reports/
if-no-files-found: error
140 changes: 140 additions & 0 deletions .github/workflows/maven-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: Maven plugin release

on:
workflow_call:
inputs:
java-version:
required: true
type: string
artifact-path:
description: Exact deployable JAR path, with optional {version} placeholder
required: true
type: string
secrets:
DEPS_TOKEN:
required: false

permissions:
contents: read

concurrency:
group: plugin-release-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: false

defaults:
run:
shell: bash

jobs:
build:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-java@v6
with:
distribution: temurin
java-version: ${{ inputs.java-version }}

- name: Validate release version
env:
TAG: ${{ github.ref_name }}
run: |
[[ "$TAG" =~ ^v[0-9]+\.[0-9]+(\.[0-9]+)?(-[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?$ ]] || {
echo '::error::Expected vMAJOR.MINOR or vMAJOR.MINOR.PATCH, with an optional prerelease suffix.'
exit 1
}
[[ "${TAG^^}" != *SNAPSHOT* ]] || exit 1

- name: Install pinned TLibs in Maven
uses: TF-Minecraft/TLibs/.github/actions/setup@905a196217471252b96be5ecf8eeb16c9e85e41d
with:
token: ${{ secrets.DEPS_TOKEN }}

- name: Prepare pinned dependencies
env:
GH_TOKEN: ${{ secrets.DEPS_TOKEN }}
run: |
if [[ -f .github/scripts/prepare-release.sh ]]; then
bash .github/scripts/prepare-release.sh
fi

- name: Check Maven version and build
env:
TAG: ${{ github.ref_name }}
run: |
version_file="$RUNNER_TEMP/maven-release-version"
mvn -B --no-transfer-progress -P'!deploy-live' help:evaluate \
-Dexpression=project.version -Doutput="$version_file"
[[ "$(cat "$version_file")" == "${TAG#v}" ]] || {
echo '::error::The tag must match project.version exactly.'
exit 1
}
mvn -B --no-transfer-progress -P'!deploy-live' clean verify

- name: Stage only the release JAR
env:
ARTIFACT_PATH: ${{ inputs.artifact-path }}
TAG: ${{ github.ref_name }}
run: |
python3 - <<'PY'
import hashlib, json, os, pathlib, shutil, zipfile
root = pathlib.Path.cwd().resolve()
source = (root / os.environ['ARTIFACT_PATH'].replace('{version}', os.environ['TAG'][1:])).resolve()
if not source.is_relative_to(root / 'target') or not source.is_file() or source.suffix != '.jar':
raise SystemExit('Expected one existing JAR inside target/')
with zipfile.ZipFile(source) as jar:
if not {'plugin.yml', 'paper-plugin.yml'}.intersection(jar.namelist()):
raise SystemExit('Release JAR has no plugin descriptor')
if jar.testzip() is not None:
raise SystemExit('Release JAR is corrupt')
dest = pathlib.Path(os.environ['RUNNER_TEMP']) / 'plugin-release'
dest.mkdir()
shutil.copyfile(source, dest / source.name)
digest = hashlib.sha256((dest / source.name).read_bytes()).hexdigest()
(dest / 'SHA256SUMS').write_text(f'{digest} {source.name}\n')
(dest / 'build.json').write_text(json.dumps({
'repository': os.environ['GITHUB_REPOSITORY'],
'commit': os.environ['GITHUB_SHA'],
'tag': os.environ['TAG'],
'run': f"{os.environ['GITHUB_SERVER_URL']}/{os.environ['GITHUB_REPOSITORY']}/actions/runs/{os.environ['GITHUB_RUN_ID']}",
'artifact': source.name,
'sha256': digest,
}, indent=2) + '\n')
PY

- uses: actions/upload-artifact@v7
with:
name: plugin-release-${{ github.sha }}
path: ${{ runner.temp }}/plugin-release/
if-no-files-found: error
retention-days: 30

publish:
needs: build
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: write
steps:
- uses: actions/download-artifact@v8
with:
name: plugin-release-${{ github.sha }}
path: release

- name: Create draft release
working-directory: release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
TAG: ${{ github.ref_name }}
run: |
sha256sum --check SHA256SUMS
flags=()
if [[ "$TAG" == *-* ]]; then flags+=(--prerelease); fi
gh release create "$TAG" ./*.jar SHA256SUMS build.json \
--verify-tag --draft --title "$TAG" --generate-notes "${flags[@]}"
20 changes: 20 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Release

on:
push:
tags: ['v*']

permissions:
contents: read

jobs:
release:
permissions:
contents: write
uses: ./.github/workflows/maven-release.yml
with:
java-version: '25'
# Exact path, not a glob. {version} is replaced with the tag without v.
artifact-path: target/tfmccore-{version}.jar
secrets:
DEPS_TOKEN: ${{ secrets.DEPS_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ Thumbs.db
# Private jar-only deps: fetched from JustinasLa/tfmc-deps, never committed
libs/*
!libs/SHA256SUMS

# Downloaded build dependencies
/libs/*.jar
Loading
Loading