Skip to content

Commit a58e06e

Browse files
authored
ci: build dated development jars and tagged draft releases (#4)
1 parent 66a223d commit a58e06e

12 files changed

Lines changed: 304 additions & 81 deletions

File tree

‎.github/dependencies.sha256‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
4241c14a7727c34feea6507ec801318a3d4a90f070e4525681079fb94ee4c593 libs/gson-2.10.1.jar
2+
b7156eab567772f9fdac0bf696b209111790c3f69149ab9a742e3dd030ec4b10 libs/spigot-api.jar
3+
bf19510145178df82cd3bd37edd514c13f411531ec5545299fd3abcbc98fe7c2 libs/joml-1.10.8.jar
4+
0b077b2d56e918cc6a8b4662a0b6ad8dc5c3cc11f6a2fe93acb7a25bdf3cb524 libs/interactiblefurniture-0.1.3-BETA.jar
5+
c48fd36730e4516c996227b18713d83763c2d7bbd70a273c81579df9b190bc63 libs/tfmccore-1.0-SNAPSHOT.jar
6+
0fedc530aaa9cd9e0a452d0bde95fb9fa0ecc31564ec625e3a0e2cef57c0aec8 libs/rpcharacters-1.1.7.jar
7+
660ff2a6ec86bc8d7779948cf65c1637e271a16e1ef812d6a273f4a5c5eec73c libs/MythicLib-1.7.jar
8+
14850d7454374d7312305d3e84a391be720301e5964963f869b27ae97f6264eb libs/MMOCore-1.13.1.jar
9+
0aa5d3cb6bad9b36f0ef4b47dbcf6e40dbbad44470ec7fa7606c30d4d815a94b libs/CustomCrops-3.6.49.jar
10+
7d3083bd05998d8cafd7114ced74a6fa2ec1c4d36f75dbbaee9f20d499a7c3ad libs/CustomFishing-2.3.27.jar
11+
5185b9e0ea8653ab61da07304f1573c6a9a5af97cf55a5d970c5a25f16bc743d libs/simplefactions-2.8.7.jar

‎.github/scripts/prepare-release.sh‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
: "${GH_TOKEN:?Set DEPS_TOKEN with Contents read access to TF-Minecraft/ServerAssets}"
4+
ref=dd1e3ec5ee27d2467d5c07f9458bef212344ec41
5+
mkdir -p libs
6+
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/4241c14a7727/gson-2.10.1.jar?ref=$ref" > "libs/gson-2.10.1.jar"
7+
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/b7156eab5677/spigot-api.jar?ref=$ref" > "libs/spigot-api.jar"
8+
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/bf1951014517/joml-1.10.8.jar?ref=$ref" > "libs/joml-1.10.8.jar"
9+
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/0b077b2d56e9/interactiblefurniture-0.1.3-BETA.jar?ref=$ref" > "libs/interactiblefurniture-0.1.3-BETA.jar"
10+
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/c48fd36730e4/tfmccore-1.0-SNAPSHOT.jar?ref=$ref" > "libs/tfmccore-1.0-SNAPSHOT.jar"
11+
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"
12+
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/660ff2a6ec86/MythicLib-1.7.jar?ref=$ref" > "libs/MythicLib-1.7.jar"
13+
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"
14+
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/0aa5d3cb6bad/CustomCrops-3.6.49.jar?ref=$ref" > "libs/CustomCrops-3.6.49.jar"
15+
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/7d3083bd0599/CustomFishing-2.3.27.jar?ref=$ref" > "libs/CustomFishing-2.3.27.jar"
16+
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"
17+
sha256sum --check .github/dependencies.sha256

‎.github/workflows/build.yml‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-24.04
15+
timeout-minutes: 20
16+
steps:
17+
- uses: actions/checkout@v7
18+
with:
19+
persist-credentials: false
20+
- uses: actions/setup-java@v6
21+
with:
22+
distribution: temurin
23+
java-version: '25'
24+
- name: Install pinned TLibs in Maven
25+
uses: TF-Minecraft/TLibs/.github/actions/setup@905a196217471252b96be5ecf8eeb16c9e85e41d
26+
with:
27+
token: ${{ secrets.DEPS_TOKEN }}
28+
29+
- name: Prepare pinned dependencies
30+
env:
31+
GH_TOKEN: ${{ secrets.DEPS_TOKEN }}
32+
run: bash .github/scripts/prepare-release.sh
33+
- name: Set dated development version
34+
id: dev
35+
shell: bash
36+
run: |
37+
dev_version="DEV-$(date -u +%Y%m%d-%H%M)"
38+
mvn -B --no-transfer-progress org.codehaus.mojo:versions-maven-plugin:2.22.0:set \
39+
-DnewVersion="$dev_version" -DgenerateBackupPoms=false
40+
mvn -B --no-transfer-progress help:evaluate \
41+
-Dexpression=project.build.finalName -Doutput="$RUNNER_TEMP/final-name"
42+
final_name=$(cat "$RUNNER_TEMP/final-name")
43+
echo "name=$final_name" >> "$GITHUB_OUTPUT"
44+
echo "jar=target/$final_name.jar" >> "$GITHUB_OUTPUT"
45+
46+
- name: Run unit tests and build
47+
run: mvn -B --no-transfer-progress clean verify -DskipTests=false -Dmaven.test.skip=false
48+
- uses: actions/upload-artifact@v7
49+
with:
50+
name: ${{ steps.dev.outputs.name }}-${{ github.run_id }}-${{ github.run_attempt }}
51+
path: ${{ steps.dev.outputs.jar }}
52+
if-no-files-found: error
53+
54+
- name: Upload unit test reports
55+
if: ${{ !cancelled() && hashFiles('target/surefire-reports/*.xml') != '' }}
56+
uses: actions/upload-artifact@v7
57+
with:
58+
name: unit-test-reports-${{ github.run_id }}-${{ github.run_attempt }}
59+
path: target/surefire-reports/
60+
if-no-files-found: error

‎.github/workflows/docs.yml‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,23 @@ on:
55
push:
66
branches: [main]
77

8+
permissions:
9+
contents: read
10+
811
jobs:
912
documentation:
10-
runs-on: ubuntu-latest
13+
runs-on: ubuntu-24.04
1114
steps:
12-
- uses: actions/checkout@v4
15+
- uses: actions/checkout@v7
1316
with:
1417
fetch-depth: 0
15-
- uses: actions/setup-python@v5
18+
persist-credentials: false
19+
- uses: actions/setup-python@v7
1620
with:
17-
python-version: "3.12"
21+
python-version: '3.12'
1822
- name: Validate documentation manifest
1923
run: python scripts/test_doc_manifest.py
2024
- name: Check internal links
2125
run: python scripts/check-links.py
2226
- name: Check documentation impact
2327
run: python scripts/check-doc-impact.py
24-
25-
# mvn test needs the system-scoped Spigot and sibling-plugin jars, plus the pinned Maven TLibs input
26-
# from pom.xml. Those files are not on GitHub runners. Run mvn test locally.
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: Maven plugin release
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
java-version:
7+
required: true
8+
type: string
9+
artifact-path:
10+
description: Exact deployable JAR path, with optional {version} placeholder
11+
required: true
12+
type: string
13+
secrets:
14+
DEPS_TOKEN:
15+
required: false
16+
17+
permissions:
18+
contents: read
19+
20+
concurrency:
21+
group: plugin-release-${{ github.repository }}-${{ github.ref }}
22+
cancel-in-progress: false
23+
24+
defaults:
25+
run:
26+
shell: bash
27+
28+
jobs:
29+
build:
30+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
31+
runs-on: ubuntu-24.04
32+
timeout-minutes: 20
33+
steps:
34+
- uses: actions/checkout@v7
35+
with:
36+
persist-credentials: false
37+
38+
- uses: actions/setup-java@v6
39+
with:
40+
distribution: temurin
41+
java-version: ${{ inputs.java-version }}
42+
43+
- name: Validate release version
44+
env:
45+
TAG: ${{ github.ref_name }}
46+
run: |
47+
[[ "$TAG" =~ ^v[0-9]+\.[0-9]+(\.[0-9]+)?(-[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?$ ]] || {
48+
echo '::error::Expected vMAJOR.MINOR or vMAJOR.MINOR.PATCH, with an optional prerelease suffix.'
49+
exit 1
50+
}
51+
[[ "${TAG^^}" != *SNAPSHOT* ]] || exit 1
52+
53+
- name: Install pinned TLibs in Maven
54+
uses: TF-Minecraft/TLibs/.github/actions/setup@905a196217471252b96be5ecf8eeb16c9e85e41d
55+
with:
56+
token: ${{ secrets.DEPS_TOKEN }}
57+
58+
- name: Prepare pinned dependencies
59+
env:
60+
GH_TOKEN: ${{ secrets.DEPS_TOKEN }}
61+
run: |
62+
if [[ -f .github/scripts/prepare-release.sh ]]; then
63+
bash .github/scripts/prepare-release.sh
64+
fi
65+
66+
- name: Check Maven version and build
67+
env:
68+
TAG: ${{ github.ref_name }}
69+
run: |
70+
version_file="$RUNNER_TEMP/maven-release-version"
71+
mvn -B --no-transfer-progress -P'!deploy-live' help:evaluate \
72+
-Dexpression=project.version -Doutput="$version_file"
73+
[[ "$(cat "$version_file")" == "${TAG#v}" ]] || {
74+
echo '::error::The tag must match project.version exactly.'
75+
exit 1
76+
}
77+
mvn -B --no-transfer-progress -P'!deploy-live' clean verify
78+
79+
- name: Stage only the release JAR
80+
env:
81+
ARTIFACT_PATH: ${{ inputs.artifact-path }}
82+
TAG: ${{ github.ref_name }}
83+
run: |
84+
python3 - <<'PY'
85+
import hashlib, json, os, pathlib, shutil, zipfile
86+
root = pathlib.Path.cwd().resolve()
87+
source = (root / os.environ['ARTIFACT_PATH'].replace('{version}', os.environ['TAG'][1:])).resolve()
88+
if not source.is_relative_to(root / 'target') or not source.is_file() or source.suffix != '.jar':
89+
raise SystemExit('Expected one existing JAR inside target/')
90+
with zipfile.ZipFile(source) as jar:
91+
if not {'plugin.yml', 'paper-plugin.yml'}.intersection(jar.namelist()):
92+
raise SystemExit('Release JAR has no plugin descriptor')
93+
if jar.testzip() is not None:
94+
raise SystemExit('Release JAR is corrupt')
95+
dest = pathlib.Path(os.environ['RUNNER_TEMP']) / 'plugin-release'
96+
dest.mkdir()
97+
shutil.copyfile(source, dest / source.name)
98+
digest = hashlib.sha256((dest / source.name).read_bytes()).hexdigest()
99+
(dest / 'SHA256SUMS').write_text(f'{digest} {source.name}\n')
100+
(dest / 'build.json').write_text(json.dumps({
101+
'repository': os.environ['GITHUB_REPOSITORY'],
102+
'commit': os.environ['GITHUB_SHA'],
103+
'tag': os.environ['TAG'],
104+
'run': f"{os.environ['GITHUB_SERVER_URL']}/{os.environ['GITHUB_REPOSITORY']}/actions/runs/{os.environ['GITHUB_RUN_ID']}",
105+
'artifact': source.name,
106+
'sha256': digest,
107+
}, indent=2) + '\n')
108+
PY
109+
110+
- uses: actions/upload-artifact@v7
111+
with:
112+
name: plugin-release-${{ github.sha }}
113+
path: ${{ runner.temp }}/plugin-release/
114+
if-no-files-found: error
115+
retention-days: 30
116+
117+
publish:
118+
needs: build
119+
runs-on: ubuntu-24.04
120+
timeout-minutes: 5
121+
permissions:
122+
contents: write
123+
steps:
124+
- uses: actions/download-artifact@v8
125+
with:
126+
name: plugin-release-${{ github.sha }}
127+
path: release
128+
129+
- name: Create draft release
130+
working-directory: release
131+
env:
132+
GH_TOKEN: ${{ github.token }}
133+
GH_REPO: ${{ github.repository }}
134+
TAG: ${{ github.ref_name }}
135+
run: |
136+
sha256sum --check SHA256SUMS
137+
flags=()
138+
if [[ "$TAG" == *-* ]]; then flags+=(--prerelease); fi
139+
gh release create "$TAG" ./*.jar SHA256SUMS build.json \
140+
--verify-tag --draft --title "$TAG" --generate-notes "${flags[@]}"

‎.github/workflows/release.yml‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags: ['v*']
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
release:
12+
permissions:
13+
contents: write
14+
uses: ./.github/workflows/maven-release.yml
15+
with:
16+
java-version: '25'
17+
# Exact path, not a glob. {version} is replaced with the tag without v.
18+
artifact-path: target/cooking-{version}.jar
19+
secrets:
20+
DEPS_TOKEN: ${{ secrets.DEPS_TOKEN }}

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ Thumbs.db
3131

3232
# Logs
3333
*.log
34+
35+
# Downloaded build dependencies
36+
/libs/*.jar

‎AGENTS.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ mvn test
1717
mvn package
1818
```
1919

20-
`mvn test` needs the local system jars declared in `pom.xml`. GitHub Actions does not have those jars, so CI runs the documentation checks only.
20+
Run `GH_TOKEN=<read-token> bash .github/scripts/prepare-release.sh` to fetch the pinned build inputs. GitHub Actions uses `DEPS_TOKEN` to prepare dependencies and runs `mvn clean verify` with unit tests enabled, alongside the documentation checks.
2121

2222
```text
2323
python scripts/test_doc_manifest.py
@@ -42,5 +42,5 @@ A change that truly has no behavior impact must update [docs/impact-waiver.md](d
4242

4343
- Food is an amount and splits across portions. Nutrition is a level and stays on every piece and scoop. See [docs/systems/portions-and-servings.md](docs/systems/portions-and-servings.md) and [docs/decisions/0001-food-vs-nutrition.md](docs/decisions/0001-food-vs-nutrition.md).
4444
- `cookware.yml` is shipped and not loaded.
45-
- `plugin.yml` version and `pom.xml` version currently differ. Do not "fix" that inside an unrelated change.
45+
- `plugin.yml` uses `${project.version}`; Maven resource filtering supplies the development or release version.
4646
- Player-facing strings must not use an em dash.

‎README.md‎

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,27 @@ Paper plugin for furniture cooking, food items, crop quality, livestock, and nut
44

55
Java 25, Spigot/Paper API 1.21.8. Hard dependencies: TLibs, InteractibleFurniture, TFMCCore. Soft dependencies: RPCharacters, MMOCore, CustomCrops, SimpleFactions.
66

7-
## Develop
7+
## Build
88

9-
```text
10-
mvn test
11-
mvn package
9+
With `GH_TOKEN` set to a token that can read ServerAssets:
10+
11+
```sh
12+
python3 ../tlibs/tools/install-dependency.py --pom pom.xml
13+
bash .github/scripts/prepare-release.sh
14+
mvn clean verify
1215
```
1316

14-
`package` copies the jar to the local Cooking build folder set in `pom.xml`. Runtime YAML is [src/main/resources](src/main/resources). The server copies a missing file out of the jar on first start and does not overwrite an existing file.
17+
The runtime JAR is written to `target/`. PR builds run unit tests and upload a UTC `DEV-YYYYMMDD-HHmm` JAR. Numeric `v*` tags create a verified draft release.
1518

1619
## Documentation
1720

18-
Organisation documentation: [TF-Minecraft/docs](https://github.com/TF-Minecraft/docs/tree/main/projects/cooking).
19-
20-
Internal docs for people and coding agents: [docs/README.md](docs/README.md).
21-
22-
Agent workflow: [AGENTS.md](AGENTS.md).
23-
24-
The player guide is the ProvinceSystem wiki page `/wiki/cooking`, plus the animal husbandry and farming pages. That guide is not the implementation spec.
25-
26-
## Known drift
21+
- [Builds and releases](https://github.com/TF-Minecraft/Docs/blob/main/PIPELINES.md)
22+
- [Project documentation](https://github.com/TF-Minecraft/Docs/tree/main/projects/Cooking)
23+
- [Implementation guides](docs/README.md)
24+
- [Agent instructions](AGENTS.md)
2725

28-
- `plugin.yml` says version `1.0`. `pom.xml` says `0.1.5-ALPHA`.
29-
- `cookware.yml` is saved into the plugin folder and is not read by a loader.
30-
31-
## TLibs build dependency
32-
33-
TLibs is a versioned Maven `provided` dependency. From this repository, prepare
34-
it once with the shared installer, then build as usual:
35-
36-
```sh
37-
python3 ../tlibs/tools/install-dependency.py --pom pom.xml
38-
mvn clean verify
39-
```
26+
Runtime YAML lives in [src/main/resources](src/main/resources). The server copies a missing file from the JAR on first start and preserves existing configuration.
4027

41-
See [TLibs dependency setup](https://github.com/TF-Minecraft/TLibs/blob/v1.1.0/DEPENDENCIES.md)
42-
for public release installation, offline builds and rollback.
43-
Other declared build dependencies still need their usual preparation.
44-
Use JDK 25 for this TLibs binary; the server must also run Java 25.
28+
TLibs uses Maven `provided` scope with a checksum-pinned version. See [TLibs dependency setup](https://github.com/TF-Minecraft/TLibs/blob/v1.1.0/DEPENDENCIES.md) for authenticated and offline installation.
4529

4630
Builds and server runtime require Java 25 and [TLibs 1.1.0](https://github.com/TF-Minecraft/TLibs/releases/tag/v1.1.0).

‎docs/reference/configuration.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ Repo source: `src/main/resources`. Server copies are created only if missing. Lo
2424
| `custom-fishing.yml` | `CustomFishingCatalog` | live catch ids, cut class, rod quality bands, vanilla fish default sizes, seafood cutting yield, `model-data`, `legacy-size-cm` |
2525
| `cookware.yml` | none | shipped, not loaded. Heat lives in `config.yml` |
2626

27-
## Known drift
27+
## Packaging
2828

29-
- `plugin.yml` `version` is `1.0`. `pom.xml` `<version>` is `0.1.5-ALPHA`. Do not change either as a drive-by.
30-
- `cookware.yml` is listed in `Cooking.createConfigs()` and is absent from `loadConfigs()`.
29+
Maven filters `plugin.yml`'s `${project.version}` into the embedded plugin version. CI development builds use `DEV-YYYYMMDD-HHmm` in UTC; numeric release tags must match the POM version. Other resource files are copied without Maven filtering.
30+
31+
Private compile dependencies are pinned in `.github/scripts/prepare-release.sh` and `.github/dependencies.sha256`. See the [shared pipeline guide](https://github.com/TF-Minecraft/Docs/blob/main/PIPELINES.md) for dependency access and release artifacts.
3132

3233
## Adding a key
3334

0 commit comments

Comments
 (0)