dotCMS / dotCMS/core

Improve dotcms-cli distribution infrastructure for broad package manager availability

Open
#34,725 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dotCMS : CLI Team : Enablement
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

The dotcms-cli is distributed today via NPM (npm install -g @dotcms/dotcli) and a JAR download from Artifactory. Both work, but neither is the natural installation path for the audiences that matter most.

The core problem is a single structural issue: the binary inside each release ZIP is named with its version and platform (dotcms-cli-26.02.16-01-osx-aarch_64) instead of a stable name (dotcms-cli). This prevents every standard package manager — Homebrew, mise, ubi — from consuming the ZIP artifacts already being published to GitHub Releases, making that investment largely wasted.

Additionally:

  • Version management is entirely manual. Developers working across branches with different server versions must manually identify, install, and switch CLI versions via npm. There is no mechanism tying "I checked out this branch" to "I now have the right CLI version."
  • The GitHub Action depends on private infrastructure. The public-facing dotcms-cli GitHub Action — used by customers to automate content sync — resolves the CLI by querying a private Artifactory Maven metadata XML endpoint. If Artifactory is unavailable, every customer's CI/CD fails. It also requires xmllint on the runner and downloads run-java.sh from Maven Central.
  • Homebrew is missing. On macOS, brew install is the default install path for developer CLI tools. Its absence is the most visible distribution gap for the primary developer audience.
  • No Docker image. CI/CD pipelines that prefer containerised tooling have no official image.

Proposed Solution

A targeted set of changes — estimated at ~4.5 engineering days — across packaging, JReleaser configuration, and CI/CD workflows:

1. Fix binary naming (foundation for everything else)

Change assembly.xml so the binary inside each platform ZIP has a stable name (dotcms-cli) instead of the current version-stamped name. The ZIP filename itself stays unchanged (dotcms-cli-{version}-{platform}.zip). This is the universal standard for CLI tools (gh, terraform, kubectl). This single change unblocks all package managers.

The NPM package is updated in parallel to unzip each platform binary into its own subdirectory (bin/osx-aarch_64/dotcms-cli) so it continues to bundle all platforms correctly.

2. Add Homebrew tap via JReleaser

Create dotCMS/homebrew-tap. Add the JReleaser brew packager to jreleaser.yml. On every CLI release, JReleaser generates the formula, calculates checksums from the ZIP assets, and pushes it to the tap automatically.

brew install dotcms/tap/dotcms-cli
3. Pin CLI version in .mise.toml for automatic version management

Add the CLI to .mise.toml with a version that is updated in the same commit as each CLI release:

"ubi:dotCMS/core[exe=dotcms-cli,tag_regex=^dotcms-cli-]" = "26.02.16-01"

This is the highest-value outcome of the whole epic. When a developer checks out any branch, mise automatically installs the correct matching CLI version. No manual npm install. No version lookup. No mismatch between CLI and the server version on that branch. Developers can still override their local version — mise overrides are a first-class feature.

Scenario Today After
Checkout a feature branch Manually find and install matching CLI via npm mise auto-installs correct version
Switch between branches with different server versions Re-run npm install or accept the mismatch mise switches automatically
New developer joins team "Find the right CLI version, install globally via npm" mise install — CLI managed alongside all other tools
CI/CD needs matching CLI Hardcode version or use "latest" (risks mismatch) Read from .mise.toml; always correct
4. Add Docker image (Docker Hub)

Publish dotcms/dotcms-cli:{version} and dotcms/dotcms-cli:latest to Docker Hub using the native Linux binary. Configured via JReleaser docker packager. Enables clean CI/CD usage without runner-level tool installation:

docker run dotcms/dotcms-cli:latest push ./workspace --token=$TOKEN
5. Add JBang catalog

JBang allows running the CLI directly from a JAR URL without installation — including SNAPSHOT builds from Artifactory. This is the recommended path for testing feature branches before a binary release exists, and replaces the fragile run-java.sh approach in the GitHub Action for Java-native environments:

jbang dotcms-cli@dotcms/core push ./workspace
6. Refactor the GitHub Action to use GitHub Releases

Replace the Artifactory XML metadata curl + run-java.sh approach with a direct download of the platform-appropriate native binary from GitHub Releases. Removes the private infrastructure dependency. Adds an optional source-url input for enterprise users who need to override to their own mirror.

Desired Outcome

  • brew install dotcms/tap/dotcms-cli installs and runs correctly on macOS
  • A developer checking out a branch automatically receives the correct matching CLI version via mise — no manual install, no version mismatch
  • docker run dotcms/dotcms-cli:latest executes correctly for CI/CD pipeline usage
  • The GitHub Action resolves the CLI from GitHub Releases, not Artifactory
  • The NPM channel continues to work identically for existing users

Target Personas

  • Developer teams
  • Content teams
  • DevOps teams
  • System administrators (dotCMS)

Scope and Estimates

Work item Estimate
Binary naming fix + NPM package restructure 0.5 day
JReleaser packager configuration (Homebrew, Docker, JBang) 1 day
cicd_release-cli.yml publish jobs + secrets setup 0.5 day
GitHub Action refactor (GitHub Releases + native binary) 1 day
mise .mise.toml entry + version pinning 0.5 day
dotCMS/homebrew-tap repo creation and validation 0.5 day
README updates and smoke testing all channels 0.5 day
Total ~4.5 days

Files to Change

  • tools/dotcms-cli/cli/src/assembly/assembly.xml — stable binary name
  • tools/dotcms-cli/jreleaser.yml — add Homebrew, Docker, JBang packagers
  • tools/dotcms-cli/npm/package.j2 + postinstall.js.seed — platform subdirs
  • tools/dotcms-cli/action/.github/workflows/main.yml + scripts/run-push.sh — GitHub Releases + native binary
  • .github/workflows/cicd_release-cli.yml — publish jobs for each packager
  • .mise.toml — add ubi entry with pinned CLI version
  • tools/dotcms-cli/README.md — updated installation instructions

New Repos Required

  • dotCMS/homebrew-tap — lightweight; JReleaser maintains the formula automatically after initial setup

Links

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the listed files under tools/dotcms-cli, especially assembly.xml, jreleaser.yml, the npm templates, the action workflow and scripts/run-push.sh; then review .github/workflows/cicd_release-cli.yml and .mise.toml. Trace the existing release assets and GitHub Action resolution before changing packaging or publishing configuration. Done means the requested package-manager channels, version pinning, native release downloads, and existing NPM behavior are validated through the README’s installation and smoke-test scenarios.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, github-actions, java, shell
Domain
build-system, ci-cd, cli, devops, release
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.