BoxLang 🚀 A New JVM Dynamic Language Learn More...
commandbox-release adds namespaced release commands to CommandBox,
which enable you to easily:
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.
Every computer needs:
Your project settings may also require:
runTests is true.Sign in to each service that you use:
gh auth login
box forgebox login
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.
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:
release.json from your answers and the
settings it finds in the project;CHANGELOG.md when the project does not
already have one;ignore list in
box.json. These patterns keep test, server, and editor
files out of the package; and.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.
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
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.
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 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.
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.
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": []
}
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": {
"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.
Use this setting when another system, such as CI, runs the tests:
{
"runTests": false
}
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.
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.
| Setting | Default | What it does |
|---|---|---|
requires
| the version that created the file | The 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. |
| 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.
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:
Replace the module:
box uninstall build-template --system
box install commandbox-release
Delete the copied build/ folder if the project still
has one from version 1.x.
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.
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.
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.
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.
box release publish on your
computer. Run box release bump, commit, and push the
tag instead.This file lists the important changes to this project.
The format follows Keep a Changelog. Version numbers follow Semantic Versioning.
commandbox-release. Install it with box install commandbox-release
and update it with box update commandbox-release --system. Commands still start with
release.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.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.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.box config set endpoints.forgebox.APIToken.release migrate and support for 1.x and 2.x project settings. See "Upgrading from 1.x or
2.x" in the README.excludes and excludesAdd settings. Release commands explain the problem if these
settings remain in release.json.version= argument for publishing. The publish command reads the version from
box.json.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.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.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.minimumKitVersion in build.json. Release commands stop and print the
update command when the installed kit is too old.box update build-template --system to update the kit.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.box install build-template.box release migrate --dryRun in each project. Then run box release migrate, review
the changes, and commit them.templates/github-release.yml.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.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.build/lib/PackageScriptService.cfc. The install and
update tasks now use the same list.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.build/lib/.release:existing-tag. This task publishes a release tag created while finishing a
Gitflow release in a tool such as GitKraken.develop.git-flow, and hotfixes.release:skip-tests as a clear name for the existing option that skips release tests.build/build.json. Module packages
exclude common ColdBox development files. Applications keep possible deployment files such
as modules, .htaccess, and .well-known.server.json and root-level server-*.json files in filename order. It
names each engine from app.cfengine, the server name, or the filename.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.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.excludesAdd adds entries to the default exclusion list. Excluding one more file requires
one new setting.build/templates/.
$
box install commandbox-release