Skip to content

Commit 9ec3b51

Browse files
ci: Optimize CI/CD workflows and add changelog generation script (#32)
* enhance CI/CD workflows and add changelog generation script * update CLAUDE.md * add pull request workflow * update .packwizignore to include Claude files * rename CI workflow to PR Build and use PR number in artifacts * remove cache * add cache * add cache * update pr workflow and claude.md
1 parent ac067d3 commit 9ec3b51

7 files changed

Lines changed: 238 additions & 3 deletions

File tree

.github/scripts/changelog.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Resolve the previous nightly tag position for incremental changelog.
5+
# Falls back to the latest stable (v*) tag if nightly tag does not exist.
6+
prev_sha=""
7+
compare_base=""
8+
9+
if git rev-parse nightly >/dev/null 2>&1; then
10+
prev_sha=$(git rev-parse nightly)
11+
fi
12+
13+
if [ -n "$prev_sha" ] && [ "$prev_sha" != "$GITHUB_SHA" ]; then
14+
compare_base="$prev_sha"
15+
else
16+
last_tag=$(git describe --tags --abbrev=0 --match='v*' 2>/dev/null || true)
17+
if [ -n "$last_tag" ]; then
18+
compare_base="$last_tag"
19+
fi
20+
fi
21+
22+
if [ -n "$compare_base" ]; then
23+
changelog=$(git log --pretty=format:"- %s (%h)" "${compare_base}..HEAD")
24+
compare_url="https://github.com/${GITHUB_REPOSITORY}/compare/${compare_base}...${GITHUB_SHA}"
25+
else
26+
changelog="- Initial nightly build"
27+
compare_url=""
28+
fi
29+
30+
{
31+
echo "body<<BODY_EOF"
32+
echo "## Nightly \`${SHORT_SHA}\`"
33+
echo ""
34+
echo "**Date:** $(date -u '+%Y-%m-%d %H:%M UTC')"
35+
echo "**Commit:** ${GITHUB_SHA}"
36+
[ -n "$compare_url" ] && echo "**Changes:** [compare](${compare_url})"
37+
echo ""
38+
echo "### What's Changed"
39+
echo "$changelog"
40+
echo "BODY_EOF"
41+
} >> "$GITHUB_OUTPUT"

.github/templates/start.bat.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ if errorlevel 1 (
99
)
1010

1111
java -jar packwiz-installer-bootstrap.jar -g -s server "@PACK_URL@"
12+
if errorlevel 1 (
13+
echo Pack update failed.
14+
exit /b 1
15+
)
1216
java -jar "@FORGE_JAR@" nogui

.github/workflows/nightly.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ on:
44
push:
55
branches:
66
- 'main'
7+
paths-ignore:
8+
- 'docs/**'
9+
- 'README.md'
10+
- 'LICENSE'
11+
- 'NOTICE.md'
12+
- 'CLAUDE.md'
13+
- '.github/ISSUE_TEMPLATE/**'
714

815
env:
916
MANIFEST_REPO: GregTechLite/gregtechlite.github.io
@@ -29,7 +36,13 @@ jobs:
2936
ref: ${{ github.ref_name }}
3037

3138
- name: Install Nix
32-
uses: cachix/install-nix-action@v31
39+
uses: nixbuild/nix-quick-install-action@v34
40+
41+
- name: Cache Nix store
42+
uses: nix-community/cache-nix-action@v7
43+
with:
44+
primary-key: nix-${{ runner.os }}-${{ hashFiles('flake.lock') }}
45+
restore-prefixes-first-match: nix-${{ runner.os }}-
3346

3447
- name: Load devShell
3548
uses: rrbutani/use-nix-shell-action@v1
@@ -62,6 +75,10 @@ jobs:
6275
user_email: 'github-actions[bot]@users.noreply.github.com'
6376
commit_message: "Nightly ${{ env.SHORT_SHA }}"
6477

78+
- name: Generate changelog
79+
id: changelog
80+
run: bash .github/scripts/changelog.sh
81+
6582
- name: Update nightly tag
6683
run: |
6784
git tag -f nightly
@@ -72,13 +89,14 @@ jobs:
7289
with:
7390
tag: nightly
7491
name: Nightly ${{ env.SHORT_SHA }}
92+
body: ${{ steps.changelog.outputs.body }}
7593
prerelease: true
7694
artifacts: |
7795
${{ steps.package.outputs.curseforge_zip }}
7896
${{ steps.package_server.outputs.server_zip }}
7997
allowUpdates: true
8098
updateOnlyUnreleased: true
81-
generateReleaseNotes: true
99+
removeArtifacts: true
82100

83101
- name: Upload nightly artifacts
84102
uses: actions/upload-artifact@v4
@@ -87,4 +105,5 @@ jobs:
87105
path: |
88106
${{ steps.package.outputs.curseforge_zip }}
89107
${{ steps.package_server.outputs.server_zip }}
108+
retention-days: 7
90109
if-no-files-found: error

.github/workflows/pr.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: PR Build
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- 'main'
7+
paths-ignore:
8+
- 'docs/**'
9+
- 'README.md'
10+
- 'LICENSE'
11+
- 'NOTICE.md'
12+
- 'CLAUDE.md'
13+
- '.github/ISSUE_TEMPLATE/**'
14+
15+
permissions:
16+
contents: read
17+
18+
concurrency:
19+
group: ci-${{ github.event.pull_request.number }}
20+
cancel-in-progress: true
21+
22+
jobs:
23+
build:
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v4
29+
with:
30+
fetch-depth: 0
31+
32+
- name: Install Nix
33+
uses: nixbuild/nix-quick-install-action@v34
34+
35+
- name: Cache Nix store
36+
uses: nix-community/cache-nix-action@v7
37+
with:
38+
primary-key: nix-${{ runner.os }}-${{ hashFiles('flake.lock') }}
39+
restore-prefixes-first-match: nix-${{ runner.os }}-
40+
41+
- name: Load devShell
42+
uses: rrbutani/use-nix-shell-action@v1
43+
with:
44+
devShell: .#default
45+
46+
- name: Resolve metadata
47+
run: bash .github/scripts/meta.sh
48+
49+
- name: Package client
50+
id: package
51+
run: bash .github/scripts/client.sh "${SLUG}-pr${{ github.event.pull_request.number }}-${SHORT_SHA}"
52+
53+
- name: Package server
54+
id: package_server
55+
run: bash .github/scripts/server.sh "${SLUG}-pr${{ github.event.pull_request.number }}-${SHORT_SHA}" "https://raw.githubusercontent.com/${{ github.event.pull_request.head.repo.full_name }}/${{ github.event.pull_request.head.sha }}/pack.toml"
56+
57+
- name: Upload build artifacts
58+
uses: actions/upload-artifact@v4
59+
with:
60+
name: "${{ env.SLUG }}-pr${{ github.event.pull_request.number }}-${{ env.SHORT_SHA }}"
61+
path: |
62+
${{ steps.package.outputs.curseforge_zip }}
63+
${{ steps.package_server.outputs.server_zip }}
64+
retention-days: 3
65+
if-no-files-found: error

.github/workflows/release.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,13 @@ jobs:
2929
ref: ${{ github.ref_name }}
3030

3131
- name: Install Nix
32-
uses: cachix/install-nix-action@v31
32+
uses: nixbuild/nix-quick-install-action@v34
33+
34+
- name: Restore Nix store cache
35+
uses: nix-community/cache-nix-action/restore@v7
36+
with:
37+
primary-key: nix-${{ runner.os }}-${{ hashFiles('flake.lock') }}
38+
restore-prefixes-first-match: nix-${{ runner.os }}-
3339

3440
- name: Load devShell
3541
uses: rrbutani/use-nix-shell-action@v1

.packwizignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,7 @@ flake.lock
5454

5555
# GitHub
5656
/.github/
57+
58+
# Claude
59+
CLAUDE.md
60+
/.claude/

CLAUDE.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
GregTech Lite (GTLite) is a Minecraft 1.12.2 Forge modpack centered around GregTech CE Unofficial (GTCEu). It uses **PackWiz** for mod management and distribution, **GroovyScript** for recipe customization, and **BetterQuesting** for progression.
8+
9+
- Pack metadata: `pack.toml` (name, version, Minecraft/Forge versions)
10+
- File manifest: `index.toml` (SHA256 hashes of all packed files)
11+
- Mod definitions: `mods/*.pw.toml` (PackWiz metadata referencing CurseForge)
12+
- Three local JARs in `mods/`: `gregtech-*.jar` (GTCEu), `gtlitecore-*.jar` (custom core mod), `morphismlib-*.jar` (dependency library)
13+
14+
## Development Environment
15+
16+
Requires Nix. Enter the dev shell with:
17+
```bash
18+
nix develop
19+
```
20+
This provides: JDK 8, tomlq (yq), packwiz, zip.
21+
22+
## Common Commands
23+
24+
```bash
25+
# Export CurseForge client package
26+
packwiz curseforge export -o dist/output.zip
27+
28+
# Add a mod from CurseForge
29+
packwiz curseforge install <mod-slug>
30+
31+
# Update a mod
32+
packwiz update <mod-name>
33+
34+
# Refresh index.toml after file changes
35+
packwiz refresh
36+
```
37+
38+
## Architecture
39+
40+
### GroovyScript Recipes (`groovy/`)
41+
42+
Recipe loading is configured in `groovy/runConfig.json` with two phases:
43+
- **preInit**: `event/` (MaterialEventHandler, TooltipEventHandler), `util/` (GroovyUtil)
44+
- **postInit**: `loader/` — OreDictionaryLoader, `loader/hooks/`, `loader/recipe/`
45+
46+
Each file in `loader/recipe/` handles recipe modifications for a specific mod (e.g., `AppliedEnergistics2.groovy`, `EnderIO.groovy`, `GregTech.groovy`). All recipes are redesigned to follow GregTech's philosophy.
47+
48+
**Recipe syntax patterns:**
49+
- Machine recipes: `recipemap('assembler').recipeBuilder().inputs(...).outputs(...).duration(...).EUt(VA[LV]).buildAndRegister()`
50+
- Crafting: `crafting.addShapeless(...)`, `crafting.shapedBuilder(...).key(...).build()`
51+
- Item references: `metaitem('circuit.good')`, `ore('plateSteel')`, `item('minecraft:stone')`, `fluid('water')`
52+
- Energy tiers: `VA[ULV]` through `VA[MAX]`, duration constants like `SECOND`
53+
54+
### Quest System (`config/betterquesting/DefaultQuests/`)
55+
56+
- `QuestLines/*.json` — Quest line definitions (20 lines covering LV through MAX voltage tiers)
57+
- `Quests/<questline-id>/<quest-id>.json` — Individual quest data
58+
59+
Quest JSON uses a NBT-like format with type suffixes: `:2` = short, `:3` = int, `:7` = byte array, `:8` = string, `:9` = tag list, `:10` = compound tag, `:11` = int array.
60+
61+
### Config (`config/`)
62+
63+
Mod configuration files. Key ones:
64+
- `gregtech/gregtech.cfg` — GregTech balance and features
65+
- `AppliedEnergistics2/AppliedEnergistics2.cfg` — AE2 settings
66+
- `betterquesting.cfg` — Quest UI and behavior
67+
68+
### Resources (`resources/`)
69+
70+
Resource pack overrides: custom textures, lang files, and JEI integration. Organized by mod namespace (e.g., `gregtech/`, `appliedenergistics2/`, `minecraft/`).
71+
72+
## CI/CD
73+
74+
Three GitHub Actions workflows (all use Nix dev shell):
75+
76+
- **pr.yml** ("PR Build"): Triggered on PRs to `main`. Ignores docs-only changes. Uses PR number and short SHA in artifact names (e.g., `gregtech-lite-pr42-a1b2c3d-curseforge.zip`). Concurrency groups by PR number to cancel stale builds. 3-day artifact retention.
77+
- **nightly.yml**: Triggered on push to `main` (+ `workflow_dispatch`). Builds artifacts, deploys manifest to `GregTechLite/gregtechlite.github.io` under `nightly/`, generates changelog from git history, force-updates `nightly` tag, publishes prerelease. 7-day artifact retention.
78+
- **release.yml**: Triggered by `v*` tags. Validates tag matches `pack.toml` version, builds artifacts, deploys manifest to `releases/{VERSION}/`, publishes GitHub Release.
79+
80+
### Build Scripts (`.github/scripts/`)
81+
82+
- `meta.sh` — Extracts metadata from `pack.toml` via `tomlq` and exports to `$GITHUB_ENV`: `NAME`, `SLUG`, `VERSION`, `MINECRAFT_VERSION`, `FORGE_VERSION`, `SHORT_SHA`
83+
- `client.sh` — Runs `packwiz curseforge export` into `dist/`
84+
- `server.sh` — Downloads Forge installer + packwiz-installer-bootstrap, runs Forge install, generates start scripts from `.github/templates/` (`start.sh.in`, `start.bat.in`, `eula.txt`, `README.txt.in`), creates server ZIP
85+
- `manifest.sh` — Copies `pack.toml`, `index.toml`, and all indexed files to `dist/manifest/` for deployment
86+
- `changelog.sh` — Generates incremental nightly changelog by diffing from previous `nightly` tag or latest `v*` tag
87+
88+
## File Exclusions
89+
90+
`.packwizignore` excludes development-only files (docs/, .github/, flake.nix, CLAUDE.md, logo.png, IDE metadata, etc.) from pack exports. Only game-relevant files ship to players.
91+
92+
## Licensing
93+
94+
- Modpack code: GNU AGPL 3.0
95+
- Assets: CC BY-NC-SA 3.0
96+
- Questbook content: CC BY-NC-ND 3.0

0 commit comments

Comments
 (0)