ci: add plugin build and release pipeline
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
cache: gradle
|
||||
|
||||
- name: Validate conventional commits
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
npx -y \
|
||||
-p @commitlint/cli \
|
||||
-p @commitlint/config-conventional \
|
||||
commitlint --from "${{ github.event.pull_request.base.sha }}" --to "${{ github.sha }}" \
|
||||
--extends @commitlint/config-conventional
|
||||
|
||||
- name: Build and test
|
||||
run: ./gradlew clean check jar
|
||||
|
||||
- name: Upload development artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: spigot-creeper-fear-${{ github.sha }}
|
||||
path: build/libs/*.jar
|
||||
if-no-files-found: error
|
||||
@@ -0,0 +1,140 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
cache: gradle
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Build and test before release
|
||||
run: ./gradlew clean check
|
||||
|
||||
- name: Capture previous tag
|
||||
id: previous_tag
|
||||
run: |
|
||||
if git describe --tags --abbrev=0 >/dev/null 2>&1; then
|
||||
echo "value=$(git describe --tags --abbrev=0)" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "value=" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Run semantic-release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
npx -y \
|
||||
-p semantic-release@24.2.9 \
|
||||
-p @semantic-release/commit-analyzer@13.0.1 \
|
||||
-p @semantic-release/release-notes-generator@14.1.0 \
|
||||
semantic-release \
|
||||
--branches main \
|
||||
--plugins @semantic-release/commit-analyzer,@semantic-release/release-notes-generator
|
||||
|
||||
- name: Capture current tag
|
||||
id: current_tag
|
||||
run: |
|
||||
if git describe --tags --exact-match HEAD >/dev/null 2>&1; then
|
||||
echo "value=$(git describe --tags --exact-match HEAD)" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "value=" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Resolve release
|
||||
id: release
|
||||
env:
|
||||
PREVIOUS_TAG: ${{ steps.previous_tag.outputs.value }}
|
||||
CURRENT_TAG: ${{ steps.current_tag.outputs.value }}
|
||||
run: |
|
||||
if [ -n "$CURRENT_TAG" ] && [ "$CURRENT_TAG" != "$PREVIOUS_TAG" ]; then
|
||||
echo "created=true" >> "$GITHUB_OUTPUT"
|
||||
echo "tag=$CURRENT_TAG" >> "$GITHUB_OUTPUT"
|
||||
echo "version=${CURRENT_TAG#v}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "created=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Build versioned plugin
|
||||
if: steps.release.outputs.created == 'true'
|
||||
env:
|
||||
VERSION: ${{ steps.release.outputs.version }}
|
||||
run: ./gradlew clean jar -PreleaseVersion="$VERSION"
|
||||
|
||||
- name: Upload release workflow artifact
|
||||
if: steps.release.outputs.created == 'true'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: spigot-creeper-fear-${{ steps.release.outputs.version }}
|
||||
path: build/libs/spigot-creeper-fear-${{ steps.release.outputs.version }}.jar
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Create Gitea release and upload plugin
|
||||
if: steps.release.outputs.created == 'true'
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
GITEA_SERVER_URL: ${{ github.server_url }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
TAG: ${{ steps.release.outputs.tag }}
|
||||
VERSION: ${{ steps.release.outputs.version }}
|
||||
PREVIOUS_TAG: ${{ steps.previous_tag.outputs.value }}
|
||||
run: |
|
||||
api_url="${GITEA_SERVER_URL}/api/v1"
|
||||
jar="build/libs/spigot-creeper-fear-${VERSION}.jar"
|
||||
export RELEASE_BODY
|
||||
if [ -n "$PREVIOUS_TAG" ]; then
|
||||
RELEASE_BODY=$(git log --pretty='format:- %s (%h)' "${PREVIOUS_TAG}..HEAD")
|
||||
else
|
||||
RELEASE_BODY=$(git log --pretty='format:- %s (%h)' HEAD)
|
||||
fi
|
||||
payload=$(node -e '
|
||||
process.stdout.write(JSON.stringify({
|
||||
tag_name: process.env.TAG,
|
||||
name: process.env.TAG,
|
||||
body: process.env.RELEASE_BODY,
|
||||
draft: false,
|
||||
prerelease: false
|
||||
}));
|
||||
')
|
||||
response=$(curl --fail-with-body --silent --show-error \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${api_url}/repos/${REPOSITORY}/releases" \
|
||||
--data "$payload")
|
||||
release_id=$(printf '%s' "$response" | node -e '
|
||||
let input = "";
|
||||
process.stdin.on("data", chunk => input += chunk);
|
||||
process.stdin.on("end", () => {
|
||||
const response = JSON.parse(input);
|
||||
if (!response.id) process.exit(1);
|
||||
process.stdout.write(String(response.id));
|
||||
});
|
||||
')
|
||||
curl --fail-with-body --silent --show-error \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary "@${jar}" \
|
||||
"${api_url}/repos/${REPOSITORY}/releases/${release_id}/assets?name=spigot-creeper-fear-${VERSION}.jar"
|
||||
@@ -0,0 +1,100 @@
|
||||
# Spigot Creeper Fear
|
||||
|
||||
A Spigot 26.2 plugin that lets players earn six Creeper Aura ranks. Once unlocked, an aura prevents creeper explosions that hit the player from breaking blocks, trading that protection for rank-dependent player damage.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Spigot 26.2
|
||||
- Java 17 or newer
|
||||
|
||||
## Progression
|
||||
|
||||
Players earn one current-tier point when they kill a creeper directly, through a projectile, or through an owned tameable. A self-destructing creeper also awards one point to every player its explosion hits. Each tier defaults to 100 points and resets progress to zero when unlocked.
|
||||
|
||||
| Rank | Creeper damage | Block damage |
|
||||
| --- | ---: | --- |
|
||||
| Locked | 1× | Normal |
|
||||
| I | 3× | Prevented |
|
||||
| II | 2× | Prevented |
|
||||
| III | 1.5× | Prevented |
|
||||
| IV | 1× | Prevented |
|
||||
| V | 0.5× | Prevented |
|
||||
| VI | Cancelled | Prevented |
|
||||
|
||||
Progress is stored by player UUID in `plugins/CreeperFear/player-progress.sqlite3`. Database work runs away from the server thread.
|
||||
|
||||
After each point, a temporary boss bar shows current-tier progress. Unlocking a rank displays a full-screen title. Rank VI players no longer receive a progress bar.
|
||||
|
||||
## Build and install
|
||||
|
||||
```bash
|
||||
./gradlew clean check jar
|
||||
cp build/libs/spigot-creeper-fear-0.1.0-SNAPSHOT.jar /path/to/server/plugins/
|
||||
```
|
||||
|
||||
Restart the server after copying the JAR. The plugin creates its configuration and SQLite database under `plugins/CreeperFear/`.
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description | Permission |
|
||||
| --- | --- | --- |
|
||||
| `/creeperaura progress` | Show personal progress | `creeperfear.progress` |
|
||||
| `/creeperaura progress <player>` | Inspect a known online or offline player | `creeperfear.admin.inspect` |
|
||||
| `/creeperaura set <player> <progress>` | Set current-tier progress | `creeperfear.admin.modify` |
|
||||
| `/creeperaura add <player> <amount>` | Adjust current-tier progress | `creeperfear.admin.modify` |
|
||||
| `/creeperaura rank <player> <rank>` | Set rank and reset tier progress | `creeperfear.admin.modify` |
|
||||
| `/creeperaura threshold <rank> <points>` | Persist a rank requirement | `creeperfear.admin.configure` |
|
||||
| `/creeperaura reload` | Reload validated configuration | `creeperfear.admin.configure` |
|
||||
|
||||
The personal progress permission defaults to everyone. Administrative permissions default to server operators. Administrative changes are recorded in the server log.
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
progression:
|
||||
requirements:
|
||||
I: 100
|
||||
II: 100
|
||||
III: 100
|
||||
IV: 100
|
||||
V: 100
|
||||
VI: 100
|
||||
|
||||
aura:
|
||||
damage-multipliers:
|
||||
I: 3.0
|
||||
II: 2.0
|
||||
III: 1.5
|
||||
IV: 1.0
|
||||
V: 0.5
|
||||
VI: 0.0
|
||||
|
||||
feedback:
|
||||
progress-bar-seconds: 5
|
||||
rank-up-title: "Creeper Aura %rank%"
|
||||
rank-up-subtitle: "Unlocked!"
|
||||
```
|
||||
|
||||
Requirements must be positive integers. Multipliers must be finite and non-negative. Invalid reloads are rejected while the last valid runtime settings remain active. Requirement changes preserve current rank and tier progress; a subsequent qualifying point can unlock at most one rank.
|
||||
|
||||
## Releases
|
||||
|
||||
Gitea Actions builds and tests every push and pull request and uploads a development JAR. Pull requests also validate conventional commit messages.
|
||||
|
||||
Pushes to `main` run semantic-release:
|
||||
|
||||
- `fix:` creates a patch release;
|
||||
- `feat:` creates a minor release;
|
||||
- a breaking-change footer or `!` creates a major release.
|
||||
|
||||
A successful release attaches a versioned JAR to the corresponding Gitea release. The repository must define a `RELEASE_TOKEN` secret with repository contents write permission.
|
||||
|
||||
For a local versioned artifact:
|
||||
|
||||
```bash
|
||||
./gradlew clean check jar -PreleaseVersion=1.2.3
|
||||
```
|
||||
|
||||
## Design
|
||||
|
||||
The [OKF design bundle](design/index.md) contains the architecture and completed user stories.
|
||||
@@ -14,3 +14,4 @@ This bundle documents a Spigot plugin in which players earn Creeper Aura ranks b
|
||||
- [User stories](user-stories/index.md)
|
||||
- [Plugin architecture](architecture.md)
|
||||
- [Design log](log.md)
|
||||
- [Project README](../README.md)
|
||||
|
||||
@@ -20,3 +20,4 @@ description: Chronological record of material changes to the Spigot Creeper Fear
|
||||
- Completed US-004 with an asynchronous self-service progress command, ordinary-player permission, completion output, and command metadata.
|
||||
- Completed US-005 with UUID-backed offline inspection, atomic progress and rank administration, separate permissions, online-state refresh, and audit logging.
|
||||
- Completed US-006 with validated per-rank requirements and multipliers, configurable feedback, persistent threshold administration, and safe reload behavior.
|
||||
- Completed US-007 with Java 17/Spigot 26.2 Gradle builds, project documentation, Gitea CI, conventional-commit checks, semantic versioning, and release artifact publication.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
type: User Story
|
||||
title: "US-007: Build and release the plugin"
|
||||
description: Give maintainers repeatable Java builds, automated verification, and versioned Gitea releases.
|
||||
status: backlog
|
||||
status: done
|
||||
---
|
||||
|
||||
# US-007: Build and release the plugin
|
||||
@@ -11,14 +11,14 @@ As a **plugin maintainer**, I want automated builds and releases so that tested,
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] The Gradle project compiles with Java 17 against Spigot API 26.2.
|
||||
- [ ] Automated tests run as part of the Gradle `check` lifecycle.
|
||||
- [ ] Pushes and pull requests build and test the plugin in Gitea Actions.
|
||||
- [ ] Pull requests validate conventional commit messages.
|
||||
- [ ] CI stores a development JAR as a workflow artifact.
|
||||
- [ ] Main-branch conventional commits drive semantic versioning.
|
||||
- [ ] A successful release builds a versioned JAR and attaches it to the corresponding Gitea release.
|
||||
- [ ] Build, installation, command, permission, configuration, and release procedures are documented.
|
||||
- [x] The Gradle project compiles with Java 17 against Spigot API 26.2.
|
||||
- [x] Automated tests run as part of the Gradle `check` lifecycle.
|
||||
- [x] Pushes and pull requests build and test the plugin in Gitea Actions.
|
||||
- [x] Pull requests validate conventional commit messages.
|
||||
- [x] CI stores a development JAR as a workflow artifact.
|
||||
- [x] Main-branch conventional commits drive semantic versioning.
|
||||
- [x] A successful release builds a versioned JAR and attaches it to the corresponding Gitea release.
|
||||
- [x] Build, installation, command, permission, configuration, and release procedures are documented.
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
Reference in New Issue
Block a user