Release the project
The release is driven by an interactive script at the root of the repository:
$ ./release.sh
Run ./release.sh --help for the full list of options.
Script options
--localFull local rehearsal: release branch, Maven build with the
releaseprofile (javadoc, sources, GPG signing), tag, and release notes generation. Nothing is published remotely (no Maven Central, Docker Hub,git push, GitHub release, or production email).--skip-testsAdds
-DskipTeststo Maven build commands (also prefilled in the Extra Maven options prompt).--dry-runSimulates the workflow without running git or Maven commands.
--rollbackUndoes a local or failed release using the
release/.releasestate file (under the gitignoredrelease/directory). Deletes the local release branch and tag, checks out the original branch, and removesrelease/.release.
Typical local rehearsal:
$ cp .env.example .env
$ ./release.sh --local --skip-tests
If the release fails, or you want to discard the local rehearsal:
$ ./release.sh --rollback
The release/.release file is written as soon as the release branch is created, so --rollback
works even when the build fails midway.
What the script does (production release)
Create a release branch
Replace the SNAPSHOT version by the final version number
Commit the change
Build the final artifacts using the
releaseprofile (javadoc, sources, GPG signing)Tag the version
Prepare release notes from
docs/source/release/{version}.mdand GitHub APIDeploy to Maven Central using the
central-publishing-maven-pluginPrepare the next SNAPSHOT version
Commit the change
Merge the release branch into the branch you started from
Push the changes and the tag to origin
Create a GitHub release with
gh release createOptionally announce the version on https://discuss.elastic.co/c/annoucements/community-ecosystem
You will be guided through all the steps.
Release notes
Release notes live in Markdown under docs/source/release/ (for example 3.0.md).
They are included in the ReadTheDocs documentation via MyST Parser and reused by the release
script to build release/{version}/release-notes.md (gitignored work directory at the repo
root, outside target/ so mvn clean does not remove them).
The final notes combine:
A usage header (
scripts/templates/release-header.md)The version-specific Markdown file (MyST
{ref}resolved to ReadTheDocs links; heading levels demoted by one so they nest under the header)GitHub-generated changelist (
## What's Changed) fromgh api .../releases/generate-notes
The early preview during release.sh may show an incomplete GitHub section, because
generate-notes runs before the tag is pushed and then resolves against the remote default
branch. After a successful git push of the release tag, release.sh regenerates
release/{version}/release-notes.md so the GitHub release and announcement email use the
correct commit range.
release.sh always runs the full workflow. Working files for a given version are written under
release/{version}/ (for example release/3.0/release-notes.md and release/3.0/release.log)
so you can open and edit them in the IDE before sending the announcement.
To regenerate notes or resend the announcement without starting another release, call the helper scripts directly.
Regenerate the assembled notes (requires gh authenticated and GITHUB_REPO in .env):
$ python3 scripts/prepare-release-notes.py \
--version 3.0 \
--since-tag fscrawler-2.9
Send (or resend) the announcement email from an existing notes file:
$ python3 scripts/send-announcement.py \
release/3.0/release-notes.md \
--subject "FSCrawler 3.0 released"
To update notes after a GitHub release was already published, edit the Markdown file, regenerate
with prepare-release-notes.py, then run:
$ gh release edit fscrawler-{version} --notes-file release/{version}/release-notes.md
Before releasing
Verify that the project builds correctly with the release profile:
$ mvn clean install -Prelease -DskipTests
Prerequisites:
Copy
.env.exampleto.envand configure SMTP credentials andGITHUB_REPOpython3and the GitHub CLI (gh auth login)A clean-ish git working tree on your integration branch
GPG signing configured for the Maven
releaseprofile~/.m2/settings.xmlwith acentralserver entry (Sonatype Central token) for production deployDocker Hub credentials when pushing images (or pass
-Ddocker.skip)
Environment variables (.env)
See .env.example at the repository root:
Variable |
Purpose |
|---|---|
GITHUB_REPO |
GitHub repository ( |
SMTP_HOST |
SMTP server hostname |
SMTP_PORT |
SMTP port (465 for SSL) |
SMTP_USER |
SMTP username |
SMTP_PASS |
Mailbox password (quote special chars: |
SMTP_SECURITY |
Optional: |
ANNOUNCE_FROM |
Sender address (must match |
ANNOUNCE_TO |
Recipient (personal address for local, Elastic list for production) |
After deployment, check the publishing status on
Central Portal.
The central-publishing-maven-plugin is configured with autoPublish enabled, so artifacts
are published automatically once validation succeeds.
Maven Central release coordinates are immutable: answering “no” during the post-deploy checks only skips the git merge/push; it does not remove or replace what was published. If a release build on Central is wrong, publish a new version (for example a patch). Docker Hub tags can usually be overwritten by deploying the same tag again.
Release Drafter
The repository uses Release Drafter to
maintain a draft GitHub release on each push to main. Tags follow the fscrawler-{version}
convention. The final published release uses the hybrid notes assembled by release.sh.
Logs are written to release/<release-version>/release.log. On failure, the script prints the
last lines of the log and suggests ./release.sh --rollback.
Note
Only developers with write rights to the Sonatype Central namespace under fr.pilato
can perform the release.
Only developers with write rights to the DockerHub repository can push the Docker images.