From df4c3c2b3ad32840e4718e6d3cca40b28923d316 Mon Sep 17 00:00:00 2001 From: perronosaurio <27968093+perronosaurio@users.noreply.github.com> Date: Mon, 5 Oct 2026 19:08:57 +0000 Subject: [PATCH] Publish a release when a new version reaches master Tagging needed someone with push rights at a terminal. Now the release workflow also runs on pushes to master: if package.json has a version with no release yet, it runs the tests, creates the tag on that commit and publishes the release. Pushing a v* tag by hand still works. --- .github/workflows/release.yml | 52 ++++++++++++++++++++++++++--------- docs/RELEASING.md | 30 ++++++++++---------- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 95bf30b..71ecb2f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,10 @@ name: Release +# Publishes a GitHub release with a zip and a tar.gz of the server. +# - On master: when package.json has a version that has no release yet (merge a "Release x.y.z" PR). +# - On a v* tag pushed by hand: releases that tag (package.json must match it). on: push: + branches: [master] tags: ['v*'] permissions: contents: write @@ -9,28 +13,50 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 + - name: Work out the version + id: version + env: + GH_TOKEN: ${{ github.token }} + run: | + version="v$(node -p "require('./package.json').version")" + echo "tag=$version" >> "$GITHUB_OUTPUT" + if [ "$GITHUB_REF_TYPE" = "tag" ]; then + test "$version" = "$GITHUB_REF_NAME" \ + || { echo "package.json says $version, tag is $GITHUB_REF_NAME"; exit 1; } + echo "publish=true" >> "$GITHUB_OUTPUT" + elif gh release view "$version" > /dev/null 2>&1; then + echo "$version is already released, nothing to do." + echo "publish=false" >> "$GITHUB_OUTPUT" + else + echo "publish=true" >> "$GITHUB_OUTPUT" + fi - uses: actions/setup-node@v7 + if: steps.version.outputs.publish == 'true' with: node-version: 24 cache: npm - - run: npm ci - - run: npm run lint - - run: npm test - - name: Check that package.json matches the tag - run: | - test "v$(node -p "require('./package.json').version")" = "$GITHUB_REF_NAME" \ - || { echo "package.json says $(node -p "require('./package.json').version"), tag is $GITHUB_REF_NAME"; exit 1; } + - if: steps.version.outputs.publish == 'true' + run: npm ci && npm run lint && npm test - name: Build the archive + if: steps.version.outputs.publish == 'true' + env: + TAG: ${{ steps.version.outputs.tag }} run: | - git archive --format=zip --prefix="MCScript-${GITHUB_REF_NAME}/" -o "MCScript-${GITHUB_REF_NAME}.zip" "$GITHUB_REF_NAME" - git archive --format=tar.gz --prefix="MCScript-${GITHUB_REF_NAME}/" -o "MCScript-${GITHUB_REF_NAME}.tar.gz" "$GITHUB_REF_NAME" + git archive --format=zip --prefix="MCScript-${TAG}/" -o "MCScript-${TAG}.zip" HEAD + git archive --format=tar.gz --prefix="MCScript-${TAG}/" -o "MCScript-${TAG}.tar.gz" HEAD - name: Take the release notes from CHANGELOG.md - run: node scripts/release-notes.js "${GITHUB_REF_NAME#v}" > notes.md + if: steps.version.outputs.publish == 'true' + env: + TAG: ${{ steps.version.outputs.tag }} + run: node scripts/release-notes.js "${TAG#v}" > notes.md - name: Publish the release + if: steps.version.outputs.publish == 'true' env: GH_TOKEN: ${{ github.token }} + TAG: ${{ steps.version.outputs.tag }} run: | flags="" - case "$GITHUB_REF_NAME" in *-*) flags="--prerelease" ;; esac - gh release create "$GITHUB_REF_NAME" MCScript-*.zip MCScript-*.tar.gz \ - --title "MCScript ${GITHUB_REF_NAME#v}" --notes-file notes.md $flags + case "$TAG" in *-*) flags="--prerelease" ;; esac + # creates the tag on this commit when it doesn't exist yet + gh release create "$TAG" MCScript-*.zip MCScript-*.tar.gz \ + --target "$GITHUB_SHA" --title "MCScript ${TAG#v}" --notes-file notes.md $flags diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 82d761a..c542558 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -1,7 +1,7 @@ # Releasing a new version Every version is published as a GitHub release with a zip and a tar.gz of the server, the way MCGalaxy does -it. The release workflow (`.github/workflows/release.yml`) does the work once a version tag is pushed. +it. The release workflow (`.github/workflows/release.yml`) does the work when a new version reaches `master`. ## Version numbers @@ -17,23 +17,25 @@ update check doesn't announce them to servers on a final release. ## Steps 1. Make sure CI is green on `master`. -2. In `CHANGELOG.md`, rename the `## Unreleased` section to the new version and date, for example - `## 2.1.0 (2026-11-02)`, and start a new empty `## Unreleased` section above it. +2. On a new branch, rename the `## Unreleased` section of `CHANGELOG.md` to the new version and date, for + example `## 2.2.0 (2026-11-02)`, and start a new empty `## Unreleased` section above it. 3. Update the version in `package.json` and `package-lock.json`: ```bash - npm version 2.1.0 --no-git-tag-version - ``` -4. Commit both files with the message `Release 2.1.0` and push to `master`. -5. Tag the commit and push the tag: - ```bash - git tag v2.1.0 - git push origin v2.1.0 + npm version 2.2.0 --no-git-tag-version ``` +4. Commit both files as `Release 2.2.0`, open a pull request and merge it once CI passes. + +That's it. When `master` gets a `package.json` version that has no release yet, the release workflow runs +the lint and tests, creates the `v2.2.0` tag on that commit, builds `MCScript-v2.2.0.zip` and `.tar.gz` +(without the tests and GitHub files) and publishes the release with the changelog section as its notes. The +release appears under **Releases** a couple of minutes after the merge. Merges that don't change the version +don't publish anything. + +Pushing a `v*` tag by hand also works: the workflow then releases that tag, as long as `package.json` has the +same version. -The workflow then runs the lint and tests, checks that the tag matches `package.json`, builds -`MCScript-v2.1.0.zip` and `.tar.gz` (without the tests and GitHub files) and creates the release with the -changelog section as its notes. If something fails, fix it, delete the tag (`git push --delete origin v2.1.0`, -`git tag -d v2.1.0`) and tag again. +If the workflow fails, fix the cause and merge the fix; the next push to `master` tries again, since that +version still has no release. Servers running an older version print a message in the console with a link to the new release when they start (unless `checkForUpdates` is off).