Improve dotcms-cli distribution infrastructure for broad package manager availability
Nobody has claimed this yet.
- 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-cliGitHub 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 requiresxmllinton the runner and downloadsrun-java.shfrom Maven Central. - Homebrew is missing. On macOS,
brew installis 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-cliinstalls 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:latestexecutes 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 nametools/dotcms-cli/jreleaser.yml— add Homebrew, Docker, JBang packagerstools/dotcms-cli/npm/package.j2+postinstall.js.seed— platform subdirstools/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 versiontools/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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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