Skip to content

javachanges CLI Reference

1. Overview

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

2. Invocation Pattern

Current main branch Maven plugin invocation after local snapshot install:

bash
mvn -q -DskipTests install
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:next
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:modules
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:status
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:plan -Djavachanges.apply=true
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:add -Djavachanges.summary="add release notes command" -Djavachanges.release=minor
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:version
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:preflight -Djavachanges.tag=v1.2.3
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:publish -Djavachanges.tag=v1.2.3
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:manifest-field -Djavachanges.field=releaseVersion -Djavachanges.fresh=true
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:release-notes -Djavachanges.tag=v1.2.3 -Djavachanges.output=target/release-notes.md

Source-driven invocation while developing this repository:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="status --directory /path/to/repo"

Common parts:

PartMeaning
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:setupRun first-time setup with safe defaults
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:init -Djavachanges.config=trueInitialize .changesets/ files and print starter commands
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:nextAsk javachanges which release workflow command to run next
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:modulesList detected build metadata and module names
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:statusRun the dedicated Maven plugin status goal
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:validateRun local release-readiness checks
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:plan -Djavachanges.apply=trueRun the dedicated plan goal
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:init-envInitialize the local release env file
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:auth-help -Djavachanges.platform=githubShow required authentication variables
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:doctor-local -Djavachanges.envFile=env/release.env.localCheck local release prerequisites
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:sync-vars -Djavachanges.envFile=env/release.env.local -Djavachanges.platform=githubPreview platform variable sync
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:github-release-plan -Djavachanges.githubRepo=owner/repoCreate or update the GitHub release-plan pull request
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:github-release-from-plan -Djavachanges.fresh=trueGenerate release notes and sync the GitHub Release
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:gitlab-release-plan -Djavachanges.projectId=12345Create or update the GitLab release-plan merge request
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:gitlab-release -Djavachanges.tag=v1.2.3Generate release notes and sync the GitLab Release
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:release-version-from-tag -Djavachanges.tag=core/v1.2.3Extract a release version from a tag
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:module-selector-args -Djavachanges.module=corePrint build-tool selector args
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:gradle-publish -Djavachanges.directory=/path/to/gradle-repo -Djavachanges.tag=v1.2.3Render or execute the Gradle publish command from a Maven runner project
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:init-github-actions -Djavachanges.force=trueGenerate the GitHub Actions release workflow
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:init-gitlab-ci -Djavachanges.force=trueGenerate the GitLab CI release template
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:publish -Djavachanges.tag=v1.2.3Run the dedicated Maven publish dry-run goal
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:ensure-gpg-public-keyPublish and verify the signing public key
mvn io.github.sonofmagic:javachanges:1.12.2-SNAPSHOT:run -Djavachanges.args="..."Use the generic bridge goal for commands without a dedicated goal
mvn -q -DskipTests compile exec:javaBuild the CLI and run the Java entrypoint
-Dexec.args="..."Pass javachanges CLI arguments
--directory /path/to/repoTarget Maven or Gradle repository root, or a subdirectory inside it

Plugin note:

  • all dedicated goals and javachanges:run inject --directory ${project.basedir} automatically unless you already passed --directory explicitly
  • output language defaults to English; pass --language zh-CN, set JAVACHANGES_LANGUAGE=zh-CN, or use -Djavachanges.language=zh-CN with 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:
bash
mvn -B io.github.sonofmagic:javachanges:1.12.2:run -Djavachanges.args="gitlab-release-plan --directory $CI_PROJECT_DIR --write-plan-files false --execute true"

Language examples:

bash
javachanges status --directory . --language zh-CN
JAVACHANGES_LANGUAGE=zh-CN javachanges plan --directory . --apply true
mvn javachanges:status -Djavachanges.language=zh-CN

If you declare the plugin in a target repository pom.xml, the shortest local form becomes:

bash
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.md

Gradle repositories should use the CLI jar form:

bash
mvn -q dependency:copy -Dartifact=io.github.sonofmagic:javachanges:1.12.2 -DoutputDirectory=.javachanges
java -jar .javachanges/javachanges-1.12.2.jar status --directory /path/to/gradle-repo
java -jar .javachanges/javachanges-1.12.2.jar plan --directory /path/to/gradle-repo --apply true

Gradle 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.

3. Safely Wrapping javachanges Through Maven

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:

make
MVNW := ./mvnw
JAVACHANGES_MVN := $(MVNW) -q -DskipTests compile exec:java

jc-version:
	$(JAVACHANGES_MVN) -Dexec.args="version --directory $(CURDIR)"

Recommended parameterized Makefile pattern:

make
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:

yaml
script:
  - >
    ./mvnw -q -DskipTests compile exec:java
    -Dexec.args="version --directory $CI_PROJECT_DIR"

Not recommended:

make
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

4. High-Value Commands

CommandPurposeWrites files
setupRun 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
initInitialize .changesets/README.md with starter examples, optionally .changesets/config.jsonc, and print starter commands.changesets/README.md, optional .changesets/config.jsonc
init-gradle-tasksGenerate a Gradle script plugin that registers javachanges tasksgradle/javachanges.gradle, optional build.gradle(.kts) with --apply true
addCreate a changeset.changesets/*.md
nextSuggest the next release workflow command, including local, GitHub, and GitLab pathsNo
modulesList detected build metadata and module namesNo
statusShow the current release planNo
validateCheck local release readiness, including build metadata, changesets, config, git state, and planned tagsNo
planRender the current release planNo
plan --apply trueApply the plan and consume changesetspom.xml or gradle.properties, CHANGELOG.md, .changesets/release-plan.json, .changesets/release-plan.md, .changesets/release-plan-backup.json
manifest-fieldRead a field from the generated release manifest, or use --fresh true to derive it from the current repository stateNo
release-notesGenerate release notes for a tagtarget file
ensure-gpg-public-keyPublish and verify the current signing public key on supported keyserversNo
preflightRender publish validation commandsNo
publishRender or execute the Maven publish commandNo
gradle-publishRender or execute the Gradle publish commandNo

5. Changeset Commands

5.1 setup

Run first-time setup with safe defaults:

bash
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.

5.2 init

Initialize the changeset directory for a repository and print the next commands to run.

Examples:

bash
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.

5.2.1 init-gradle-tasks

Generate a Gradle script plugin that registers javachanges tasks for a Gradle repository.

Examples:

bash
java -jar .javachanges/javachanges-1.12.2.jar init-gradle-tasks --directory /path/to/gradle-repo
java -jar .javachanges/javachanges-1.12.2.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=true

The 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".

5.3 add

Create a new changeset file.

Example:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="add --directory /path/to/repo --summary 'add release notes command' --release minor --modules core"

Behavior:

InputMeaning
--summaryFirst line of the generated markdown body
--releasepatch, minor, or major
--modulesComma-separated Maven artifactIds, Gradle project names, or all
--bodyOptional extra markdown content after the summary
--formattext or json
--no-interactiveFail 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
```md
---
"core": minor
---

add release notes command
```

Compatibility note:

  • add still accepts legacy flag names such as --release and --modules
  • the generated file itself uses the official Changesets-style package map

5.4 status

Show the current pending release plan.

Example:

bash
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

5.5 plan

Render the release plan without writing files:

bash
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:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="plan --directory /path/to/repo --apply true"

When --apply true is used, javachanges:

  1. updates the root Maven <revision> or Gradle gradle.properties version
  2. prepends a new section to CHANGELOG.md
  3. writes .changesets/release-plan.json
  4. writes .changesets/release-plan.md
  5. writes .changesets/release-plan-backup.json before modifying files
  6. 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:

bash
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.

5.6 manifest-field

Read a field from the generated release manifest, or derive it from the current repository state.

Example:

bash
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:

FieldMeaning
releaseVersionRelease version without the leading v
nextSnapshotVersionNext root snapshot version
releaseLevelAggregated 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.

6. Repository And Version Commands

CommandPurposeExample
versionPrint the current root revisionversion --directory /path/to/repo --format json
modulesList detected Maven artifactIds or Gradle project namesmodules --directory /path/to/repo --format json
release-version-from-tagExtract 1.2.3 from v1.2.3 or core/v1.2.3release-version-from-tag --tag v1.2.3 --format json
release-module-from-tagExtract the package/module name from core/v1.2.3release-module-from-tag --tag core/v1.2.3 --format json
assert-moduleValidate a Maven artifactId or Gradle project name existsassert-module --directory /path/to/repo --module core
assert-snapshotEnsure the current revision is a snapshotassert-snapshot --directory /path/to/repo
assert-release-tagEnsure a tag matches the current repository versionassert-release-tag --directory /path/to/repo --tag v1.2.3
module-selector-argsPrint build-tool selector argsmodule-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.

7. Environment And Settings Commands

CommandPurpose
write-settingsGenerate a Maven settings.xml file
init-envInitialize a local release env file from the example template
auth-helpPrint platform auth requirements
render-varsPreview GitHub/GitLab variables and secrets, or emit JSON with --format json
doctor-localCheck local release prerequisites, or emit JSON with --format json
doctor-platformCheck remote platform readiness, or emit JSON with --format json
sync-varsSync variables to GitHub or GitLab
audit-varsCompare local env values with remote platform state, or emit JSON with --format json
ensure-gpg-public-keyUpload 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:

bash
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:

bash
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:

CommandNotes
addIncludes created changeset path, release level, affected packages, and next commands
versionIncludes build tool, version file, current revision, release version, and snapshot flag
modulesIncludes build tool, version file, current revision, module list, and add commands
release-version-from-tagIncludes tag, release version, and release module
release-module-from-tagIncludes tag, release version, and release module
statusIncludes the current release-plan status and review commands
nextIncludes pending release metadata and recommended next commands
planIncludes dry-run/apply/restore metadata and next commands
validateIncludes release-readiness check results and issues
render-varsIncludes platform and showSecrets in the payload
doctor-localIncludes section summaries, suggestions, and final error text on failure
doctor-platformIncludes platform and section summaries for env and CLI checks
audit-varsIncludes platform, audit sections, and final error text on failure
doctor-publishIncludes publish target, mode, tag, build tool, module, Gradle task, current revision, publish version, snapshot mode fields, readiness checks, repair suggestions, and next commands
preflightIncludes publish action metadata plus snapshot mode fields such as snapshotVersionMode, effectiveVersion, and snapshotBuildStampApplied
publishIncludes publish action metadata such as tag, module, release version, and release notes file
gradle-publishIncludes Gradle publish action metadata such as tag, module, release version, and snapshot mode
github-release-planIncludes action, skip reason, and release version
github-tag-from-planIncludes action, skip reason, release version, and tag
github-release-from-planIncludes action, tag, release version, and release notes file
gitlab-release-planIncludes action, skip reason, release version, and project id
gitlab-tag-from-planIncludes action, skip reason, release version, module, and tag
gitlab-releaseIncludes action, project id, tag, module, release version, and release notes file

Common flags for these commands:

FlagUsed byMeaning
--env-fileall fourinput env file path
--platformrender-vars, doctor-platform, audit-varsgithub, gitlab, or all
--show-secretsrender-varsreveal secret values instead of masking them
--github-repodoctor-local, doctor-platform, audit-varsoptional GitHub owner/repo identifier
--gitlab-repodoctor-local, doctor-platform, audit-varsoptional GitLab group/project identifier
--format jsonall fourswitch stdout from human text to machine-readable JSON

7.1 ensure-gpg-public-key

Use this command in CI after GPG import and before a Maven Central publish:

bash
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.com and hkps://keys.openpgp.org
  • retries until at least one supported keyserver can fetch the key

Useful flags:

FlagMeaning
--primary-keyserverOverride the first keyserver URL
--secondary-keyserverOverride the fallback keyserver URL
--attemptsMaximum discovery attempts before failure
--retry-delay-secondsDelay between discovery attempts

JSON mode contract:

  • stdout contains only one JSON object
  • exit code 0 means success, non-zero means validation failure or execution error
  • top-level fields may include ok, command, envFile, platform, showSecrets, sections, suggestions, and error

8. Publish Commands

8.1 doctor-publish

Validate whether a Maven or Gradle project is ready to publish to Maven Central:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="doctor-publish --directory /path/to/repo --target maven-central"

Use JSON output in CI:

bash
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:

FlagMeaning
--targetPublish target. Currently supports maven-central
--modePublish mode: auto, snapshot, or release
--tagExplicit release tag such as v1.2.3 or module/v1.2.3; implies release mode and is mirrored into next commands
--moduleRestrict readiness checks and next commands to one Maven artifactId or Gradle project name
--taskGradle publish task name to mirror into the next gradle-publish command
--allow-dirtySkip the clean worktree check and include --allow-dirty true in next commands
--snapshot-version-modeSnapshot version strategy: stamped or plain
--snapshot-build-stampExplicit snapshot publish stamp; when omitted in stamped mode, doctor generates one and mirrors it in next commands
--format jsonEmit machine-readable readiness checks

8.2 preflight

Render the Maven validation flow before a real publish.

Snapshot example:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory /path/to/repo --snapshot"

Plain snapshot example:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory /path/to/repo --snapshot --snapshot-version-mode plain"

Explicit snapshot build stamp:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="preflight --directory /path/to/repo --snapshot --snapshot-build-stamp 20260420.154500.ci001"

Release example:

bash
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:

bash
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.

8.3 publish

Render the real Maven publish command:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="publish --directory /path/to/repo --tag v1.2.3"

Actually execute it:

bash
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_TAG is present, publish uses it automatically, so a tag job can just run publish --execute true
  • if the current branch matches .changesets/config.json or .changesets/config.jsonc snapshotBranch, publish and preflight default 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:

FlagMeaning
--snapshotPublish the current snapshot instead of a release tag
--snapshot-version-modeSnapshot version strategy: stamped or plain
--snapshot-build-stampExplicit snapshot publish stamp, overriding the default UTC timestamp + git short sha
--tagTarget release tag
--moduleRestrict to one Maven artifactId or Gradle project name
--allow-dirtyAllow a dirty working tree
--execute trueRun the final publish command instead of only printing it

8.4 gradle-publish

Render the Gradle publish command:

bash
java -jar .javachanges/javachanges-1.12.2.jar gradle-publish --directory /path/to/repo --tag v1.2.3
mvn javachanges:gradle-publish -Djavachanges.directory=/path/to/repo -Djavachanges.tag=v1.2.3

Actually execute it:

bash
java -jar .javachanges/javachanges-1.12.2.jar gradle-publish --directory /path/to/repo --tag v1.2.3 --execute true

Snapshot example:

bash
java -jar .javachanges/javachanges-1.12.2.jar gradle-publish --directory /path/to/repo --snapshot true

Custom task example:

bash
java -jar .javachanges/javachanges-1.12.2.jar gradle-publish --directory /path/to/repo --tag v1.2.3 --task publishAllPublicationsToMavenRepository

gradle-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 --task when the publication task is not named publish

9. Platform Release Commands

9.1 GitHub Release Commands

CommandPurpose
github-release-planCreate or update a GitHub release-plan pull request
github-tag-from-planCreate and push the final release tag from a generated release plan
github-release-publish-stateResolve whether a GitHub Release publish job should continue
github-release-from-planGenerate release metadata and optionally create or update the GitHub Release
init-github-actionsWrite a minimal GitHub Actions workflow that wires release-plan, tag, publish, and GitHub Release jobs

Examples:

bash
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.

9.2 GitLab Release Commands

CommandPurpose
gitlab-release-planCreate or update a GitLab release-plan merge request
gitlab-tag-from-planCreate the final release tag from a generated release plan
gitlab-releaseGenerate release notes and create or update the GitLab Release for the current tag
init-gitlab-ciWrite a minimal GitLab CI template that wires release-plan, tag, publish, and GitLab Release jobs

Examples:

bash
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.

10. Help Output

You can always ask picocli for built-in help:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="--help"
mvn -q -DskipTests compile exec:java -Dexec.args="plan --help"
NeedDocument
First-time setup and local workflowGetting Started
Local development workflowDevelopment Guide
Generated manifest filesRelease Plan Manifest
GitHub Actions integrationGitHub Actions Usage Guide
GitLab CI/CD integrationGitLab CI/CD Usage Guide

Released under the Apache-2.0 License.