Skip to content

Do Release

Do Release #26

Workflow file for this run

name: Do Release
on:
workflow_dispatch:
inputs:
release-version:
description: 'Version to be released (e.g. 2.3.0).'
required: true
next-snapshot-version:
description: 'Version to be set after the release - without the -SNAPSHOT suffix (e.g. 2.4.0).'
required: true
env:
GIT_AUTHOR_NAME: Flash Gordon
GIT_AUTHOR_EMAIL: <>
GIT_COMMITTER_NAME: Terminator the Kitty
GIT_COMMITTER_EMAIL: <>
jobs:
do-release:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.maven_release.outputs.TAG }}
version: ${{ steps.maven_release.outputs.VERSION }}
base-version: ${{ steps.maven_release.outputs.BASE_VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Verify release notes file exists
run: |
VERSION=${{ github.event.inputs.release-version }}
BASE_VERSION="${VERSION%%-*}"
NOTES_FILE="distribution/doc/release-notes/${BASE_VERSION}.md"
if [ ! -f "$NOTES_FILE" ]; then
echo "::error::Release notes file not found: $NOTES_FILE"
echo "Create it before triggering the release workflow."
exit 1
fi
echo "Found release notes: $NOTES_FILE"
- name: Set up Java and credentials
uses: actions/setup-java@v5
with:
java-version: 11
distribution: 'temurin'
server-id: ossrh
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
cache: 'maven'
- name: Do the Maven release and prepare Linux assets
id: maven_release
run: |
VERSION=${{ github.event.inputs.release-version }}
BASE_VERSION="${VERSION%%-*}"
FULL_VERSION="JSignPdf-$VERSION"
NEXT_VERSION=${{ github.event.inputs.next-snapshot-version }}-SNAPSHOT
TAG=JSignPdf_${VERSION//\./_}
set -x
mvn --batch-mode clean install
mvn -P release --batch-mode "-Dtag=${TAG}" release:prepare \
"-DreleaseVersion=${VERSION}" \
"-DdevelopmentVersion=${NEXT_VERSION}"
mvn -P release --batch-mode release:perform \
-DstagingProgressTimeoutMinutes=30 -Dmaven.wagon.rto=7200000 \
-Dmaven.wagon.httpconnectionManager.maxPerRoute=60 -Dmaven.wagon.httpconnectionManager.maxTotal=100
cd distribution/target
ls -R
mkdir upload
mv *.zip upload/
cp generated-docs/JSignPdf.pdf "upload/$FULL_VERSION.pdf"
cp "../doc/release-notes/${BASE_VERSION}.md" upload/README.md
echo "TAG=$TAG" >> $GITHUB_OUTPUT
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "BASE_VERSION=$BASE_VERSION" >> $GITHUB_OUTPUT
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
- name: Stage Linux release assets for the publish job
uses: actions/upload-artifact@v4
with:
name: jsignpdf-linux-assets
path: distribution/target/upload/*
if-no-files-found: error
retention-days: 1
- name: Publish PDF guide for downstream jobs
uses: actions/upload-artifact@v4
with:
name: jsignpdf-pdf-guide
path: distribution/target/generated-docs/JSignPdf.pdf
if-no-files-found: error
retention-days: 1
windows-installers:
needs: do-release
runs-on: windows-latest
steps:
- name: Checkout release tag
uses: actions/checkout@v6
with:
ref: ${{ needs.do-release.outputs.tag }}
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
java-version: 21
distribution: 'temurin'
cache: 'maven'
- name: Build jsignpdf and installcert jars
shell: bash
run: mvn -B -DskipTests -pl jsignpdf,installcert -am package
- name: Download PDF guide from the release job
uses: actions/download-artifact@v4
with:
name: jsignpdf-pdf-guide
path: distribution/target/pdf-guide
- name: Build Windows installers (EXE / MSI / ZIP)
shell: pwsh
run: ./distribution/windows/build-windows-installers.ps1 -Version ${{ needs.do-release.outputs.version }}
- name: Stage Windows installers for the publish job
uses: actions/upload-artifact@v4
with:
name: jsignpdf-windows-assets
path: distribution/target/upload/*
if-no-files-found: error
retention-days: 1
publish-release:
needs: [do-release, windows-installers]
runs-on: ubuntu-latest
permissions:
contents: write
env:
TAG: ${{ needs.do-release.outputs.tag }}
VERSION: ${{ needs.do-release.outputs.version }}
BASE_VERSION: ${{ needs.do-release.outputs.base-version }}
FULL_VERSION: JSignPdf-${{ needs.do-release.outputs.version }}
steps:
- name: Checkout release tag
uses: actions/checkout@v6
with:
ref: ${{ needs.do-release.outputs.tag }}
- name: Download Linux assets
uses: actions/download-artifact@v4
with:
name: jsignpdf-linux-assets
path: release-assets/JSignPdf-${{ needs.do-release.outputs.version }}
- name: Download Windows assets
uses: actions/download-artifact@v4
with:
name: jsignpdf-windows-assets
path: release-assets/JSignPdf-${{ needs.do-release.outputs.version }}
- name: List staged assets
run: ls -R release-assets
- name: Upload all assets to SourceForge
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: |
set -euo pipefail
echo "$SSH_PRIVATE_KEY" > private_key
chmod 600 private_key
cd release-assets
sftp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ../private_key kwart@frs.sourceforge.net:/home/frs/project/jsignpdf/stable <<EOF
put -R "${FULL_VERSION}"
exit
EOF
cd ..
rm -f private_key
- name: Create GitHub release with all assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
NOTES_FILE="distribution/doc/release-notes/${BASE_VERSION}.md"
if [ ! -f "$NOTES_FILE" ]; then
echo "::error::Release notes file not found at $NOTES_FILE"
exit 1
fi
# Delete any pre-existing release so we publish a single release event
# with the correct body and the full asset set in one shot.
if gh release view "$TAG" >/dev/null 2>&1; then
gh release delete "$TAG" --yes --cleanup-tag=false
fi
shopt -s nullglob
assets=(release-assets/"$FULL_VERSION"/*)
if [ ${#assets[@]} -eq 0 ]; then
echo "::error::No assets found under release-assets/$FULL_VERSION/"
exit 1
fi
gh release create "$TAG" \
--title "$TAG" \
--notes-file "$NOTES_FILE" \
"${assets[@]}"