Skip to content

Commit 5a47c55

Browse files
committed
chore: migrate to new release process
1 parent c6969e2 commit 5a47c55

16 files changed

Lines changed: 6730 additions & 194 deletions
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Promote Latest Release
2+
3+
on:
4+
release:
5+
types: [released]
6+
7+
jobs:
8+
promote-release:
9+
name: Mark highest semver as latest
10+
runs-on: ubuntu-latest
11+
12+
permissions:
13+
contents: write
14+
15+
steps:
16+
- name: Find and mark latest release
17+
uses: actions/github-script@v7
18+
with:
19+
script: |
20+
const semver = require('semver');
21+
const { owner, repo } = context.repo;
22+
23+
console.log(`Fetching all releases for ${owner}/${repo}...`);
24+
const { data: allReleases } = await github.rest.repos.listReleases({
25+
owner,
26+
repo,
27+
});
28+
29+
const sortedReleases = allReleases
30+
.filter(r => !r.draft && !r.prerelease && semver.valid(r.tag_name))
31+
.sort((a, b) => semver.rcompare(a.tag_name, b.tag_name));
32+
33+
if (sortedReleases.length === 0) {
34+
core.info("No valid, non-prerelease releases found. Exiting.");
35+
return;
36+
}
37+
38+
const latestRelease = sortedReleases[0];
39+
console.log(`Highest semver release found: ${latestRelease.tag_name}`);
40+
41+
console.log(`Updating release ${latestRelease.tag_name} to be the new 'latest' release.`);
42+
await github.rest.repos.updateRelease({
43+
owner,
44+
repo,
45+
release_id: latestRelease.id,
46+
make_latest: 'true',
47+
});
48+
console.log(`Successfully marked ${latestRelease.tag_name} as the latest release.`);

.github/workflows/release-please.yml

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Release Preview
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
- 'mc/*'
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
preview:
15+
name: Preview Release Notes
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: "lts/*"
27+
28+
- run: npm ci
29+
30+
- name: Checkout PR branch (required for semantic-release)
31+
run: git checkout "origin/${{ github.head_ref }}"
32+
33+
- name: Generate release notes (Dry Run)
34+
id: dryrun
35+
env:
36+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
run: |
38+
# Run semantic-release in dry-run mode and capture all output
39+
# Unset GITHUB_ACTIONS to avoid issues with semantic-release refusing to run in CI
40+
output=$(unset GITHUB_ACTIONS && npx semantic-release --dry-run --no-ci --branches "${{ github.head_ref }}")
41+
42+
# Output the raw result for debugging
43+
echo "Raw output from semantic-release:"
44+
echo "$output"
45+
46+
if [[ $? -ne 0 ]]; then
47+
echo "❌ Error generating release notes."
48+
echo "$output"
49+
exit 1
50+
fi
51+
52+
# Check if a release would be created
53+
if echo "$output" | grep -q "There are no relevant changes"; then
54+
notes="NO_RELEASE"
55+
else
56+
# Extract just the release notes section for a cleaner comment
57+
notes=$(echo "$output" | awk '/Release note for version/{flag=1; next} flag')
58+
fi
59+
60+
# Use multiline output for the notes
61+
echo "notes<<EOF" >> $GITHUB_OUTPUT
62+
echo "$notes" >> $GITHUB_OUTPUT
63+
echo "EOF" >> $GITHUB_OUTPUT
64+
65+
- name: Generate PR body
66+
id: pr_body
67+
run: |
68+
echo "body<<EOF" >> $GITHUB_OUTPUT
69+
70+
if [[ "${{ steps.dryrun.outputs.notes }}" == "NO_RELEASE" ]]; then
71+
echo "No release will be created when this pull request is merged." >> $GITHUB_OUTPUT
72+
else
73+
echo "This pull request will trigger a new release when merged." >> $GITHUB_OUTPUT
74+
echo -e "<details>\n" >> $GITHUB_OUTPUT
75+
echo -e "<summary>Release notes</summary>\n" >> $GITHUB_OUTPUT
76+
echo -e "${{ steps.dryrun.outputs.notes }}\n" >> $GITHUB_OUTPUT
77+
echo -e "</details>\n" >> $GITHUB_OUTPUT
78+
fi
79+
80+
echo "EOF" >> $GITHUB_OUTPUT
81+
82+
- name: Post or Update PR Comment
83+
uses: marocchino/sticky-pull-request-comment@v2
84+
with:
85+
header: release-preview
86+
message: |
87+
### 🚀 Release Preview
88+
${{ steps.pr_body.outputs.body }}

.github/workflows/release.yml

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Create Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- 'mc/*'
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
issues: write
13+
14+
jobs:
15+
release:
16+
name: Create Release
17+
runs-on: ubuntu-latest
18+
# This condition prevents the workflow from running on pushes that
19+
# only contain the [skip ci] message from semantic-release itself.
20+
if: contains(github.event.head_commit.message, '[skip ci]') == false
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
27+
- uses: actions/setup-java@v4
28+
with:
29+
java-version: 21
30+
distribution: 'microsoft'
31+
32+
- name: Setup Gradle
33+
uses: gradle/actions/setup-gradle@v4
34+
35+
- name: make gradle wrapper executable
36+
run: chmod +x ./gradlew
37+
38+
- name: Setup Node.js
39+
uses: actions/setup-node@v4
40+
with:
41+
node-version: "lts/*"
42+
43+
- run: npm ci
44+
45+
- name: Get Minecraft version
46+
id: mcVersion
47+
run: |
48+
PROPERTIES_FILE="gradle.properties"
49+
MC_VERSION_REGEX='minecraft_version\s*=\s*(.+)'
50+
51+
MC_VERSION=$(grep -oP "$MC_VERSION_REGEX" "$PROPERTIES_FILE" | cut -d'=' -f2 | tr -d '[:space:]' || true)
52+
echo "version=$MC_VERSION" >> $GITHUB_OUTPUT
53+
54+
- name: Release
55+
run: npx semantic-release
56+
env:
57+
MINECRAFT_VERSION: "${{ steps.mcVersion.outputs.version }}"
58+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59+
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
60+
61+
# Because semantic-release also marks maintenance releases as latest,
62+
# we need to ensure that the highest semver release is marked as latest.
63+
promote-release:
64+
needs: release
65+
name: Mark highest semver as latest
66+
runs-on: ubuntu-latest
67+
68+
permissions:
69+
contents: write
70+
71+
steps:
72+
- name: Checkout
73+
uses: actions/checkout@v4
74+
with:
75+
fetch-depth: 0
76+
77+
- run: npm ci
78+
- name: Find and mark latest release
79+
uses: actions/github-script@v7
80+
with:
81+
script: |
82+
const semver = require('semver');
83+
const { owner, repo } = context.repo;
84+
85+
console.log(`Fetching all releases for ${owner}/${repo}...`);
86+
const { data: allReleases } = await github.rest.repos.listReleases({
87+
owner,
88+
repo,
89+
});
90+
91+
const sortedReleases = allReleases
92+
.filter(r => !r.draft && !r.prerelease && semver.valid(r.tag_name))
93+
.sort((a, b) => semver.rcompare(a.tag_name, b.tag_name));
94+
95+
if (sortedReleases.length === 0) {
96+
core.info("No valid, non-prerelease releases found. Exiting.");
97+
return;
98+
}
99+
100+
const latestRelease = sortedReleases[0];
101+
console.log(`Highest semver release found: ${latestRelease.tag_name}`);
102+
103+
console.log(`Updating release ${latestRelease.tag_name} to be the new 'latest' release.`);
104+
await github.rest.repos.updateRelease({
105+
owner,
106+
repo,
107+
release_id: latestRelease.id,
108+
make_latest: 'true',
109+
});
110+
console.log(`Successfully marked ${latestRelease.tag_name} as the latest release.`);
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Verify Maintenance Branch
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened, edited]
6+
branches: [main, 'mc/*']
7+
8+
jobs:
9+
verify:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout PR code
13+
uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
16+
17+
- name: Set common variables
18+
id: vars
19+
run: |
20+
PROPERTIES_FILE="gradle.properties"
21+
MC_VERSION_REGEX='minecraft_version\s*=\s*(.+)'
22+
23+
NEW_MC_VERSION=$(grep -oP "$MC_VERSION_REGEX" "$PROPERTIES_FILE" | cut -d'=' -f2 | tr -d '[:space:]' || true)
24+
25+
if [[ -z "$NEW_MC_VERSION" ]]; then
26+
echo "Could not determine Minecraft version in this PR."
27+
exit 1
28+
fi
29+
30+
OLD_MC_VERSION=$(git show ${{ github.event.pull_request.base.sha }}:"$PROPERTIES_FILE" | grep -oP "$MC_VERSION_REGEX" | cut -d'=' -f2 | tr -d '[:space:]' || true)
31+
32+
if [[ -z "$OLD_MC_VERSION" ]]; then
33+
echo "Could not determine base Minecraft version."
34+
exit 1
35+
fi
36+
37+
echo "new_mc_version=$NEW_MC_VERSION" >> $GITHUB_OUTPUT
38+
echo "old_mc_version=$OLD_MC_VERSION" >> $GITHUB_OUTPUT
39+
40+
- name: Verify that maintenance branch exists for version upgrades (for merges to main)
41+
if: github.base_ref == 'main'
42+
run: |
43+
NEW_MC_VERSION="${{ steps.vars.outputs.new_mc_version }}"
44+
OLD_MC_VERSION="${{ steps.vars.outputs.old_mc_version }}"
45+
46+
if [[ "$NEW_MC_VERSION" != "$OLD_MC_VERSION" ]]; then
47+
echo "Minecraft version change detected: $OLD_MC_VERSION -> $NEW_MC_VERSION"
48+
EXPECTED_BRANCH="mc/$OLD_MC_VERSION"
49+
echo "Verifying that maintenance branch '$EXPECTED_BRANCH' exists..."
50+
51+
if git ls-remote --exit-code --heads origin "$EXPECTED_BRANCH"; then
52+
echo "✅ Success: Maintenance branch '$EXPECTED_BRANCH' was found."
53+
exit 0
54+
else
55+
echo "❌ Failure: The required maintenance branch '$EXPECTED_BRANCH' does not exist."
56+
echo "Before merging this PR, you must create and push the maintenance branch for the previous version:"
57+
echo " git checkout main"
58+
echo " git pull"
59+
echo " git checkout -b $EXPECTED_BRANCH"
60+
echo " git push -u origin $EXPECTED_BRANCH"
61+
echo " git checkout -"
62+
echo "After creating the branch, re-run this workflow."
63+
exit 1
64+
fi
65+
else
66+
echo "No Minecraft version change detected. Check not required."
67+
exit 0
68+
fi
69+
70+
- name: Verify that Minecraft version was not changed (for merges to maintenance branches)
71+
if: startsWith(github.base_ref, 'mc/')
72+
run: |
73+
NEW_MC_VERSION="${{ steps.vars.outputs.new_mc_version }}"
74+
OLD_MC_VERSION="${{ steps.vars.outputs.old_mc_version }}"
75+
76+
if [[ "$NEW_MC_VERSION" != "$OLD_MC_VERSION" ]]; then
77+
echo "❌ Failure: Minecraft version change detected in maintenance branch."
78+
echo "You cannot change the Minecraft version in a maintenance branch."
79+
exit 1
80+
else
81+
echo "✅ Success: No Minecraft version change detected in maintenance branch."
82+
exit 0
83+
fi

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,8 @@ hs_err_*.log
3838
replay_*.log
3939
*.hprof
4040
*.jfr
41+
42+
# Node.js files for release scripts
43+
44+
node_modules/
45+
npm-debug.log

0 commit comments

Comments
 (0)