From ed02d61d942b43ad73bd14b10df947b1a73e28d7 Mon Sep 17 00:00:00 2001
From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com>
Date: Tue, 22 Sep 2026 15:27:59 +0000
Subject: [PATCH] ci: build dated development jars and tagged draft releases
---
.github/dependencies.sha256 | 7 ++
.github/scripts/prepare-release.sh | 13 +++
.github/workflows/build.yml | 104 +++++++--------------
.github/workflows/maven-release.yml | 135 ++++++++++++++++++++++++++++
.github/workflows/release.yml | 20 +++++
.gitignore | 3 +
pom.xml | 57 +++++-------
src/main/resources/plugin.yml | 2 +-
8 files changed, 232 insertions(+), 109 deletions(-)
create mode 100644 .github/dependencies.sha256
create mode 100644 .github/scripts/prepare-release.sh
create mode 100644 .github/workflows/maven-release.yml
create mode 100644 .github/workflows/release.yml
diff --git a/.github/dependencies.sha256 b/.github/dependencies.sha256
new file mode 100644
index 0000000..b473f66
--- /dev/null
+++ b/.github/dependencies.sha256
@@ -0,0 +1,7 @@
+bbac27e3055d135a4a7f6164ace5e32b7e6275cc8387575a8c8e1809fdc555fd libs/TLibs.jar
+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
diff --git a/.github/scripts/prepare-release.sh b/.github/scripts/prepare-release.sh
new file mode 100644
index 0000000..f4dbc5f
--- /dev/null
+++ b/.github/scripts/prepare-release.sh
@@ -0,0 +1,13 @@
+#!/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/runtime/plugins/TLibs.jar?ref=$ref" > "libs/TLibs.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/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
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a61e06f..66b7bea 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,96 +2,54 @@ 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: '21'
- cache: maven
-
- - name: Fetch private dependencies
+ java-version: '25'
+ - 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 'TLibs-1.0.jar' \
- --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
diff --git a/.github/workflows/maven-release.yml b/.github/workflows/maven-release.yml
new file mode 100644
index 0000000..3103b70
--- /dev/null
+++ b/.github/workflows/maven-release.yml
@@ -0,0 +1,135 @@
+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: 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[@]}"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..a807ca5
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -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 }}
diff --git a/.gitignore b/.gitignore
index 598f188..71f25ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/pom.xml b/pom.xml
index 5f13211..a9b9daa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,13 +12,6 @@
UTF-8
21
21
- D:/Dokumenter/My Plugins/Reference Libs
- D:/Dokumenter/My Plugins/TFMC/TFMCCore
- D:/Dokumenter/My Plugins/TFMC/TLibs
- D:/Dokumenter/My Plugins/TFMC/VehicleFramework
- D:/Dokumenter/My Plugins/TFMC/RPCharacters
- D:/Dokumenter/My Plugins/TFMC/AdvancedCrafting
- D:/Dokumenter/My Plugins/TFMC/SimpleFactions
@@ -54,49 +47,49 @@
TLibs
1.0
system
- ${tfmc.tlibs}/TLibs.jar
+ ${project.basedir}/libs/TLibs.jar
local
VehicleFramework
- 1.1.11
+ 1.1.12
system
- ${tfmc.vehicleframework}/vehicleframework-1.1.11.jar
+ ${project.basedir}/libs/vehicleframework-1.1.12.jar
local
RPCharacters
1.1.7
system
- ${tfmc.rpcharacters}/rpcharacters-1.1.7.jar
+ ${project.basedir}/libs/rpcharacters-1.1.7.jar
local
AdvancedCrafting
- 1.1.7
+ 1.2.1
system
- ${tfmc.advancedcrafting}/advancedcrafting-1.1.7.jar
+ ${project.basedir}/libs/advancedcrafting-1.2.1.jar
local
SimpleFactions
2.8.7
system
- ${tfmc.sf}/simplefactions-2.8.7.jar
+ ${project.basedir}/libs/simplefactions-2.8.7.jar
local
MythicLib
1.7.1
system
- ${tfmc.refs}/MythicLib-dist-1.7.1.jar
+ ${project.basedir}/libs/MythicLib-dist-1.7.1.jar
local
MMOCore
1.13.1
system
- ${tfmc.refs}/MMOCore-1.13.1.jar
+ ${project.basedir}/libs/MMOCore-1.13.1.jar
@@ -134,7 +127,19 @@
- TFMCCore
+
+
+ src/main/resources
+ true
+ plugin.yml
+
+
+ src/main/resources
+ false
+ plugin.yml
+
+
+ ${project.artifactId}-${project.version}
org.apache.maven.plugins
@@ -146,24 +151,6 @@
maven-surefire-plugin
3.2.5
-
- org.apache.maven.plugins
- maven-antrun-plugin
- 3.1.0
-
-
- package
- run
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index ab07f12..c6fbc32 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,7 +1,7 @@
main: net.tfminecraft.tfmccore.TFMCCore
api-version: 1.21
name: TFMCCore
-version: 1.0
+version: ${project.version}
author: Drefvelin
depend: [TLibs]