Skip to content

chore: release 2.9.0 — local-project classpath fallback for expressio… #14

chore: release 2.9.0 — local-project classpath fallback for expressio…

chore: release 2.9.0 — local-project classpath fallback for expressio… #14

Workflow file for this run

name: Release
# Creates a GitHub Release when a v* tag is pushed. Release body is generated
# from commits in the previous v* tag's range by .github/scripts/release-notes.sh
# (Conventional-Commit buckets with emoji headers, mirroring the Release
# Generator template). The MCP server JAR and the standalone sandbox zip are
# attached as release assets.
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
# Default permissions are read-only; this job needs write for gh release create.
permissions:
contents: read
# Serialize tag-push runs so two near-simultaneous tags can't race on
# gh release upload. cancel-in-progress=false because release jobs should
# always complete (we don't want a half-uploaded release).
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # job-level scope for gh release create + upload assets
steps:
# Action pinned to SHA — protects against the major-version tag (v4)
# being moved to a malicious commit. Comment shows the tag at pin time
# so Dependabot updates are reviewable.
- name: Check out repository (full history for tag diffing)
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
# We use gh with GH_TOKEN; nothing here uses raw authenticated git,
# so don't leave GITHUB_TOKEN sitting in .git/config after checkout.
persist-credentials: false
- name: Set up JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
java-version: "21"
cache: maven
- name: Resolve current and previous tag
id: tags
env:
# GITHUB_REF_NAME comes from the runner; safe but mirror through
# env: for consistency with the defense-in-depth pattern.
CUR: ${{ github.ref_name }}
run: |
# Immediately-lower v* tag in semver order. Locate CUR in the
# descending-sorted list and emit the next entry — that's the
# correct predecessor regardless of whether CUR itself is the
# highest tag (the back-fill case pushed v2.1.2 after v2.2.0
# already existed and the old "highest other tag" heuristic
# picked v2.2.0 as previous, producing an empty changelog).
prev=$(git tag --list 'v*' --sort=-v:refname \
| awk -v cur="$CUR" 'found{print;exit} $0==cur{found=1}')
{
echo "cur=$CUR"
echo "prev=$prev"
echo "version=${CUR#v}"
} >> "$GITHUB_OUTPUT"
echo "Current: $CUR"
echo "Previous: ${prev:-<none>}"
- name: Build MCP server JAR
run: ./mvnw -pl jdwp-mcp-server -am clean package -DskipTests
- name: Stage JAR with versioned filename
id: jar
env:
VERSION: ${{ steps.tags.outputs.version }}
run: |
src="jdwp-mcp-server/target/mcp-jdwp-java.jar"
dst_versioned="dist/mcp-jdwp-java-${VERSION}.jar"
dst_alias="dist/mcp-jdwp-java.jar"
mkdir -p dist
if [[ ! -f "$src" ]]; then
echo "error: $src was not produced by the build" >&2
exit 1
fi
cp "$src" "$dst_versioned"
cp "$src" "$dst_alias"
{
echo "versioned=$dst_versioned"
echo "alias=$dst_alias"
} >> "$GITHUB_OUTPUT"
- name: Assemble standalone sandbox zip
id: sandbox
env:
VERSION: ${{ steps.tags.outputs.version }}
run: |
chmod +x release/sandbox/assemble.sh
release/sandbox/assemble.sh "$VERSION"
# Unversioned alias so /releases/latest/download/jdwp-sandbox.zip
# works across releases.
cp "release/sandbox/dist/jdwp-sandbox-${VERSION}.zip" \
"release/sandbox/dist/jdwp-sandbox.zip"
{
echo "versioned=release/sandbox/dist/jdwp-sandbox-${VERSION}.zip"
echo "alias=release/sandbox/dist/jdwp-sandbox.zip"
} >> "$GITHUB_OUTPUT"
- name: Generate release notes
env:
GH_TOKEN: ${{ github.token }}
CUR: ${{ steps.tags.outputs.cur }}
PREV: ${{ steps.tags.outputs.prev }}
run: |
chmod +x .github/scripts/release-notes.sh
.github/scripts/release-notes.sh "$CUR" "$PREV" > release-body.md
echo "── release-body.md ──"
cat release-body.md
echo "── end ──"
- name: Publish GitHub Release
env:
GH_TOKEN: ${{ github.token }}
CUR: ${{ steps.tags.outputs.cur }}
JAR_VERSIONED: ${{ steps.jar.outputs.versioned }}
JAR_ALIAS: ${{ steps.jar.outputs.alias }}
ZIP_VERSIONED: ${{ steps.sandbox.outputs.versioned }}
ZIP_ALIAS: ${{ steps.sandbox.outputs.alias }}
run: |
# Idempotent: edit if a release for this tag already exists
# (e.g. retroactively-created), otherwise create.
if gh release view "$CUR" >/dev/null 2>&1; then
echo "Release $CUR exists — updating notes and re-uploading assets."
gh release edit "$CUR" \
--notes-file release-body.md \
--title "$CUR"
gh release upload "$CUR" \
"$JAR_VERSIONED" "$JAR_ALIAS" \
"$ZIP_VERSIONED" "$ZIP_ALIAS" \
--clobber
else
gh release create "$CUR" \
--title "$CUR" \
--notes-file release-body.md \
"$JAR_VERSIONED" "$JAR_ALIAS" \
"$ZIP_VERSIONED" "$ZIP_ALIAS"
fi