BoxLang 🚀 A New JVM Dynamic Language Learn More...

commandbox-release

v3.0.0 CommandBox Modules

commandbox-release

commandbox-release logo

commandbox-release adds namespaced release commands to CommandBox, which enable you to easily:

  • Update/bump project version
  • Automatically populate a changelog with release date and version number
  • Run TestBox tests
  • Build and check a release zip file and
  • Publish a package to Github and/or Forgebox.

It supports both modules and web apps. Forgebox storage is optional. Each project stores its release settings in a release.json, in your project root.

Before you install

Every computer needs:

Your project settings may also require:

  • GitHub CLI to create GitHub Releases;
  • a ForgeBox account to publish to ForgeBox; and
  • a running test server when runTests is true.

Sign in to each service that you use:

gh auth login
box forgebox login

Install

box install commandbox-release

Update it later with:

box update commandbox-release --system

A project can set requires in release.json to choose the oldest module version it supports. If your installed version is too old, release commands stop and show how to update it.

Set up a project

Go to the project's root folder and run:

box release init

The command asks where to publish the project and whether to run tests before each release. Then it:

  • creates release.json from your answers and the settings it finds in the project;
  • creates CHANGELOG.md when the project does not already have one;
  • adds patterns to the ignore list in box.json. These patterns keep test, server, and editor files out of the package; and
  • adds its .tmp/ and .artifacts/ folders to .gitignore.

ForgeBox publishing is on by default when the project is a module. That means the box.json type is a module type, such as modules or commandbox-modules, or the project root has ModuleConfig.cfc. Other projects, such as web apps, publish only to GitHub by default. You can change publish.forgebox in release.json at any time.

Use --yes to accept the default answers. Use --docs to copy RELEASE.md into your project. Use --ci to copy a GitHub Actions workflow to .github/workflows/release.yml. You can run setup again. It keeps existing files unless you use --force.

If the folder has no box.json yet, the command offers to create one.

Release and Publish a Module or Web App

box release init                       # answer the setup questions
# Add notes under [Unreleased] in CHANGELOG.md.
box release publish patch --dryRun     # build the zip without changing the version
box release publish patch              # change the version and publish the release

Three ways to release

Change the version and publish in one command

box release publish patch              # 1.0.0 -> 1.0.1 for a bug fix
box release publish minor              # 1.0.0 -> 1.1.0 for a new feature
box release publish major              # 1.0.0 -> 2.0.0 for a breaking change
box release publish minor beta         # 1.0.0 -> 1.1.0-beta.1 to start a prerelease

Run these commands on your production branch, such as main. The command first checks Git, the changelog, and your service sign-ins. Then it updates the branch from origin, changes the version, and moves the [Unreleased] notes into a dated section. It commits the changes as Release 1.0.1, runs the tests, and builds and checks the zip. It publishes only after those steps pass. Finally, it creates and pushes the tag and creates the GitHub Release.

If a step fails after the commit, fix the reported problem. The version change is already committed on your computer. Run box release publish without a level to continue.

Change the version and publish in separate steps

box release bump patch                 # change the version and date the release notes
git add box.json CHANGELOG.md
git commit -m "Release 1.0.1"
box release check                      # optional
box release publish --dryRun           # optional practice
box release publish                    # test, build, and publish the current version

box release publish without a level uses the version already in box.json. It does not change that version.

Gitflow and GitKraken

Gitflow is a way to manage release branches and tags. GitKraken can finish a Gitflow release and create its version tag. Change the version on the release branch, then publish it from the production branch:

start a release in GitKraken           # develop -> release/1.0.1
(add notes under [Unreleased])
box release bump patch                 # works on any branch; no commit
commit "Release 1.0.1" in GitKraken
finish the release in GitKraken        # merges into master and develop; creates v1.0.1
check out master in GitKraken
box release publish                    # uses v1.0.1 and pushes the tag if needed

For a hotfix, use a hotfix/* branch in the same way. box release publish patch stops on release/* and hotfix/* branches and shows these steps. The release guide also explains the git-flow command and pull requests.

Commands

Run these commands from any folder inside a project. box release help prints the same list.

Command What it does
box release init Creates the release settings, changelog, and package ignore list.
box release publish Publishes the version in box.json. Uses an existing tag if it points to the current commit.
box release publish patch Changes the version, commits the change, and publishes. You can also use minor, major, or a prerelease level.
box release publish --dryRun Builds the zip without committing, publishing, or pushing.
box release publish --skipTests Publishes without running the tests again.
box release bump patch Changes the version and dates the release notes. It does not commit.
box release check Finds problems that would stop a release.
box release test Runs the tests once, or on each engine listed in release.json.
box release package Builds and checks the zip file without publishing.
box release notes Shows the release notes for the current version.
box release resume Finishes a release that stopped after publishing.

Run box help release publish to see all help for one command.

Settings

The setup command creates release.json in the project root. Edit that file to change how release commands work.

{
    "requires": "3.0.0",
    "branch": "main",
    "changelog": "CHANGELOG.md",
    "testRunner": "http://127.0.0.1:60299/tests/runner.cfm",
    "runTests": true,
    "publish": {
        "forgebox": true,
        "github": true
    },
    "engines": []
}

Choose the production branch

Set branch to the production branch, usually main or master. This branch holds published versions and their tags. In a Gitflow project, do not set it to develop or a temporary release/* branch. Setup uses Gitflow's production branch when it finds one. Check the value in the new file before your first release.

Publish to GitHub but not ForgeBox

{
    "publish": {
        "forgebox": false,
        "github": true
    }
}

If release.json does not set publish.forgebox, a module publishes to ForgeBox and any other project does not. Set the value yourself to override that default.

Do not run tests during the build

Use this setting when another system, such as CI, runs the tests:

{
    "runTests": false
}

Keep files out of the package

The package includes project files unless a pattern in the box.json ignore list leaves them out. A pattern is a rule that matches file paths. ForgeBox uses the same list. This keeps the GitHub zip and the ForgeBox package in sync. Setup adds common patterns, and you can edit the list at any time.

{
    "ignore": [
        "**/.*",
        "/tests/",
        "/test-harness/",
        "/server*.json",
        "**/*.bak"
    ]
}

Here is how the patterns match paths:

  • /tests/ starts with a slash, so it matches only the tests folder in the project root.
  • temp/ has no leading slash, so it matches a folder named temp at every depth.
  • **/*.bak matches every .bak file at every depth.
  • !/.htaccess keeps a file that an earlier pattern removed. Web apps use this to ship .htaccess and .well-known/ while **/.* removes the other hidden files.

The package also leaves out .git, .gitignore, release.json, .tmp, and .artifacts. The build does not use .gitignore to choose package files. For example, .gitignore may exclude a modules/ folder that the running project needs. The build stops if the box.json ignore list excludes box.json, or ModuleConfig.cfc when the project has one.

Test more than one CFML engine

During setup, the command finds server.json and server-*.json files in the project root. It adds each one to engines in filename order. Remove servers you do not want to test.

{
    "engines": [
        { "name": "Lucee 5", "configFile": "[email protected]" },
        { "name": "Adobe 2023", "configFile": "[email protected]" }
    ]
}

box release test starts each engine, runs the tests, and stops the engine before starting the next one. It tries every engine even if one fails. It reports an error at the end if any engine failed.

Other settings

Setting Default What it does
requires the version that created the fileThe oldest commandbox-release version this project can use.
tagPrefix v The text before the version in tag names.
gitSync true Gets new commits from origin before a release, without making a merge commit.
requireCleanTree true Stops a release when there are uncommitted changes.
stagingDir .tmp The temporary build folder.
artifactsDir .artifacts Where the zip and checksum files are written.
coldboxMapping test-harness/coldbox The folder used for the coldbox mapping during the build, if the folder exists.
warmup { "attempts": 60, "delaySeconds": 5 } How often release test checks whether each engine is ready.

Common problems

Message How to fix it
Command "release" cannot be resolved Install the module in this CommandBox with box install commandbox-release.
No box.json file was found Run the command from inside a CommandBox project, or run box release init to create one.
This project requires commandbox-release X or newer Run box update commandbox-release --system.
This project has build.json from build-template 1.x or 2.x See Upgrading from 1.x or 2.x.
You have uncommitted changes Commit or stash the changes, and then run the command again.
You are on a Gitflow release branch Run box release bump patch on that branch, commit the changes, finish the release, then publish from master.
The test server ... did not answer Start the project's test server. You can also correct testRunner or set runTests to false when tests run somewhere else.
Could not find the GitHub CLI Install gh, open a new terminal, and run gh auth login.
The "## [Unreleased]" section ... is empty Add notes under [Unreleased], and then run the command again.
The package is missing box.json or ModuleConfig.cfc Remove the box.json ignore pattern that excludes the required file.
Tag v1.2.3 already exists on origin That version was already released. Change the version before trying again.
Tag v1.2.3 points to a different commit on origin The local and remote tags point to different commits. Do not move the published tag. Check the release history or use a new version.
Version X is committed locally and nothing was published Fix the problem in the message. Then run box release publish without a level.
release.json contains invalid JSON Check for missing quotes, extra commas, or backslashes that must be doubled.

Run box release check when you do not know what is wrong. It reports release problems without changing the project.

Upgrading from 1.x or 2.x

Version 3.0 renamed build-template to commandbox-release. It reads release.json instead of build.json. The old settings are not converted for you. Update each project as follows:

  1. Replace the module:

    box uninstall build-template --system
    box install commandbox-release
    
  2. Delete the copied build/ folder if the project still has one from version 1.x.

  3. Delete build.json or build/build.json. Run box release init. Copy custom values such as branch, engines, and tagPrefix into the new release.json. Rename minimumKitVersion to requires.

  4. Move custom excludes and excludesAdd rules to the ignore list in box.json. Write them as file patterns. A leading / matches only the project root. Without it, the pattern matches at any folder depth. Setup already adds common patterns.

  5. Update scripts and CI steps: release run is now release publish, release run --existingTag is now just release publish, release engines is now release test, and release github is now release resume. release migrate is gone.

Develop commandbox-release

Install the development dependencies and run the tests:

box install
box run-script test

The test runner loads this working copy as the commandbox-release module. It uses a separate CommandBox installation, so a globally installed version does not affect the tests. Unit tests check version rules, changelogs, settings, project lookup, and ignore patterns. Integration tests create temporary projects in .test-work/. They run real commands through tests/support/Invoke.cfc and use a local Git remote. They do not publish to ForgeBox or GitHub.

To test the working copy as an installed module, run box install <path to this checkout>. Then open a new shell. box release help should list the commands. The module uses its own box release publish command to release itself.

Files in commands/release/ receive command arguments. Files in models/ do the release work. Rules that do not need CommandBox have their own model components.

More information

Changelog

This file lists the important changes to this project.

The format follows Keep a Changelog. Version numbers follow Semantic Versioning.

[Unreleased]

Changed

  • The module is named commandbox-release. Install it with box install commandbox-release and update it with box update commandbox-release --system. Commands still start with release.
  • Project settings are now in release.json instead of build.json. The minimumKitVersion setting is now called requires.
  • box release publish replaces release run. With no level, it publishes the version in box.json. With a level, such as patch, it changes the version, dates the release notes, commits the changes, and publishes.
  • box release publish uses an existing version tag if it points to the current commit. You no longer need --existingTag for tags made by Gitflow or GitKraken.
  • box release publish <level> stops on Gitflow release/* and hotfix/* branches. It shows the steps to finish the release from those branches.
  • box release init asks where to publish the project and whether to run tests. ForgeBox publishing is on by default when box.json or ModuleConfig.cfc shows that the project is a module. Use --yes to accept the default answers. If box.json is missing, setup offers to create it.
  • Packages now use the box.json ignore list to leave files out. ForgeBox uses the same list, so its package and the GitHub zip contain the same files. box release init adds common ignore patterns.
  • The build stops if an ignore pattern leaves out box.json, or ModuleConfig.cfc when the project has one.
  • box release test replaces release engines. It runs tests once if no engines are listed.
  • box release resume replaces release github.
  • box release bump now shows the steps to commit the change and run box release publish.
  • box release publish stops when git pull brings in new commits. Run it again to check the updated project.
  • stagingDir and artifactsDir must be folders inside the project. The build deletes these folders before each run.

Fixed

  • The GitHub Actions template now signs in to ForgeBox with box config set endpoints.forgebox.APIToken.

Removed

  • release migrate and support for 1.x and 2.x project settings. See "Upgrading from 1.x or 2.x" in the README.
  • The excludes and excludesAdd settings. Release commands explain the problem if these settings remain in release.json.
  • The version= argument for publishing. The publish command reads the version from box.json.

[2.0.1] - 2026-09-13

  • Cleaned up README and code documentation.

[2.0.0] - 2026-09-13

Changed

  • build-template is now a CommandBox module. Install it once on each computer with box install build-template. You no longer need to copy a build folder into each project.
  • Build tasks are now commands in the release namespace. The commands are box release run, release check, release bump <level>, release package, release engines, release init, release notes, release github, and release migrate. Run box release help to list them.
  • Project settings now use build.json in the project root. The kit can still read the old 1.x file at build/build.json. It prints a notice until release migrate moves the file.
  • A project can set minimumKitVersion in build.json. Release commands stop and print the update command when the installed kit is too old.
  • Release commands now find the project from any folder inside it.
  • Use box update build-template --system to update the kit.

Removed

  • Projects no longer need the copied build folder, Update.cfc, build-kit.json, templateVersion, or scripts added to box.json by the installer.
  • release init no longer adds scripts to box.json. release migrate updates old 1.x scripts to use the new commands. Existing box run-script release calls continue to work.

Migration from 1.x

  1. Run box install build-template.
  2. Run box release migrate --dryRun in each project. Then run box release migrate, review the changes, and commit them.
  3. Install the module before the release step in CI. See templates/github-release.yml.

[1.5.0] - 2026-09-13

Added

  • build-kit:update (build/Update.cfc) updates the kit files copied into a project. It can download the latest build-template release or use :source=<folder or zip>. It replaces kit files under build/ but keeps build/build.json. It adds new box.json scripts, records the kit version, and prints changelog entries added since the previous version. Use :version= to choose a release. Use :dryRun=true to list changes without applying them.
  • build/build-kit.json records the kit version and repository. The installer now writes the real kit version to templateVersion instead of always writing 1.0.0.
  • release:check now reports whether the release tag exists on origin.

Changed

  • release:existing-tag now checks origin before publishing. It pushes a local-only tag right before creating the GitHub Release. It stops when origin has the same tag at another commit. Before this change, an unpushed Gitflow tag caused the last release step to fail after the package was already published to ForgeBox.
  • The box.json script list moved to build/lib/PackageScriptService.cfc. The install and update tasks now use the same list.

[1.4.2] - 2028-08-10

Changed

  • bump:beta, bump:alpha, and direct preminor calls now stop before changing an active prerelease to a new target. Use :allowPrereleaseRetarget=true to allow that change.

[1.4.1] - 2028-08-07

  • Updated the logo.

[1.4.0] - 2028-08-07

Added

  • Added TestBox tests for version rules, changelog parsing, project settings, public task APIs, multiple-engine workflows, installation, package builds, and safe release practice runs.

Changed

  • Build task components now use direct names and smaller workflow functions.
  • Developer documentation now uses plain language for people who are new to the project.
  • Version, changelog, and project detection rules now use small internal services under build/lib/.
  • The multiple-engine guide now explains that all configured engines run before the command reports any failures.

[1.3.0] - 2028-08-03

Added

  • Added release:existing-tag. This task publishes a release tag created while finishing a Gitflow release in a tool such as GitKraken.

Changed

  • The Gitflow guide now gives the branch steps in order. Create the release branch first. Change the version and commit on that branch. Then finish the release into production and develop.
  • Git instructions now include the matching review, stage, commit, and push steps for people who use GitKraken or another Git app.
  • The guide now has separate GitKraken instructions for valid, old, and already published tags.

[1.2.0] - 2026-07-31

Added

  • Added a Gitflow release guide for plain Git, pull requests, git-flow, and hotfixes.
  • Added a mode that publishes tags created by Gitflow or tag-based CI jobs.
  • Added release:skip-tests as a clear name for the existing option that skips release tests.

Changed

  • A release practice run can run from a non-production branch and prints a warning. A real release must still run from the configured production branch.
  • Release updates now allow fast-forward changes only. Normal releases now reject tags that already exist locally or on the remote.
  • Setup now uses Gitflow's production branch when it is configured. Git instructions now list separate review, stage, and commit steps for developers who are new to Git.
  • The optional GitHub Actions workflow can publish an existing tag. It requests only the repository content permission needed to create the release.

[1.1.0] - 2026-07-30

Added

  • New projects now get a complete exclusion list in build/build.json. Module packages exclude common ColdBox development files. Applications keep possible deployment files such as modules, .htaccess, and .well-known.
  • Setup now finds server.json and root-level server-*.json files in filename order. It names each engine from app.cfengine, the server name, or the filename.

Changed

  • The included build.json is now marked as a starter file that setup can replace. Setup does not replace an existing unmarked or invalid file unless you use :force=true.

[1.0.0] - 2026-07-29

Added

  • Added the first build kit tasks: Build, Release, Bump, TestEngines, Install, and Doctor. They share one settings file at build/build.json.
  • box run-script release checks the project, updates it from the remote, runs tests, builds the package, publishes to ForgeBox, creates a Git tag, and creates a GitHub Release. It uses the changelog notes and attaches the zip file.
  • release:check reports whether a project is ready to release. It prints a fix for each problem.
  • release:dryrun runs a release practice run without publishing.
  • release:hotfix and :skipTests=true skip the tests and print a warning.
  • test:engines runs the tests on each engine in order. It stops at the first failure and lists the engines that passed before the failure.
  • bump:major, bump:minor, and bump:patch change the version and move [Unreleased] notes into a dated section. Prereleases follow SemVer. For example, bump:patch changes 1.2.0-beta.3 to 1.2.0, not 1.2.1.
  • bump:beta, bump:alpha, and bump:prerelease start or update prereleases. Use :preid for another prerelease label.
  • Install.cfc sets up a project in one command. It reads the test runner from box.json and creates the engine list from root-level server-*.json files.
  • The build checks packages before publishing. It compares the number of staged files with the number of files in the zip and stops when the numbers differ.
  • Packages include the short Git commit hash for the source used to build them.
  • excludesAdd adds entries to the default exclusion list. Excluding one more file requires one new setting.
  • Added an optional GitHub Actions workflow under build/templates/.

$ box install commandbox-release

No collaborators yet.
     
  • {{ getFullDate("2026-09-13T10:19:29Z") }}
  • {{ getFullDate("2026-09-22T18:37:35Z") }}
  • 96
  • 7