Skip to content

javachanges GitLab CI/CD Usage Guide

English | 简体中文

1. Overview

This guide explains how to use javachanges in GitLab CI/CD for:

  1. regular validation
  2. GitLab CI/CD variable management
  3. release merge request generation
  4. release tag creation from the generated release plan
  5. Maven publishing in tag pipelines
  6. Maven dependency caching

javachanges has two GitLab-specific commands:

CommandPurpose
gitlab-release-planCreate or update a release branch and release merge request
gitlab-tag-from-planCreate and push the final release tag after the release plan lands

2. What javachanges Can Do In GitLab CI/CD

Recommended command mapping:

GoalCommand
Check pending release statestatus
Apply a release plan locally or in CIplan --apply true
Generate Maven settings from env varswrite-settings
Preview GitLab variables from a local env filerender-vars --platform gitlab
Check platform readinessdoctor-local, doctor-platform
Sync GitLab variables through glabsync-vars --platform gitlab
Audit GitLab variables through glab variable exportaudit-vars --platform gitlab
Create or update a GitLab release MRgitlab-release-plan --execute true
Create and push a release tag after a release plan mergegitlab-tag-from-plan --execute true
Validate a publishpreflight
Run the real Maven deploy commandpublish --execute true

3. Variable Model

3.1 Shared Maven repository variables

javachanges understands these values from env/release.env.example:

VariableRequiredMeaning
MAVEN_RELEASE_REPOSITORY_URLYesRelease repository URL
MAVEN_SNAPSHOT_REPOSITORY_URLYesSnapshot repository URL
MAVEN_RELEASE_REPOSITORY_IDYesRelease repository id
MAVEN_SNAPSHOT_REPOSITORY_IDYesSnapshot repository id
MAVEN_REPOSITORY_USERNAMEYes, unless explicit split credentials are usedShared username
MAVEN_REPOSITORY_PASSWORDYes, unless explicit split credentials are usedShared password
MAVEN_RELEASE_REPOSITORY_USERNAMEOptionalExplicit release username
MAVEN_RELEASE_REPOSITORY_PASSWORDOptionalExplicit release password
MAVEN_SNAPSHOT_REPOSITORY_USERNAMEOptionalExplicit snapshot username
MAVEN_SNAPSHOT_REPOSITORY_PASSWORDOptionalExplicit snapshot password
GITLAB_RELEASE_TOKENOptionalExtra token for GitLab release creation flows outside CI job token fallback

When syncing to GitLab with sync-vars, secret values are written as masked and protected variables.

3.2 Extra variables for GitLab release branch and MR automation

gitlab-release-plan also depends on these runtime values:

VariableSource
CI_PROJECT_IDGitLab built-in CI variable or --project-id
CI_DEFAULT_BRANCHGitLab built-in CI variable
CI_SERVER_HOSTGitLab built-in CI variable
CI_SERVER_URLGitLab built-in CI variable
CI_PROJECT_PATHGitLab built-in CI variable
GITLAB_RELEASE_BOT_USERNAMEProject variable you provide
GITLAB_RELEASE_BOT_TOKENProject variable you provide

gitlab-tag-from-plan additionally needs:

Option or variableMeaning
--before-sha or CI_COMMIT_BEFORE_SHAPrevious commit SHA
--current-sha or CI_COMMIT_SHACurrent commit SHA

4. Local Preparation

4.1 Build the CLI

bash
mvn -q test

4.2 Initialize a local env file

bash
mvn -q -DskipTests compile exec:java -Dexec.args="init-env --target env/release.env.local"

4.3 Preview GitLab variables

bash
mvn -q -DskipTests compile exec:java -Dexec.args="render-vars --env-file env/release.env.local --platform gitlab"

4.4 Check local readiness

bash
mvn -q -DskipTests compile exec:java -Dexec.args="doctor-local --env-file env/release.env.local --gitlab-repo group/project"

4.5 Sync GitLab variables with glab

Dry-run:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="sync-vars --env-file env/release.env.local --platform gitlab --repo group/project"

Apply:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="sync-vars --env-file env/release.env.local --platform gitlab --repo group/project --execute true"

Audit:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="audit-vars --env-file env/release.env.local --platform gitlab --gitlab-repo group/project"

Recommended stages:

  1. verify
  2. release-plan
  3. tag
  4. publish

6. Example .gitlab-ci.yml

yaml
stages:
  - verify
  - release-plan
  - tag
  - publish

default:
  image: maven:3.9.9-eclipse-temurin-8
  cache:
    key:
      files:
        - pom.xml
    paths:
      - .m2/repository

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

verify:
  stage: verify
  script:
    - mvn -B verify
    - mvn -B -DskipTests compile exec:java -Dexec.args="status --directory $CI_PROJECT_DIR"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH

release_plan_mr:
  stage: release-plan
  script:
    - mvn -B -DskipTests compile
    - mvn -B -DskipTests compile exec:java -Dexec.args="gitlab-release-plan --directory $CI_PROJECT_DIR --execute true"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

release_tag:
  stage: tag
  script:
    - mvn -B -DskipTests compile
    - >
      mvn -B -DskipTests compile exec:java
      -Dexec.args="gitlab-tag-from-plan --directory $CI_PROJECT_DIR --before-sha $CI_COMMIT_BEFORE_SHA --current-sha $CI_COMMIT_SHA --execute true"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

publish_release:
  stage: publish
  script:
    - mvn -B -DskipTests compile
    - >
      mvn -B -DskipTests compile exec:java
      -Dexec.args="publish --directory $CI_PROJECT_DIR --tag $CI_COMMIT_TAG --execute true"
  rules:
    - if: $CI_COMMIT_TAG

How the example works:

JobPurpose
verifyValidates the repository and prints release state
release_plan_mrCreates or updates the release branch and merge request
release_tagCreates the final tag after the release plan manifest has changed on the default branch
publish_releasePublishes from the final Git tag

7. How The GitLab-specific Commands Behave

7.1 gitlab-release-plan

Default behavior:

InputDefault
--project-idCI_PROJECT_ID
--target-branchCI_DEFAULT_BRANCH, or main if absent
--release-branchchangeset-release/<target-branch>

Important behavior:

ConditionResult
No pending changesetsSkips the release MR
--execute true missingDry-run only
Release plan produces no staged file changesSkips MR update
Open release MR already existsUpdates it instead of creating a new one

7.2 gitlab-tag-from-plan

Important behavior:

ConditionResult
beforeSha missing or all zerosSkips tagging
.changesets/release-plan.json did not change between commitsSkips tagging
Tag already exists remotelySkips tagging
--execute true missingDry-run only

8. Generic Maven Publish In GitLab CI/CD

The generic publish helper uses:

  1. preflight logic to verify revision, tag, and credentials
  2. write-settings logic to generate .m2/settings.xml
  3. repository variables such as MAVEN_RELEASE_REPOSITORY_URL
  4. credentials from your GitLab CI/CD variables

Typical tag-pipeline split:

yaml
publish_preflight:
  stage: publish
  script:
    - mvn -B -DskipTests compile
    - >
      mvn -B -DskipTests compile exec:java
      -Dexec.args="preflight --directory $CI_PROJECT_DIR --tag $CI_COMMIT_TAG"
  rules:
    - if: $CI_COMMIT_TAG

publish_execute:
  stage: publish
  script:
    - mvn -B -DskipTests compile
    - >
      mvn -B -DskipTests compile exec:java
      -Dexec.args="publish --directory $CI_PROJECT_DIR --tag $CI_COMMIT_TAG --execute true"
  rules:
    - if: $CI_COMMIT_TAG

9. Maven Cache Behavior In GitLab CI/CD

Recommended cache:

yaml
cache:
  key:
    files:
      - pom.xml
  paths:
    - .m2/repository

Recommended runtime option:

yaml
variables:
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

What this improves:

Cached wellNot solved by GitLab cache alone
Maven dependenciesGit clone/fetch cost
Maven pluginsJDK image pull time
Repeat pipelines with the same pom.xmlGitLab API calls for release MR creation
Reuse across jobs on shared cache backendsRemote repository publishing latency

Important behavior:

SituationResult
New cache keyFirst pipeline still downloads
pom.xml changesCache key may change
Different runners without shared cacheCache reuse may be weak
Shared/distributed GitLab cache configuredCross-runner reuse improves

10. Common Mistakes

ProblemCauseFix
Release MR job fails to pushGITLAB_RELEASE_BOT_TOKEN or GITLAB_RELEASE_BOT_USERNAME missingadd the bot credentials as project variables
Release tag job never tagsrelease-plan.json did not change or CI_COMMIT_BEFORE_SHA is unusableinspect the branch pipeline and the generated release plan
sync-vars does nothingenv file still contains placeholdersreplace replace-me values first
audit-vars fails with MISMATCHlocal env and remote project variables divergedresync or deliberately update one side
Publish job fails on missing Maven credentialsproject variables were not configuredsync the variables with glab, then rerun

Use these docs together:

NeedDocument
Generic release commands and local preparationDevelopment Guide
GitHub-based self-release flow in this repositoryGitHub Actions Release Flow
Maven Central-specific publishingPublish To Maven Central

12. Summary

The practical GitLab CI/CD path is:

  1. validate with status
  2. create or update a release MR with gitlab-release-plan
  3. create the final tag with gitlab-tag-from-plan
  4. sync and audit GitLab variables with sync-vars and audit-vars
  5. publish from tags with preflight and publish

13. References

Released under the Apache-2.0 License.