Skip to content

javachanges GitHub Actions Usage Guide

English | 简体中文

1. Overview

This guide explains how to use javachanges in GitHub Actions for:

  1. regular CI validation
  2. release-plan generation
  3. GitHub Actions variable and secret management
  4. publish preflight and real publishing
  5. Maven dependency caching

The examples in this guide use direct CLI commands such as:

bash
mvn -q -DskipTests compile exec:java -Dexec.args="status --directory $PWD"

Note: this repository currently documents direct javachanges CLI usage. It does not ship a Makefile wrapper in the repository root.

2. What javachanges Can Do In GitHub Actions

Recommended command mapping:

GoalCommand
Check pending release statestatus
Apply a release planplan --apply true
Read releaseVersion from the manifestmanifest-field --field releaseVersion
Generate Maven settings from env varswrite-settings --output .m2/settings.xml
Render required GitHub variables and secretsrender-vars --env-file env/release.env.local --platform github
Check local/platform readinessdoctor-local, doctor-platform
Sync GitHub Actions variables and secretssync-vars --platform github
Audit remote GitHub Actions variables and secretsaudit-vars --platform github
Validate a release publish locally or in CIpreflight
Run the actual Maven deploy commandpublish --execute true
Generate release notesrelease-notes --tag vX.Y.Z --output target/release-notes.md

For a GitHub-based release workflow, keep these files under version control:

PathPurpose
.changesets/*.mdPending release intent
.changesets/release-plan.jsonGenerated release manifest
.changesets/release-plan.mdGenerated release PR body
CHANGELOG.mdGenerated changelog
env/release.env.exampleVariable template for repository publishing
.github/workflows/*.ymlCI and release workflows

4. Local Preparation Before Touching GitHub Actions

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"

Template fields in env/release.env.example:

VariableMeaning
MAVEN_RELEASE_REPOSITORY_URLRelease repository URL
MAVEN_SNAPSHOT_REPOSITORY_URLSnapshot repository URL
MAVEN_RELEASE_REPOSITORY_IDRelease server id used in Maven settings
MAVEN_SNAPSHOT_REPOSITORY_IDSnapshot server id used in Maven settings
MAVEN_REPOSITORY_USERNAMEShared username fallback
MAVEN_REPOSITORY_PASSWORDShared password fallback
MAVEN_RELEASE_REPOSITORY_USERNAMEOptional explicit release username
MAVEN_RELEASE_REPOSITORY_PASSWORDOptional explicit release password
MAVEN_SNAPSHOT_REPOSITORY_USERNAMEOptional explicit snapshot username
MAVEN_SNAPSHOT_REPOSITORY_PASSWORDOptional explicit snapshot password

4.3 Check your local environment

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

4.4 Preview GitHub variables and secrets

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

4.5 Sync GitHub variables and secrets with gh

Dry-run:

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

Apply:

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

Audit:

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

sync-vars writes:

Remote typeNames
GitHub Actions variablesMAVEN_RELEASE_REPOSITORY_URL, MAVEN_SNAPSHOT_REPOSITORY_URL, MAVEN_RELEASE_REPOSITORY_ID, MAVEN_SNAPSHOT_REPOSITORY_ID
GitHub Actions secretsMAVEN_REPOSITORY_USERNAME, MAVEN_REPOSITORY_PASSWORD, MAVEN_RELEASE_REPOSITORY_USERNAME, MAVEN_RELEASE_REPOSITORY_PASSWORD, MAVEN_SNAPSHOT_REPOSITORY_USERNAME, MAVEN_SNAPSHOT_REPOSITORY_PASSWORD

5. GitHub Actions Workflow Patterns

5.1 CI-only validation

Use this when you want pull requests to validate build health and pending release state.

yaml
name: CI

on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - uses: actions/setup-java@v5
        with:
          distribution: corretto
          java-version: '8'
          cache: maven
          cache-dependency-path: pom.xml

      - name: Verify build
        run: mvn -B verify

      - name: Inspect release state
        run: mvn -B -DskipTests compile exec:java -Dexec.args="status --directory $GITHUB_WORKSPACE"

5.2 Release-plan pull request automation

Use this pattern when main should accumulate .changesets/*.md files and produce a reviewed release PR.

yaml
name: Release Plan

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write

jobs:
  release-pr:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - uses: actions/setup-java@v5
        with:
          distribution: corretto
          java-version: '8'
          cache: maven
          cache-dependency-path: pom.xml

      - name: Build CLI
        run: mvn -B -DskipTests compile

      - name: Apply release plan
        run: mvn -B -DskipTests compile exec:java -Dexec.args="plan --directory $GITHUB_WORKSPACE --apply true"

      - name: Read release version
        if: hashFiles('.changesets/release-plan.json') != ''
        id: release_version
        run: |
          value="$(mvn -q -DskipTests compile exec:java -Dexec.args="manifest-field --directory $GITHUB_WORKSPACE --field releaseVersion" | tail -n 1)"
          echo "value=$value" >> "$GITHUB_OUTPUT"

      - name: Commit release plan
        if: hashFiles('.changesets/release-plan.json') != ''
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          RELEASE_VERSION: ${{ steps.release_version.outputs.value }}
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git switch -C changeset-release/main
          git add pom.xml CHANGELOG.md .changesets
          git commit -m "chore(release): apply changesets for v${RELEASE_VERSION}"
          git push --force-with-lease origin HEAD:changeset-release/main
          gh pr create \
            --base main \
            --head changeset-release/main \
            --title "chore(release): v${RELEASE_VERSION}" \
            --body-file .changesets/release-plan.md

5.3 Generic Maven publish with javachanges publish

Use this when the target repository publishes to your own Maven release/snapshot repositories and you want javachanges to:

  1. validate the tag and version state
  2. generate .m2/settings.xml
  3. render the exact Maven deploy command
  4. optionally execute the real deploy
yaml
name: Publish

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: read

jobs:
  publish:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - uses: actions/setup-java@v5
        with:
          distribution: corretto
          java-version: '8'
          cache: maven
          cache-dependency-path: pom.xml

      - name: Build CLI
        run: mvn -B -DskipTests compile

      - name: Preflight
        env:
          MAVEN_RELEASE_REPOSITORY_URL: ${{ vars.MAVEN_RELEASE_REPOSITORY_URL }}
          MAVEN_SNAPSHOT_REPOSITORY_URL: ${{ vars.MAVEN_SNAPSHOT_REPOSITORY_URL }}
          MAVEN_REPOSITORY_USERNAME: ${{ secrets.MAVEN_REPOSITORY_USERNAME }}
          MAVEN_REPOSITORY_PASSWORD: ${{ secrets.MAVEN_REPOSITORY_PASSWORD }}
        run: |
          mvn -B -DskipTests compile exec:java \
            -Dexec.args="preflight --directory $GITHUB_WORKSPACE --tag ${GITHUB_REF_NAME}"

      - name: Publish
        env:
          MAVEN_RELEASE_REPOSITORY_URL: ${{ vars.MAVEN_RELEASE_REPOSITORY_URL }}
          MAVEN_SNAPSHOT_REPOSITORY_URL: ${{ vars.MAVEN_SNAPSHOT_REPOSITORY_URL }}
          MAVEN_REPOSITORY_USERNAME: ${{ secrets.MAVEN_REPOSITORY_USERNAME }}
          MAVEN_REPOSITORY_PASSWORD: ${{ secrets.MAVEN_REPOSITORY_PASSWORD }}
        run: |
          mvn -B -DskipTests compile exec:java \
            -Dexec.args="publish --directory $GITHUB_WORKSPACE --tag ${GITHUB_REF_NAME} --execute true"

Note: this generic publish flow uses the repository URLs and credentials from env/release.env.example.
If you are publishing to Maven Central with a central-publish Maven profile, see Publish To Maven Central and GitHub Actions Release Flow.

6. Maven Cache Behavior In GitHub Actions

The recommended configuration is:

yaml
- uses: actions/setup-java@v5
  with:
    distribution: corretto
    java-version: '8'
    cache: maven
    cache-dependency-path: pom.xml

What this helps with:

Cached wellNot solved by Maven cache
Maven dependencies in ~/.m2/repositorygit checkout and git fetch
Maven plugins and plugin dependenciesJDK download and setup
Repeat builds with the same pom.xml hashGPG key import
Cross-workflow reuse of the same dependency graphSonatype or custom repository publish latency

Important behavior:

SituationResult
First run of a new cache keyDownloads still happen
pom.xml changesA new cache key may need fresh downloads
GitHub-hosted runner starts cleanCache still restores from GitHub storage, not from previous local disk state
You cache target/ instead of Maven repoUsually a bad trade-off for Java library CI

Use this order:

  1. mvn -B verify
  2. javachanges status
  3. javachanges plan --apply true only in the release-plan workflow
  4. javachanges preflight before any real publish
  5. javachanges publish --execute true only in a publish workflow

8. Common Mistakes

ProblemCauseFix
Release PR keeps changing unexpectedlyrelease workflow edits files outside .changesets, pom.xml, or CHANGELOG.mdlimit the release-plan commit scope
Publish job says repository credentials are missingrequired vars or secrets were never syncedrun render-vars, sync-vars, then audit-vars
Maven downloads still appear after enabling cachenew cache key or first runlet one successful run warm the cache
publish fails on a dirty worktreepreflight and publish reject local changes by defaultcommit changes or pass --allow-dirty true only when intended
GitHub workflow examples mention wrappers you do not havecopied examples assume local wrapper scripts or Make targetsuse direct CLI commands from this guide

Use these docs together:

NeedDocument
Full GitHub Actions release PR flow used by this repositoryGitHub Actions Release Flow
Maven Central publishing requirementsPublish To Maven Central
Cross-platform release commandsDevelopment Guide

10. Summary

The practical GitHub Actions path is:

  1. validate with status in CI
  2. generate a reviewed release PR with plan --apply true
  3. manage GitHub variables and secrets with render-vars, sync-vars, and audit-vars
  4. use preflight before any deploy
  5. publish with either the generic publish helper or a Maven Central-specific workflow

11. References

Released under the Apache-2.0 License.