javachanges is a small Java CLI that brings a Changesets-like release planning workflow to Maven and Gradle repositories.
Documentation site: https://javachanges.icebreaker.top
It is designed for repositories that want:
- file-based release intents in
.changesets/*.md - reviewed release plans before version bumps land
- generated changelog and release notes
- CI-friendly publish checks and release helpers
- optional GitHub and GitLab variable sync helpers
This repository is the standalone source home for javachanges.
The current codebase focuses on:
- adding and validating changesets
- generating release plans
- updating the root Maven
revisionor Gradlegradle.propertiesversion - generating changelog and release notes
- preparing Maven settings from environment variables
- release preflight and publish helpers
- GitHub and GitLab environment-variable auditing
- GitHub and GitLab release PR / MR and tag automation helpers
Requirements:
- Java 8+
- Maven 3.8+
- a git repository
- a Maven repository with a root
pom.xml, or a Gradle repository withgradle.properties - either Maven
<modules>, Gradleinclude(...)entries insettings.gradle(.kts), or a single root artifact/project
Recommended for target repositories: declare the Maven plugin and run the short local goals:
<plugin>
<groupId>io.github.sonofmagic</groupId>
<artifactId>javachanges</artifactId>
<version><!-- latest released version --></version>
</plugin>Then inside that repository:
mvn javachanges:setup
mvn javachanges:init -Djavachanges.config=true
mvn javachanges:next
mvn javachanges:modules
mvn javachanges:status
mvn javachanges:validate
mvn javachanges:plan -Djavachanges.apply=true
mvn javachanges:add -Djavachanges.summary="add release notes command" -Djavachanges.release=minor
mvn javachanges:version
mvn javachanges:write-settings -Djavachanges.settingsMode=release
mvn javachanges:doctor-publish
mvn javachanges:preflight -Djavachanges.tag=v1.2.3
mvn javachanges:publish -Djavachanges.tag=v1.2.3
mvn javachanges:manifest-field -Djavachanges.field=releaseVersion -Djavachanges.fresh=true
mvn javachanges:release-notes -Djavachanges.tag=v1.2.3 -Djavachanges.output=target/release-notes.mdThe plugin defaults --directory to the current Maven project's ${project.basedir}, so if you run it inside the target repository you usually do not need to pass --directory explicitly. The generic run goal still exists for commands that do not have a dedicated goal yet.
If you cannot modify the target repository pom.xml, or you are using Gradle, use the released CLI from Maven Central instead:
mvn -q dependency:copy -Dartifact=io.github.sonofmagic:javachanges:<released-version> -DoutputDirectory=.javachanges
java -jar .javachanges/javachanges-<released-version>.jar --helpOn the current main branch, after installing the snapshot locally, you can also run javachanges as a Maven plugin:
./mvnw -q -DskipTests install
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:setup
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:init -Djavachanges.config=true
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:next
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:modules
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:status
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:validate
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:plan -Djavachanges.apply=true
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:add -Djavachanges.summary="add release notes command" -Djavachanges.release=minor
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:write-settings -Djavachanges.settingsMode=release
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:doctor-publish
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:manifest-field -Djavachanges.field=releaseVersion
mvn io.github.sonofmagic:javachanges:1.12.0-SNAPSHOT:release-notes -Djavachanges.tag=v1.2.3 -Djavachanges.output=target/release-notes.mdRepository-local shortcuts for working on javachanges itself:
pnpm ci:local
pnpm ci:local:build
pnpm ci:local:docs
pnpm ci:local:release
./mvnw -B test
./mvnw -B -Pcoverage -Dmaven.repo.local=.m2/repository test
pnpm snapshot:install
pnpm snapshot:preflight
pnpm snapshot:publish:local
pnpm docs:deploy:localThese map to the same phases used elsewhere in the docs:
ci:localruns the local CI simulation: Java build checks, docs build, and release automation dry-runsci:local:buildmirrors the Java build steps from.github/workflows/ci.ymlci:local:docsinstalls docs dependencies and runs the VitePress buildci:local:releasevalidates release PR/MR planning, publish readiness, and snapshot publish preflight in dry-run mode only./mvnw -B testruns the default test suite with build prerequisite checks./mvnw -B -Pcoverage -Dmaven.repo.local=.m2/repository testalso generates a JaCoCo HTML report undertarget/site/jacoco/snapshot:installinstalls the current1.12.0-SNAPSHOTinto local Mavensnapshot:preflightpreviews a local snapshot publish withlocal.dev.001snapshot:publish:localpublishes a unique snapshot throughcentral-publishing-maven-plugindocs:deploy:localrebuildswebsite/distand serves it through Wrangler locally
The snapshot shortcuts pin Maven's local repository to .m2/repository inside this repository so local bootstrap does not depend on a writable global ~/.m2.
Snapshot verification:
- Snapshot repository:
https://central.sonatype.com/repository/maven-snapshots/ - Snapshot metadata pattern:
https://central.sonatype.com/repository/maven-snapshots/io/github/sonofmagic/javachanges/<resolved-snapshot-version>/maven-metadata.xml - Snapshot artifact pattern:
https://central.sonatype.com/repository/maven-snapshots/io/github/sonofmagic/javachanges/<resolved-snapshot-version>/javachanges-<timestamped-version>.jar
Sonatype currently does not provide a working browse UI for hosted snapshots, so the practical verification path is to open maven-metadata.xml, open the exact artifact URL, or resolve the dependency from Maven/Gradle.
Published package:
- Maven Central page:
https://central.sonatype.com/artifact/io.github.sonofmagic/javachanges - CLI jar URL pattern:
https://repo1.maven.org/maven2/io/github/sonofmagic/javachanges/<released-version>/javachanges-<released-version>.jar
Released CLI examples against a target repository:
java -jar .javachanges/javachanges-<released-version>.jar status --directory /path/to/your/repo
java -jar .javachanges/javachanges-<released-version>.jar add --directory /path/to/your/repo
java -jar .javachanges/javachanges-<released-version>.jar plan --directory /path/to/your/repoIf you want to work on this repository itself from source, see Development Guide.
For Maven repositories, see Maven Usage Guide. The short version is: keep the root version in a <revision> property, use the Maven plugin for day-to-day commands, and use the released CLI jar when you cannot change the target pom.xml.
For Gradle repositories, see Gradle Usage Guide. The short version is: keep version=...-SNAPSHOT in gradle.properties, define projects in settings.gradle(.kts), and run the released CLI jar directly.
javachanges now defaults to the same core markdown shape used by Node.js Changesets:
---
"javachanges": minor
---
Add GitHub Actions release automation.Monorepo example:
---
"core": minor
"cli": patch
---
Improve CLI parsing and release planning.How to read it:
- each frontmatter key is a Maven artifactId or Gradle project name
- each value is the semver bump for that artifact:
patch,minor,major - the markdown body is the user-facing summary and notes
Defaults and behavior:
javachanges addwrites the official package-map style by default- if you use
--modules all,javachangeswrites all detected Maven artifactIds or Gradle project names - the first non-empty body line becomes the summary shown in
status, release PRs, changelogs, and release notes - changelog sections are grouped by the aggregated release level:
major,minor,patch
The shortest hand-written form for a single-module repository is:
---
"javachanges": patch
---
Fix Windows path handling in release-notes generation.Compatibility:
- the old
release/modules/summary/typefrontmatter format is still accepted when reading existing files - new files should use the official package-map style above
Legacy format example:
---
release: minor
type: ci
modules: javachanges
summary: automate javachanges self-release publishing via GitHub Actions
---Field reference:
"artifactId"/"projectName"Required in the new format. Each frontmatter key is a Maven artifactId or Gradle project name, usually quoted to match official Changesets style. For single-module repositories, this is typically the root artifactId or root project name. For monorepos, add one entry per affected module.patch/minor/majorRequired value for each artifactId entry. Controls the semver bump contributed by that module. Allowed values:patch,minor,major. Typical guidance:patchfor backwards-compatible fixes, docs, chores, CI, or small improvements.minorfor backwards-compatible features.majorfor breaking changes.- body Recommended markdown body below the frontmatter. The first non-empty line is reused as the summary. Additional paragraphs or bullets can hold rollout notes, migration details, or context.
typeLegacy optional metadata field, only for backwards compatibility with olderjavachangesfiles. New files should generally omit it.release,modules,summaryLegacy fields from the olderjavachangesformat. Still accepted for parsing existing files, but no longer recommended for new changesets.
src/main/java: the CLI source codedocs/: public documentation pagesexamples/basic-monorepo/: a minimal Maven example repository with CI templates and generated release-plan snapshotsexamples/basic-gradle-monorepo/: a minimal Gradle example repository with CI templates and generated release-plan snapshotswebsite/: the VitePress site published as static assets with Workers + Wrangler- Cloudflare can connect this repository directly through Workers Builds, so GitHub does not need a dedicated docs deploy workflow
env/release.env.example: a generic env template for release automation
High-value commands:
initsetupaddnextmodulesstatusvalidateplanmanifest-fieldversionwrite-settingsinit-gradle-tasksinit-envauth-helprender-varsdoctor-localdoctor-platformsync-varsaudit-varsdoctor-publishpreflightpublishgradle-publishrelease-notesensure-gpg-public-keyrelease-version-from-tagrelease-module-from-tagassert-moduleassert-snapshotassert-release-tagmodule-selector-args
GitHub-specific helpers:
github-release-plangithub-tag-from-plangithub-release-publish-stategithub-release-from-planinit-github-actions
GitLab-specific helpers:
gitlab-release-plangitlab-tag-from-plangitlab-releaseinit-gitlab-ci
- Overview
- Overview (zh-CN)
- Getting Started
- Getting Started (zh-CN)
- Maven Usage Guide
- Maven Usage Guide (zh-CN)
- Gradle Usage Guide
- Gradle Usage Guide (zh-CN)
- Examples Guide
- Examples Guide (zh-CN)
- Command Cookbook
- Command Cookbook (zh-CN)
- Configuration Reference
- Configuration Reference (zh-CN)
- CLI Reference
- CLI Reference (zh-CN)
- Output Contracts
- Output Contracts (zh-CN)
- Development Guide
- Development Guide (zh-CN)
- Release Plan Manifest
- Release Plan Manifest (zh-CN)
- Troubleshooting Guide
- Troubleshooting Guide (zh-CN)
- Cloudflare Workers Builds
- Cloudflare Workers Builds (zh-CN)
- GitHub Actions Release Flow
- GitHub Actions Release Flow (zh-CN)
- GitHub Actions Usage Guide
- GitHub Actions Usage Guide (zh-CN)
- GitLab CI/CD Usage Guide
- GitLab CI/CD Usage Guide (zh-CN)
- Publish To Maven Central
- Publish To Maven Central (zh-CN)
- Use Cases
- Use Cases (zh-CN)
Apache-2.0