| description | Complete command reference for javachanges, including release planning, environment, and publishing helpers. |
|---|
This page is the command reference for javachanges.
Use it when you already understand the release workflow and need to look up:
- the command name
- required flags
- common argument combinations
- what each command reads or writes
Current main branch Maven plugin invocation after local snapshot install:
mvn -q -DskipTests install
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:next
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:modules
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:status
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:plan -Djavachanges.apply=true
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:add -Djavachanges.summary="add release notes command" -Djavachanges.release=minor
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:version
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:preflight -Djavachanges.tag=v1.2.3
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:publish -Djavachanges.tag=v1.2.3
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:manifest-field -Djavachanges.field=releaseVersion -Djavachanges.fresh=true
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:release-notes -Djavachanges.tag=v1.2.3 -Djavachanges.output=target/release-notes.mdSource-driven invocation while developing this repository:
mvn -q -DskipTests compile exec:java -Dexec.args="status --directory /path/to/repo"Common parts:
| Part | Meaning |
|---|---|
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:setup |
Run first-time setup with safe defaults |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:init -Djavachanges.config=true |
Initialize .changesets/ files and print starter commands |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:next |
Ask javachanges which release workflow command to run next |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:modules |
List detected build metadata and module names |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:status |
Run the dedicated Maven plugin status goal |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:validate |
Run local release-readiness checks |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:plan -Djavachanges.apply=true |
Run the dedicated plan goal |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:init-env |
Initialize the local release env file |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:auth-help -Djavachanges.platform=github |
Show required authentication variables |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:doctor-local -Djavachanges.envFile=env/release.env.local |
Check local release prerequisites |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:sync-vars -Djavachanges.envFile=env/release.env.local -Djavachanges.platform=github |
Preview platform variable sync |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:github-release-plan -Djavachanges.githubRepo=owner/repo |
Create or update the GitHub release-plan pull request |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:github-release-from-plan -Djavachanges.fresh=true |
Generate release notes and sync the GitHub Release |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:gitlab-release-plan -Djavachanges.projectId=12345 |
Create or update the GitLab release-plan merge request |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:gitlab-release -Djavachanges.tag=v1.2.3 |
Generate release notes and sync the GitLab Release |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:release-version-from-tag -Djavachanges.tag=core/v1.2.3 |
Extract a release version from a tag |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:module-selector-args -Djavachanges.module=core |
Print build-tool selector args |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:gradle-publish -Djavachanges.directory=/path/to/gradle-repo -Djavachanges.tag=v1.2.3 |
Render or execute the Gradle publish command from a Maven runner project |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:init-github-actions -Djavachanges.force=true |
Generate the GitHub Actions release workflow |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:init-gitlab-ci -Djavachanges.force=true |
Generate the GitLab CI release template |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:publish -Djavachanges.tag=v1.2.3 |
Run the dedicated Maven publish dry-run goal |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:ensure-gpg-public-key |
Publish and verify the signing public key |
mvn io.github.sonofmagic:javachanges:__JAVACHANGES_CURRENT_SNAPSHOT_VERSION__:run -Djavachanges.args="..." |
Use the generic bridge goal for commands without a dedicated goal |
mvn -q -DskipTests compile exec:java |
Build the CLI and run the Java entrypoint |
-Dexec.args="..." |
Pass javachanges CLI arguments |
--directory /path/to/repo |
Target Maven or Gradle repository root, or a subdirectory inside it |
Plugin note:
- all dedicated goals and
javachanges:runinject--directory ${project.basedir}automatically unless you already passed--directoryexplicitly - output language defaults to English; pass
--language zh-CN, setJAVACHANGES_LANGUAGE=zh-CN, or use-Djavachanges.language=zh-CNwith Maven plugin goals to render javachanges prompts, errors, and generated Markdown in Chinese - for CI or external repositories, you can call the published plugin directly without a custom runner POM:
mvn -B io.github.sonofmagic:javachanges:__JAVACHANGES_LATEST_RELEASE_VERSION__:run -Djavachanges.args="gitlab-release-plan --directory $CI_PROJECT_DIR --write-plan-files false --execute true"Language examples:
javachanges status --directory . --language zh-CN
JAVACHANGES_LANGUAGE=zh-CN javachanges plan --directory . --apply true
mvn javachanges:status -Djavachanges.language=zh-CNIf you declare the plugin in a target repository pom.xml, the shortest local form becomes:
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: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.mdGradle repositories should use the CLI jar form:
mvn -q dependency:copy -Dartifact=io.github.sonofmagic:javachanges:__JAVACHANGES_LATEST_RELEASE_VERSION__ -DoutputDirectory=.javachanges
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar status --directory /path/to/gradle-repo
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar plan --directory /path/to/gradle-repo --apply trueGradle detection requires gradle.properties with version or revision, plus settings.gradle(.kts) or build.gradle(.kts).
Note: some commands do not require a repository, for example
release-version-from-tag.
When javachanges is executed through exec-maven-plugin, keep the entire CLI payload inside one -Dexec.args=... value. Do not define a reusable shell fragment that ends with bare -Dexec.args= and append the real command later, because the shell, Make, or CI runner may split the next token and Maven will then treat it as a lifecycle phase.
Recommended Makefile pattern:
MVNW := ./mvnw
JAVACHANGES_MVN := $(MVNW) -q -DskipTests compile exec:java
jc-version:
$(JAVACHANGES_MVN) -Dexec.args="version --directory $(CURDIR)"Recommended parameterized Makefile pattern:
MVNW := ./mvnw
JAVACHANGES_MVN := $(MVNW) -q -DskipTests compile exec:java
define RUN_JAVACHANGES
$(JAVACHANGES_MVN) -Dexec.args="$(1) --directory $(CURDIR)"
endef
jc-status:
$(call RUN_JAVACHANGES,status)Recommended GitLab CI pattern:
script:
- >
./mvnw -q -DskipTests compile exec:java
-Dexec.args="version --directory $CI_PROJECT_DIR"Not recommended:
JAVACHANGES = ./mvnw -q -DskipTests compile exec:java -Dexec.args=
jc-version:
$(JAVACHANGES) "version --directory $(CURDIR)"Why it breaks:
-Dexec.args=is already complete before the next token is appended.- The quoted
version --directory ...token is no longer attached to the system property assignment. - Maven receives that token as a positional argument and may parse it as a lifecycle phase, causing errors such as
Unknown lifecycle phase "version --directory ...".
Rules of thumb:
- keep
-Dexec.args="..."in the final command line, not in a prefix variable - prefer one shell command per invocation
- if you need reuse, wrap the whole command in a Make function or shell script
- in CI YAML, prefer one folded scalar command instead of concatenating fragments across variables
| Command | Purpose | Writes files |
|---|---|---|
setup |
Run first-time setup with safe defaults; optional flags can also generate env and CI templates | .changesets/README.md, .changesets/config.jsonc, optional env and CI files |
init |
Initialize .changesets/README.md with starter examples, optionally .changesets/config.jsonc, and print starter commands |
.changesets/README.md, optional .changesets/config.jsonc |
init-gradle-tasks |
Generate a Gradle script plugin that registers javachanges tasks | gradle/javachanges.gradle, optional build.gradle(.kts) with --apply true |
add |
Create a changeset | .changesets/*.md |
next |
Suggest the next release workflow command, including local, GitHub, and GitLab paths | No |
modules |
List detected build metadata and module names | No |
status |
Show the current release plan | No |
validate |
Check local release readiness, including build metadata, changesets, config, git state, and planned tags | No |
plan |
Render the current release plan | No |
plan --apply true |
Apply the plan and consume changesets | pom.xml or gradle.properties, CHANGELOG.md, .changesets/release-plan.json, .changesets/release-plan.md, .changesets/release-plan-backup.json |
manifest-field |
Read a field from the generated release manifest, or use --fresh true to derive it from the current repository state |
No |
release-notes |
Generate release notes for a tag | target file |
ensure-gpg-public-key |
Publish and verify the current signing public key on supported keyservers | No |
preflight |
Render publish validation commands | No |
publish |
Render or execute the Maven publish command | No |
gradle-publish |
Render or execute the Gradle publish command | No |
Run first-time setup with safe defaults:
mvn javachanges:setup
mvn -q -DskipTests compile exec:java -Dexec.args="setup --directory /path/to/repo"By default, setup writes only .changesets/README.md and .changesets/config.jsonc, detects the build model and modules, then prints the next useful commands. Use --env true, --github-actions true, --gitlab-ci true, or --gradle-tasks true to also generate release env, CI templates, or Gradle task shortcuts. For Gradle repositories, --apply-gradle-tasks true also writes the Gradle task script and appends it to build.gradle(.kts). Existing generated files are preserved unless --force true is passed.
Initialize the changeset directory for a repository and print the next commands to run.
Examples:
mvn javachanges:init -Djavachanges.config=true
mvn -q -DskipTests compile exec:java -Dexec.args="init --directory /path/to/repo --config"Use --force or -Djavachanges.force=true to replace an existing .changesets/config.json or .changesets/config.jsonc with the default template.
The same force flag also refreshes an existing .changesets/README.md with the current starter guide; without it, custom README content is preserved.
Generate a Gradle script plugin that registers javachanges tasks for a Gradle repository.
Examples:
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar init-gradle-tasks --directory /path/to/gradle-repo
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar init-gradle-tasks --directory /path/to/gradle-repo --apply true
mvn javachanges:init-gradle-tasks -Djavachanges.directory=/path/to/gradle-repo
mvn javachanges:init-gradle-tasks -Djavachanges.directory=/path/to/gradle-repo -Djavachanges.apply=trueThe default output is gradle/javachanges.gradle. Use --apply true or -Djavachanges.apply=true to append it to build.gradle.kts with apply(from = "gradle/javachanges.gradle"), or to build.gradle with apply from: "gradle/javachanges.gradle". The generated tasks include javachangesStatus, javachangesStatusJson, javachangesAdd, javachangesPlan, javachangesApplyPlan, javachangesRestorePlan, javachangesDoctorPublish, javachangesGradlePublish, and release automation shortcuts. The script resolves io.github.sonofmagic:javachanges from existing repositories, adds mavenCentral() only when no repositories exist, can use a local jar with -Pjavachanges.jar=.javachanges/javachanges.jar, supports JVM options through -Pjavachanges.jvmArgs="...", supports global CLI options through -Pjavachanges.directory=... and -Pjavachanges.language=zh-CN, supports scoped modeled options such as -Pjavachanges.status.format=json, and appends raw CLI options with -Pjavachanges.extraArgs="--format json" or command-scoped properties such as -Pjavachanges.status.extraArgs="--format json".
Create a new changeset file.
Example:
mvn -q -DskipTests compile exec:java -Dexec.args="add --directory /path/to/repo --summary 'add release notes command' --release minor --modules core"Behavior:
| Input | Meaning |
|---|---|
--summary |
First line of the generated markdown body |
--release |
patch, minor, or major |
--modules |
Comma-separated Maven artifactIds, Gradle project names, or all |
--body |
Optional extra markdown content after the summary |
--format |
text or json |
--no-interactive |
Fail instead of prompting when --summary or --release is missing |
If --release is not one of patch, minor, or major, the command fails before writing a file and prints the allowed values.
When prompts are enabled, multi-module repositories also prompt for affected modules and show the detected module names. Use --no-interactive true in CI or scripts so missing input fails with a clear error instead of waiting for stdin.
Use --format json when automation needs the created changeset path, affected packages, and next commands.
After writing the file, add prints the resolved release level, affected packages, and status / next commands for the same repository so users can review the plan immediately.
Generated file shape:
```md
---
"core": minor
---
add release notes command
```Compatibility note:
addstill accepts legacy flag names such as--releaseand--modules- the generated file itself uses the official Changesets-style package map
Show the current pending release plan.
Example:
mvn -q -DskipTests compile exec:java -Dexec.args="status --directory /path/to/repo"Typical output includes:
- current root revision
- latest whole-repo tag
- pending changeset count
- release plan summary
- affected packages
- each pending changeset entry
- next-step commands for creating or applying a changeset
Render the release plan without writing files:
mvn -q -DskipTests compile exec:java -Dexec.args="plan --directory /path/to/repo"Without --apply true, plan prints the same review-oriented next steps as status, including the exact apply command when changesets are pending.
Apply the release plan:
mvn -q -DskipTests compile exec:java -Dexec.args="plan --directory /path/to/repo --apply true"When --apply true is used, javachanges:
- updates the root Maven
<revision>or Gradlegradle.propertiesversion - prepends a new section to
CHANGELOG.md - writes
.changesets/release-plan.json - writes
.changesets/release-plan.md - writes
.changesets/release-plan-backup.jsonbefore modifying files - deletes the consumed changeset files
After applying the plan, the command prints copyable restore, git status, git add, git commit, and javachanges next commands for the same repository. The git add command uses the detected build tool, so Maven repositories include pom.xml and Gradle repositories include gradle.properties.
To undo a local apply before committing it:
mvn -q -DskipTests compile exec:java -Dexec.args="plan --directory /path/to/repo --restore true"Automation commands such as github-release-plan and gitlab-release-plan avoid
committing the generated release-plan.json and release-plan.md files by default.
The PR/MR body is generated as a transient file, and later tag/release jobs should use
--fresh true. Pass --write-plan-files true only for compatibility with older
manifest-based automation.
Read a field from the generated release manifest, or derive it from the current repository state.
Example:
mvn -q -DskipTests compile exec:java -Dexec.args="manifest-field --directory /path/to/repo --field releaseVersion"
mvn -q -DskipTests compile exec:java -Dexec.args="manifest-field --directory /path/to/repo --field releaseVersion --fresh true"Common fields:
| Field | Meaning |
|---|---|
releaseVersion |
Release version without the leading v |
nextSnapshotVersion |
Next root snapshot version |
releaseLevel |
Aggregated release type |
--fresh true uses pending changesets when they still exist. After an applied release
plan has consumed changesets, it infers whole-repo release metadata from the current
snapshot version, for example 1.2.0-SNAPSHOT becomes release version 1.2.0.
| Command | Purpose | Example |
|---|---|---|
version |
Print the current root revision | version --directory /path/to/repo --format json |
modules |
List detected Maven artifactIds or Gradle project names | modules --directory /path/to/repo --format json |
release-version-from-tag |
Extract 1.2.3 from v1.2.3 or core/v1.2.3 |
release-version-from-tag --tag v1.2.3 --format json |
release-module-from-tag |
Extract the package/module name from core/v1.2.3 |
release-module-from-tag --tag core/v1.2.3 --format json |
assert-module |
Validate a Maven artifactId or Gradle project name exists | assert-module --directory /path/to/repo --module core |
assert-snapshot |
Ensure the current revision is a snapshot | assert-snapshot --directory /path/to/repo |
assert-release-tag |
Ensure a tag matches the current repository version | assert-release-tag --directory /path/to/repo --tag v1.2.3 |
module-selector-args |
Print build-tool selector args | module-selector-args --directory /path/to/repo --module core |
version supports --format json when automation needs the build tool, version file, snapshot flag, and release version derived from the current revision.
The release tag parsing commands support --format json and return both releaseVersion and releaseModule, so scripts can parse a tag once and reuse both fields.
modules also prints copyable add commands. For multi-module repositories, it includes both a first-module example and a --modules all example. Use --format json when automation needs the detected build tool, version file, module list, and generated add commands.
For Maven repositories, module-selector-args --module core prints Maven -pl :core -am.
For Gradle repositories, it prints the Gradle project selector :core.
| Command | Purpose |
|---|---|
write-settings |
Generate a Maven settings.xml file |
init-env |
Initialize a local release env file from the example template |
auth-help |
Print platform auth requirements |
render-vars |
Preview GitHub/GitLab variables and secrets, or emit JSON with --format json |
doctor-local |
Check local release prerequisites, or emit JSON with --format json |
doctor-platform |
Check remote platform readiness, or emit JSON with --format json |
sync-vars |
Sync variables to GitHub or GitLab |
audit-vars |
Compare local env values with remote platform state, or emit JSON with --format json |
ensure-gpg-public-key |
Upload the current public signing key and wait until a supported keyserver can fetch it |
write-settings defaults to --mode all, which writes release and snapshot server entries. Use --mode release or --mode snapshot when a CI job only has credentials for one publish lane.
Example:
mvn -q -DskipTests compile exec:java -Dexec.args="render-vars --directory /path/to/repo --env-file env/release.env.local --platform github"Structured-output example:
mvn -q -DskipTests compile exec:java -Dexec.args="doctor-local --directory /path/to/repo --env-file env/release.env.local --format json"Commands that currently support --format json:
| Command | Notes |
|---|---|
add |
Includes created changeset path, release level, affected packages, and next commands |
version |
Includes build tool, version file, current revision, release version, and snapshot flag |
modules |
Includes build tool, version file, current revision, module list, and add commands |
release-version-from-tag |
Includes tag, release version, and release module |
release-module-from-tag |
Includes tag, release version, and release module |
status |
Includes the current release-plan status and review commands |
next |
Includes pending release metadata and recommended next commands |
plan |
Includes dry-run/apply/restore metadata and next commands |
validate |
Includes release-readiness check results and issues |
render-vars |
Includes platform and showSecrets in the payload |
doctor-local |
Includes section summaries, suggestions, and final error text on failure |
doctor-platform |
Includes platform and section summaries for env and CLI checks |
audit-vars |
Includes platform, audit sections, and final error text on failure |
doctor-publish |
Includes publish target, mode, tag, build tool, module, Gradle task, current revision, publish version, snapshot mode fields, readiness checks, repair suggestions, and next commands |
preflight |
Includes publish action metadata plus snapshot mode fields such as snapshotVersionMode, effectiveVersion, and snapshotBuildStampApplied |
publish |
Includes publish action metadata such as tag, module, release version, and release notes file |
gradle-publish |
Includes Gradle publish action metadata such as tag, module, release version, and snapshot mode |
github-release-plan |
Includes action, skip reason, and release version |
github-tag-from-plan |
Includes action, skip reason, release version, and tag |
github-release-from-plan |
Includes action, tag, release version, and release notes file |
gitlab-release-plan |
Includes action, skip reason, release version, and project id |
gitlab-tag-from-plan |
Includes action, skip reason, release version, module, and tag |
gitlab-release |
Includes action, project id, tag, module, release version, and release notes file |
Common flags for these commands:
| Flag | Used by | Meaning |
|---|---|---|
--env-file |
all four | input env file path |
--platform |
render-vars, doctor-platform, audit-vars |
github, gitlab, or all |
--show-secrets |
render-vars |
reveal secret values instead of masking them |
--github-repo |
doctor-local, doctor-platform, audit-vars |
optional GitHub owner/repo identifier |
--gitlab-repo |
doctor-local, doctor-platform, audit-vars |
optional GitLab group/project identifier |
--format json |
all four | switch stdout from human text to machine-readable JSON |
Use this command in CI after GPG import and before a Maven Central publish:
mvn -q -DskipTests compile exec:java -Dexec.args="ensure-gpg-public-key --directory /path/to/repo"What it does:
- reads the imported secret key fingerprint from
gpg - attempts to publish the public key to
hkps://keyserver.ubuntu.comandhkps://keys.openpgp.org - retries until at least one supported keyserver can fetch the key
Useful flags:
| Flag | Meaning |
|---|---|
--primary-keyserver |
Override the first keyserver URL |
--secondary-keyserver |
Override the fallback keyserver URL |
--attempts |
Maximum discovery attempts before failure |
--retry-delay-seconds |
Delay between discovery attempts |
JSON mode contract:
- stdout contains only one JSON object
- exit code
0means success, non-zero means validation failure or execution error - top-level fields may include
ok,command,envFile,platform,showSecrets,sections,suggestions, anderror
Validate whether a Maven or Gradle project is ready to publish to Maven Central:
mvn -q -DskipTests compile exec:java -Dexec.args="doctor-publish --directory /path/to/repo --target maven-central"Use JSON output in CI:
mvn -q -DskipTests compile exec:java -Dexec.args="doctor-publish --directory /path/to/repo --format json"For Maven projects, the doctor checks build model, current revision, effective snapshot publish version or release tag, optional module target, clean Git worktree, Maven command availability, required POM metadata, Central publish profiles, source/javadoc/signing plugins, their publish goal bindings, Central publishing plugin extension/configuration, repository URL and credentials, and GPG signing inputs.
For Gradle projects, the doctor checks gradle.properties, effective snapshot publish version or release tag, optional module target, clean Git worktree, settings/build files, detected modules, Gradle command availability, maven-publish or publishing configuration, signing configuration or Gradle signing environment variables, repository URLs and credentials, and the next gradle-publish command.
Important flags:
| Flag | Meaning |
|---|---|
--target |
Publish target. Currently supports maven-central |
--mode |
Publish mode: auto, snapshot, or release |
--tag |
Explicit release tag such as v1.2.3 or module/v1.2.3; implies release mode and is mirrored into next commands |
--module |
Restrict readiness checks and next commands to one Maven artifactId or Gradle project name |
--task |
Gradle publish task name to mirror into the next gradle-publish command |
--allow-dirty |
Skip the clean worktree check and include --allow-dirty true in next commands |
--snapshot-version-mode |
Snapshot version strategy: stamped or plain |
--snapshot-build-stamp |
Explicit snapshot publish stamp; when omitted in stamped mode, doctor generates one and mirrors it in next commands |
--format json |
Emit machine-readable readiness checks |
Render the Maven validation flow before a real publish.
Snapshot example:
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory /path/to/repo --snapshot"Plain snapshot example:
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory /path/to/repo --snapshot --snapshot-version-mode plain"Explicit snapshot build stamp:
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory /path/to/repo --snapshot --snapshot-build-stamp 20260420.154500.ci001"Release example:
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory /path/to/repo --tag v1.2.3"GitLab snapshot branch example with config-driven defaults:
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory $CI_PROJECT_DIR"In plain snapshot mode, preflight prints that it is using plain snapshot mode and keeps the effective publish version at the original pom.xml revision such as 1.2.3-SNAPSHOT.
Render the real Maven publish command:
mvn -q -DskipTests compile exec:java -Dexec.args="publish --directory /path/to/repo --tag v1.2.3"Actually execute it:
mvn -q -DskipTests compile exec:java -Dexec.args="publish --directory /path/to/repo --tag v1.2.3 --execute true"Snapshot publishing resolves the root 1.2.3-SNAPSHOT into a unique publish revision such as 1.2.3-20260420.154500.abc1234-SNAPSHOT, then injects it through -Drevision=. You can override the generated build stamp with --snapshot-build-stamp or the JAVACHANGES_SNAPSHOT_BUILD_STAMP environment variable.
If you pass --snapshot-version-mode plain, publish keeps the effective Maven version at the original snapshot revision such as 1.2.3-SNAPSHOT instead of rewriting it to a stamped value. preflight and publish both print the active snapshot mode so CI logs show whether the run is plain or stamped.
Important Maven repository note:
- plain mode means the project version stays
1.2.3-SNAPSHOT - Maven and Nexus snapshot repositories still usually expand uploaded artifact filenames to timestamped snapshot files
- that timestamped filename expansion is standard Maven snapshot repository behavior, not a second rewrite by
javachanges
GitLab CI defaults:
- if
CI_COMMIT_TAGis present,publishuses it automatically, so a tag job can just runpublish --execute true - if the current branch matches
.changesets/config.jsonor.changesets/config.jsoncsnapshotBranch,publishandpreflightdefault to snapshot mode - if the repository config also sets
"snapshotVersionMode": "plain", the same GitLab snapshot-branch flow automatically uses plain snapshot mode - this removes the need for CI shell wrappers that manually branch on tags vs snapshot branches
Important flags:
| Flag | Meaning |
|---|---|
--snapshot |
Publish the current snapshot instead of a release tag |
--snapshot-version-mode |
Snapshot version strategy: stamped or plain |
--snapshot-build-stamp |
Explicit snapshot publish stamp, overriding the default UTC timestamp + git short sha |
--tag |
Target release tag |
--module |
Restrict to one Maven artifactId or Gradle project name |
--allow-dirty |
Allow a dirty working tree |
--execute true |
Run the final publish command instead of only printing it |
Render the Gradle publish command:
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar gradle-publish --directory /path/to/repo --tag v1.2.3
mvn javachanges:gradle-publish -Djavachanges.directory=/path/to/repo -Djavachanges.tag=v1.2.3Actually execute it:
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar gradle-publish --directory /path/to/repo --tag v1.2.3 --execute trueSnapshot example:
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar gradle-publish --directory /path/to/repo --snapshot trueCustom task example:
java -jar .javachanges/javachanges-__JAVACHANGES_LATEST_RELEASE_VERSION__.jar gradle-publish --directory /path/to/repo --tag v1.2.3 --task publishAllPublicationsToMavenRepositorygradle-publish resolves the same release or snapshot version as publish, then renders ./gradlew --no-daemon publish -Pversion=.... If --module api is provided, it renders ./gradlew --no-daemon :api:publish -Pversion=.... Use --task to replace the final Gradle task name.
Important Gradle repository note:
- this command does not generate Maven
settings.xml - repository URLs and credentials should stay in the Gradle build or CI environment
- pass
--taskwhen the publication task is not namedpublish
| Command | Purpose |
|---|---|
github-release-plan |
Create or update a GitHub release-plan pull request |
github-tag-from-plan |
Create and push the final release tag from a generated release plan |
github-release-publish-state |
Resolve whether a GitHub Release publish job should continue |
github-release-from-plan |
Generate release metadata and optionally create or update the GitHub Release |
init-github-actions |
Write a minimal GitHub Actions workflow that wires release-plan, tag, publish, and GitHub Release jobs |
Examples:
mvn -q -DskipTests compile exec:java -Dexec.args="github-release-plan --directory /path/to/repo --github-repo owner/repo --write-plan-files false --execute true"
mvn javachanges:github-release-plan -Djavachanges.githubRepo=owner/repo -Djavachanges.writePlanFiles=false
mvn -q -DskipTests compile exec:java -Dexec.args="github-tag-from-plan --directory /path/to/repo --fresh true --execute true"
mvn javachanges:github-tag-from-plan -Djavachanges.fresh=true
mvn javachanges:github-release-publish-state -Djavachanges.fresh=true
mvn -q -DskipTests compile exec:java -Dexec.args="github-release-from-plan --directory /path/to/repo --fresh true --release-notes-file target/release-notes.md --execute true"
mvn javachanges:github-release-from-plan -Djavachanges.fresh=true -Djavachanges.releaseNotesFile=target/release-notes.md
mvn -q -DskipTests compile exec:java -Dexec.args="github-release-from-plan --directory /path/to/repo --format json"
mvn javachanges:init-github-actions -Djavachanges.force=true
mvn -q -DskipTests compile exec:java -Dexec.args="init-github-actions --directory /path/to/repo --output .github/workflows/javachanges-release.yml --force true"
mvn -q -DskipTests compile exec:java -Dexec.args="init-github-actions --directory /path/to/gradle-repo --build-tool gradle --output .github/workflows/javachanges-release.yml --force true"The GitHub release-plan, tag, and release commands also support --format json for CI-safe machine-readable output.
| Command | Purpose |
|---|---|
gitlab-release-plan |
Create or update a GitLab release-plan merge request |
gitlab-tag-from-plan |
Create the final release tag from a generated release plan |
gitlab-release |
Generate release notes and create or update the GitLab Release for the current tag |
init-gitlab-ci |
Write a minimal GitLab CI template that wires release-plan, tag, publish, and GitLab Release jobs |
Examples:
mvn -q -DskipTests compile exec:java -Dexec.args="gitlab-release-plan --directory /path/to/repo --project-id 12345 --write-plan-files false --execute true"
mvn javachanges:gitlab-release-plan -Djavachanges.projectId=12345 -Djavachanges.writePlanFiles=false
mvn -q -DskipTests compile exec:java -Dexec.args="gitlab-tag-from-plan --directory /path/to/repo --fresh true --fallback-from-release-commit true --execute true"
mvn javachanges:gitlab-tag-from-plan -Djavachanges.fresh=true -Djavachanges.fallbackFromReleaseCommit=true
mvn -q -DskipTests compile exec:java -Dexec.args="gitlab-release --directory /path/to/repo --ignore-catalog-validation true --execute true"
mvn javachanges:gitlab-release -Djavachanges.ignoreCatalogValidation=true
mvn javachanges:init-gitlab-ci -Djavachanges.force=true
mvn -q -DskipTests compile exec:java -Dexec.args="init-gitlab-ci --directory /path/to/repo --output .gitlab-ci.yml --force true"
mvn -q -DskipTests compile exec:java -Dexec.args="init-gitlab-ci --directory /path/to/gradle-repo --build-tool gradle --output .gitlab-ci.yml --force true"Use --fallback-from-release-commit true when a default-branch pipeline may need to recover the release tag from a merged chore(release): release vX.Y.Z commit. Use --ignore-catalog-validation true only when Maven artifacts are the source of truth and a GitLab Catalog validation error should not fail Release page creation.
You can always ask picocli for built-in help:
mvn -q -DskipTests compile exec:java -Dexec.args="--help"
mvn -q -DskipTests compile exec:java -Dexec.args="plan --help"| Need | Document |
|---|---|
| First-time setup and local workflow | Getting Started |
| Local development workflow | Development Guide |
| Generated manifest files | Release Plan Manifest |
| GitHub Actions integration | GitHub Actions Usage Guide |
| GitLab CI/CD integration | GitLab CI/CD Usage Guide |