BoxLang 🚀 A New JVM Dynamic Language Learn More...
commandbox-release builds and publishes CFML modules and
web apps. It adds box release commands to CommandBox.
The commands can change your project's version, add a version and
date to its release notes, run TestBox tests, and build a zip file.
They publish to GitHub, ForgeBox, or both. Each project keeps its
settings in release.json in the project's root folder.
Install CommandBox and Git. Run the examples below in your terminal.
Your project needs a Git repository with a remote named
origin. This is the repository that release commands get
commits from and push commits and tags to. For GitHub releases, this
remote must point to the project's GitHub repository. If your remote
has another name, set remote in
release.json. This README says origin for
that remote.
You will choose where to publish and whether to run tests during setup:
gh auth login.box forgebox login.box install commandbox-release
Update it later with:
box update commandbox-release --system
Go to the project's root folder and run:
box release init
Answer the questions about publishing and tests. If the project has
no box.json, setup offers to create it. That file
describes your package and stores its version.
Setup creates release.json and creates
CHANGELOG.md if needed. It also updates two files:
box.json: adds file patterns to the ignore
list to keep development files out of the package..gitignore: adds .tmp/ and
.artifacts/ so Git ignores the generated build files.Open release.json and check these settings before releasing:
branch: your production branch, usually
main or master. This is the branch you
publish stable versions from. In a Gitflow project, use the
production branch rather than develop. To publish alpha
or beta versions from develop too, see Publish prereleases from develop.publish.github and publish.forgebox: where
to publish. Sign in to each service you enable.runTests, testRunner, and
testCommand: whether to run tests, and how.
testRunner is the TestBox runner on a web server. Use a
path, such as /tests/runner.cfm, for the project's
CommandBox server, or a full URL. See Choose the test runner.
testCommand is a CommandBox command, such as
run-script test, that runs the tests without a
server. Use runTests: false when another system already
runs your tests.Modules publish to GitHub and ForgeBox by default. Web apps publish
to GitHub by default. Setup treats a project as a module when
box.json has a module type, such as modules
or commandbox-modules, or the project has
ModuleConfig.cfc in its root folder.
Review the box.json ignore list too. It controls which
files go into the package. The settings
reference below explains the options.
Optional setup flags:
--yes accepts the default answers without asking questions.--docs copies the release guide to
RELEASE.md in your project.--ci copies a GitHub Actions workflow to
.github/workflows/release.yml. That workflow publishes
when you push a version tag. Use it instead of publishing from your computer.You can run setup again. It keeps existing files unless you use --force.
ColdBox app templates add this script to box.json:
"postInstall": "pathExists .env || cp .env.example .env && package set ignore=[]"
CommandBox runs the commands in order, so package set
ignore=[] runs even when .env exists. Each
box install that runs the script empties the ignore
list that setup adds. On a server, the script can also copy
.env.example to .env, with blank values,
next to the real file.
Setup asks whether to remove the script. Answer y to
remove it. Then commit box.json. To create
.env on a new clone, run cp .env.example
.env in box. With --yes, or when nobody can
answer, setup keeps the script and prints a note. Setup only removes
this exact script. When another install script runs package set
ignore, setup and box release check name it, and
you change it by hand.
New versions of commandbox-release may add recommended ignore patterns. These patterns keep files out of the package. To add missing patterns to an existing project, run:
box release init --yes
Setup adds missing patterns to the box.json ignore list.
Setup also adds build folders to .gitignore so Git
ignores the build files. Your existing patterns,
release.json, and changelog stay unchanged. Review the
added patterns, then commit box.json and .gitignore.
box release check and box release publish
list any recommended patterns that are missing. If your package needs
files that a pattern excludes, remove that pattern from
box.json. Missing patterns do not stop a release.
These steps publish directly from your production branch. If your project uses release branches, follow Gitflow releases instead.
Switch to the branch set in release.json. For
example, if branch is main:
git switch main
Add notes under ## [Unreleased] in
CHANGELOG.md. Describe what changed. For example:
## [Unreleased]
### Added
- A search form on the home page.
Commit the setup files and notes before publishing:
git add box.json release.json CHANGELOG.md .gitignore
git commit -m "Set up releases and add release notes"
Commit any other changes you want in this release too. A real release stops if you have uncommitted changes.
Start the test server if your settings require one. Then check the release with a dry run:
box release publish patch --dryRun
This runs enabled tests and builds and checks the zip. It writes
build files to .tmp/ and .artifacts/ by
default. It does not change the version in box.json,
edit your changelog, commit, publish, or push. Read the output and
fix any reported problems.
Publish after the dry run passes:
box release publish patch
patch changes a version such as 1.0.0 to
1.0.1. The command moves your release notes into a
dated section and commits the version and changelog changes. It
runs enabled tests again and builds the package before publishing
to the services you chose.
If you want to keep the version already in box.json for
your first release, use none instead of
patch in both commands. It dates and commits the release
notes without changing the version.
If publishing stops, follow the recovery steps in the output. If the
version change was committed but nothing was published or pushed, fix
the problem and run box release publish without a level.
This uses the current version rather than changing it again.
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 for an early version to test
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. When GitHub
publishing is enabled, it creates a version tag, pushes the branch and
tag, and creates the GitHub Release. A tag marks the commit used for a version.
Use minor beta to start a prerelease: a version for
testing before the normal release. If the command stops, follow its
recovery instructions. Do not repeat a command with a level after its
version change has been committed.
From a prerelease, patch, minor, and
major publish the stable version. For example,
patch changes 1.1.0-beta.2 to
1.1.0. The command asks before it does that. See You meant to
publish the next prerelease.
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 uses develop for completed work, temporary
branches to prepare releases or hotfixes, and a production branch for
published versions. A hotfix is a fix made from production. Set
branch in release.json to the production branch.
On develop, include a version level to create a release
branch and publish its changes:
box release gitflow minor --dryRun # show the steps and build from the current branch
box release gitflow minor # from 1.0.0: create release/1.1.0, merge, and publish
On an existing release branch, use box release gitflow
without a level if the version in box.json is already
newer than production. Otherwise, include a level, such as box
release gitflow minor.
The command:
origin and updates local branches
when gitSync is enabled. If the current branch changes,
it stops so you can run it again to check the updated files.develop.[Unreleased] notes
when a level is used. It commits those files with a message such as
Release 1.1.0.develop and the production branch. When
the changelog is the only file with a merge conflict, the command
combines both versions: it keeps the [Unreleased] notes
on develop and adds the new version section. Notes that
this release published are removed from [Unreleased] on
develop, even when develop added notes of
its own.develop, and
deletes the release branch locally and on origin. Use
--keepBranch to keep the release branch.Nothing is pushed until the build passes. If the command stops before
publishing or creating a tag, follow the reported steps. Fix any code
changes on the release branch and commit them. Then run box
release gitflow on that branch without a level. Git does not
repeat merges that are already complete. If publishing or pushing has
started, use the printed recovery steps.
For a hotfix, create a hotfix/* branch from production
and commit your fix first. Run box release gitflow on
that branch. The command uses the version in box.json if
it is newer than production. Otherwise, it makes a patch version. If
box.json has a prerelease, such as
1.0.0-beta.2, it makes the next prerelease,
1.0.0-beta.3. To finish the prerelease and publish
1.0.0, run box release gitflow patch. It
merges into both develop and production. If a release
branch is also open, use box release gitflow --keepBranch
to keep the hotfix branch. After publishing, merge the hotfix branch
into the release branch yourself. If the hotfix branch was already
deleted, merge the production branch into the release branch to
include the fix.
A Gitflow dry run builds from your current branch. It does not create
or merge branches, change box.json or the changelog,
publish, or push. Its zip does not include the results of the planned merges.
Branch names come from your Gitflow settings in Git config. GitKraken
and git flow store them there. The defaults are
develop, release/, and hotfix/.
The production branch comes from release.json and must
match your Gitflow settings when those settings specify it.
You can use your Git GUI to merge the release branch and create its
version tag. In this example, production is master, and
the current version is 1.0.0:
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 master and the tag if needed
box release publish does not push develop.
Push it from your Git GUI.
For a hotfix, use a hotfix/* branch in the same way.
box release publish patch stops on
release/* and hotfix/* branches and shows
both release options. The release
guide also explains the git-flow command and pull requests.
If you finish the branch before you change the version,
master gets a tag such as v1.0.1, but
box.json still has 1.0.0. Run box
release publish on master. It shows the steps
that fix this and offers to do them. See You
finished a branch before you changed the version.
You can publish alpha or beta versions from develop
while features keep changing, and keep the production branch for
stable versions. List develop in release.json:
{
"requires": "3.6.0",
"branch": "master",
"prereleaseBranches": ["develop"]
}
Then run these commands on develop. Each one commits the
version on develop, builds, publishes, tags the commit,
and pushes develop and the tag. GitHub marks the release
as a prerelease.
box release publish preminor alpha # 2.0.0 -> 2.1.0-alpha.1 (preid defaults to beta)
box release publish prerelease # 2.1.0-alpha.1 -> 2.1.0-alpha.2
box release publish # publish the prerelease already in box.json
box release publish --dryRun # show the steps, including git push origin develop
A listed branch publishes prerelease versions only. box release
publish minor on develop stops and points to
box release gitflow minor. The production branch still
publishes every version, so nothing changes there. The list is empty
by default. An older commandbox-release ignores the setting and still
refuses on develop, so set requires to
3.6.0 or newer.
To release the stable version, run box release gitflow
minor on develop as usual. From
2.1.0-alpha.3 it creates release/2.1.0,
merges into both branches, and publishes 2.1.0 from
production. Each alpha moved its notes into its own changelog section,
so write the notes for 2.1.0 under
[Unreleased] first. The command stops with a reminder
when the section is empty. It also asks before it finishes the
prerelease. In CI, add --finishPrerelease. box
release gitflow without a level stops on develop
while box.json holds an unpublished prerelease, because
that prerelease belongs on develop.
A hotfix during a prerelease line changes box.json on
both branches, such as 2.0.1 on the hotfix and
2.1.0-alpha.2 on develop. The merge into
develop then conflicts on box.json.
box release gitflow cancels that merge and shows the
steps, including which version to keep.
The GitHub Actions template also runs when you push a prerelease tag,
so do not run box release publish on your computer if you
use that workflow.
box release checks for common mistakes before it changes anything. It fixes some of them by itself. For others, it shows the fix and offers to do it.
You start hotfix/1.0.1 or release/1.1.0 and
add your notes. Then you select Finish in GitKraken,
or run git flow hotfix finish, but you did not run
box release gitflow or box release bump
first. Now master has the tag v1.0.1, but
box.json still has 1.0.0.
Run box release publish or box release
gitflow on master. The command explains what
happened, lists the steps that fix it, and asks:
Do these steps now and publish 1.0.1? [y/n]
Answer y. box release then:
hotfix/1.0.1 from master. For a
minor or major version, it creates a release branch, such as release/1.1.0.v1.0.1.box release gitflow on the new branch. It
changes the version, dates the notes, runs the tests, merges into
develop and master, publishes, and pushes
both branches. Then it deletes the branch.The release tags the new merge commit, the same way it tags any
release. master gets a second merge commit for the
branch. That is expected.
Answer n, or press Enter, to stop without changes. You
can then run the steps yourself:
git tag -d v1.0.1
git switch -c hotfix/1.0.1
box release gitflow patch # changes the version, merges, publishes, and pushes both branches
In CI or a script, nobody can answer the question. Add
--fixTag to do the steps without asking:
box release publish --fixTag
box release gitflow --fixTag --dryRun # shows the steps and changes nothing
box release does not offer the fix in these cases. The message explains what to do instead.
origin. That version may be
published. See Common problems.develop branch is missing.box
release publish minor for the tag v1.0.1.
Leave out the level to publish 1.0.1.hotfix/1.0.1, and that branch has
commits that are not on master.The fix also stops before it changes anything when
origin/master has commits that the tagged commit does not have.
box.json has 1.0.0-beta.15. You want
1.0.0-beta.16, but you run box release gitflow
patch instead of box release gitflow prerelease.
From a prerelease, patch, minor, and
major all make the stable version 1.0.0. So
the command shows what will happen and asks first:
note 1.0.0-beta.15 -> 1.0.0 finishes the prerelease. 1.0.0 is a stable version.
To publish the next prerelease instead, run: box release gitflow prerelease
Finish the prerelease and publish stable version 1.0.0? [y/n]
Answer n, or press Enter, to stop without changes. Then
run the command from the note. Answer y to publish 1.0.0.
box release publish <level> asks the same question.
A practice run (--dryRun) shows the note and does not
ask. box release bump <level> shows the note too.
It does not ask, because it publishes nothing.
In CI or a script, nobody can answer. The command stops before it
changes anything. Add --finishPrerelease to finish the
prerelease without the question:
box release gitflow patch --finishPrerelease
The question comes only from a level. box release
publish and box release gitflow without a level
publish the version already in box.json, so they do not
ask. This includes the GitHub Actions template, and the run without a
level that continues a release after a failure.
A new major version, such as 1.4.2 to
2.0.0, shows a note but does not ask. You chose
major on purpose.
You add notes on develop while
release/1.1.0 or a hotfix branch is open. Then both
branches changed [Unreleased]. box release
gitflow keeps the new develop notes under
[Unreleased] and removes the notes that the release
published. It prints:
Combined CHANGELOG.md: kept the [Unreleased] notes on develop, removed 1 note that [1.1.0] released, and added [1.1.0].
If you reworded a note on develop, the command keeps it
under [Unreleased]. Check the changelog on
develop after the release.
box release publish uses a tag at the current commit,
such as one from GitKraken. It pushes the tag and the production
branch when origin does not have them. See Gitflow and a Git GUI.box release
gitflow combines both versions. See Merge and publish in one command.box release publish <level> checks the new
version's tag before it changes any files.origin has new commits. When git
pull brings in new commits, the release stops before it
builds. Run the command again to check the updated files.box release resume creates and pushes the tag and the
GitHub Release. Do not run the full release again.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, and pushes the
branch if needed. Runs on the production branch, or on a branch
in prereleaseBranches for a prerelease. |
box release publish patch
| Changes the version, commits the change, and publishes.
You can also use minor, major, or a
prerelease level. A branch in prereleaseBranches
accepts prerelease levels only. |
box release publish --dryRun
| Builds the zip without committing, publishing, or pushing. |
box release publish --skipTests
| Publishes without running the tests again. |
box release publish --skipHooks
| Publishes without running the beforePublish command. |
box release publish patch --finishPrerelease
| Finishes a prerelease, such as 1.0.0-beta.4
to 1.0.0, without asking. box release
gitflow has the same flag. Use it in CI or a script. |
box release publish --fixTag
| Fixes a Gitflow finish that tagged a version before
box.json changed, without asking, and publishes
that version. See Mistakes box release can fix. |
box release gitflow minor
| On develop, creates a release branch, merges
it, and publishes. On a release or hotfix branch, changes the
version, merges that branch, and publishes. |
box release gitflow
| Merges and publishes the current release or hotfix
branch. Uses its version if newer than production; otherwise, a
hotfix uses patch (or prerelease for a
prerelease), and a release requires a level. |
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 test command, or 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. This example
publishes to both GitHub and ForgeBox and runs tests:
{
"requires": "3.0.0",
"branch": "main",
"changelog": "CHANGELOG.md",
"testRunner": "/tests/runner.cfm",
"runTests": true,
"publish": {
"forgebox": true,
"github": true
},
"engines": []
}
The JSON examples below show individual settings. Update those values
in your existing release.json; keep the other settings
you need.
Set branch to the production branch, usually
main or master. This branch holds published
stable 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. To publish
prereleases from develop as well, list it in
prereleaseBranches. See Publish prereleases from develop.
{
"publish": {
"forgebox": false,
"github": true
}
}
If release.json does not set
publish.forgebox, modules publish to ForgeBox and other
projects do not. Set it to true or false to
choose for yourself.
Set testRunner to the path of the TestBox runner on the
project's CommandBox server:
{
"testRunner": "/tests/runner.cfm"
}
The release finds the server's address when it runs the tests, the
same way box server open does. So
release.json does not repeat the port, and the port can
change. The server must have started at least once. With
engines, each engine's address comes from its own server
JSON file, so the engines can use different ports.
The runner can also be a full URL, such as
http://127.0.0.1:60310/tests/runner.cfm. Use a URL when
the tests run on a server that CommandBox did not start.
If release.json does not set testRunner,
the release uses testbox.runner from
box.json. If that is not set either, it uses /tests/runner.cfm.
Use this setting when another system runs the tests, such as a continuous integration (CI) workflow:
{
"runTests": false
}
Some projects run their tests inside CommandBox, not on a web server.
A CommandBox module often does this with box run-script
test. Set testCommand to that command:
{
"runTests": true,
"testCommand": "run-script test",
"engines": []
}
The release runs box run-script test in a new process
from the project root. You can leave out box. The
command's output shows while it runs. If the command fails, the
release stops the same way it stops for failing tests. A command fails
when it exits with an error, for example because a spec failed.
--skipTests skips the command.
With testCommand, the release does not use
testRunner and does not need a test server. The command
cannot test each engine, because it does not start servers. If
release.json sets both testCommand and
engines, release commands stop with an error.
The command runs in a new box process, so
box must be on your PATH. A test runner for a CommandBox
module often unloads that module and loads the working copy. Inside
the release's own CommandBox, it could unload commandbox-release in
the middle of the release. A new process keeps the release safe from
those changes.
box release init suggests run-script test
for a CommandBox module when box.json has a
test script and no TestBox runner URL.
A release can run a CommandBox command after the tests and the build
pass and before anything is published or pushed. Set it in hooks.beforePublish:
{
"hooks": {
"beforePublish": "deploybot env push --yes"
}
}
box release publish and box release gitflow
run the command. It runs in a new box process from the
project root, the same way as testCommand. You can leave
out box. The command's output shows while it runs. If the
command fails, the release stops and nothing is published or pushed. A
command fails when it exits with an error.
--dryRun) shows the command but does
not run it.--skipHooks skips the command. box release
resume never runs it.--yes.box.json and use run-script <name>.This setting is not the same as the prePublish and
postPublish scripts in box.json. CommandBox
runs those scripts around its own publish command, which
sends the package to ForgeBox.
Some deploy tools start a deploy when a branch is pushed. A new
version may need settings that the web server does not have yet, such
as a new key in .env. Then the deploy can fail. The
beforePublish command can send the settings before the
release pushes the branch. The example above uses commandbox-deploybot.
It sends nothing when the server already has the same settings.
Use this only when the release's push starts the deploy. Sending a
.env file usually restarts the site with the new
settings. If you deploy later, send the settings right before you
deploy instead. Otherwise the old code runs with the new settings
until the deploy.
Change settings in a way that the old and new code can both use:
The GitHub Actions workflow template uses
skipHooks=true. The workflow cannot read files from your
computer, such as .env.production. Your tag push has also
already started any deploy that runs on a push.
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, so both packages
exclude the same files. Setup adds common patterns. 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 include .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 build output, such as
includes/build/, 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.
The package leaves out coldbox/, modules/,
and testbox/ too. box install creates these
folders from the dependencies in box.json, so run
box install on the server after a deploy. Only
box install should write to modules/. Keep
your app's own modules in modules_app/, which the package
includes. To ship one of these folders, add a pattern that keeps it to
the ignore list, such as "!/coldbox/".
The build also stops if the package contains a .env
file, such as .env or .env.production. These
files can hold passwords and keys. Example files are allowed:
.env.example, .env.sample,
.env.template, and .env.dist. The
**/.* pattern that setup adds leaves out all
.env files.
During setup, the command finds server.json and
server-*.json files in the project root. It adds each
server 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. When
testRunner is a path, the command reads each engine's
port after the engine starts, so each server JSON file can use its own
port. It tries every engine even if one fails. It reports an error at
the end if any engine failed.
When tests fail, the command lists each failed test as bundle
> suite > spec -- message. Here, a bundle is a test
file, a suite is a group of tests, and a spec is one test. When
testing several engines, the final results group failed tests by engine.
The release commands use TestBox's eagerFailure option
to ask the runner to stop after the first test file that has a
failure. The rest of that file still runs. Later files are skipped.
The standard TestBox runner ignores this option and always runs every
test. To use it, copy
testbox/system/runners/HTMLRunner.cfm into your
tests folder, include the copy from
tests/runner.cfm, and change two lines in the copy:
<!--- Add next to the other cfparam tags --->
<cfparam name="url.eagerFailure" default="false" type="boolean">
<!--- Pass the option to TestBox --->
results = testbox.run( reporter=url.reporter, eagerFailure=url.eagerFailure )
A custom runner that calls testbox.run() itself needs
only the eagerFailure argument. Other tools that call the
runner without eagerFailure=true still run every test.
| Setting | Default | What it does |
|---|---|---|
requires
| the version that created the file | The oldest commandbox-release version this project can use. Commands stop and show how to update if your installed version is too old. |
prereleaseBranches
| []
| Branches that may publish prerelease versions with
box release publish, such as
["develop"]. Stable versions still
publish from branch. See Publish prereleases
from develop. |
tagPrefix
| v
| The text before the version in tag names. |
remote
| origin
| The Git remote that release commands get commits from and push to. |
gitSync
| true
| Gets new commits from the remote 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. |
hooks
| { "beforePublish": "" }
| A CommandBox command to run before publishing. See Run a command before publishing. |
Some mistakes have an automatic fix. See Mistakes box release can fix.
| 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. |
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 gitflow on that branch if
its version is newer than production. Otherwise, include a
level, such as box release gitflow patch. See Gitflow releases for the
GitKraken option. |
develop can publish only prerelease versions
| The branch is in prereleaseBranches, and the
version is stable. Use a prerelease level, such as box
release publish preminor alpha, or release the stable
version with box release gitflow minor. |
box release publish <level> must run from
production branch
| Switch to the production branch. To publish a prerelease
from this branch instead, add it to
prereleaseBranches in release.json. |
... could not be merged into develop
| Switch to develop, merge the release or
hotfix branch, fix the conflicts, and commit. Switch back to the
release or hotfix branch and run box release
gitflow without a level. The command combines a changelog
conflict by itself. When it cannot, the message names the part
of the changelog that changed on both branches. |
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. If the tests
run without a server, set testCommand. |
testRunner is the path ..., but no server has started
| Start the project's server once with box server
start, so CommandBox knows its address. You can also set
testRunner to a full URL. |
The test command failed: box ...
| Read the command's output above the error, or run the
same command in the project root. Fix the tests, or use
--skipTests when the same files already passed. |
The test command did not start because box was not found
| Add the CommandBox folder to PATH, and then open a new terminal. |
release.json has both testCommand and engines
| Remove engines to use the test command.
Remove testCommand to test each engine. |
The beforePublish command failed: box ...
| Read the command's output above the error, or run the
same command in the project root. Fix the problem, or use
--skipHooks to release without it. |
release.json hooks has an unknown hook
| Check the spelling. beforePublish is the
only hook. |
The package contains .env...
| Add "**/.env*" to the
box.json ignore list. To keep an example file, also
add "!/.env.example" after it. If the
message names a box.json script, remove that script
first. See The ColdBox
template's postInstall script. |
The box.json ignore list is empty after box install
| An install script runs package set ignore.
box release check names it. Run box release
init and answer y to remove the ColdBox
template's script. Change any other script by hand. Then run
box release init --yes to add the patterns again. |
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. |
The package contains node_modules
| The package includes a node_modules folder
with Node.js dependencies. Add /node_modules/ to
the box.json ignore list, or run box release
init --yes. |
The package is ... MB
| The zip is larger than 50 MB. Add large folders your
package does not need to the box.json ignore list.
These may include uploads, media, or build output. The package
already leaves out coldbox/, modules/,
and testbox/. The warning does not stop the build. |
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. |
Tag v1.2.3 is on this commit, but box.json still has
version 1.2.2
| A Gitflow finish tagged the version before box.json
changed. Answer y when the command offers to fix
it, or add --fixTag. You can also follow the steps
in the message. See You
finished a branch before you changed the version. |
Nobody can answer the question here. To publish X, add --finishPrerelease
| The level finishes a prerelease. To publish the next
prerelease instead, use prerelease. To publish the
stable version, add --finishPrerelease. |
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.
Install the development dependencies and run the tests:
box install
box run-script test # the full suite
box run-script test:fast # unit tests only, under a minute
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. Each integration bundle starts
one box and runs all of its commands in it, so the full
suite takes minutes instead of a new box start for every command.
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.
box release init offers to remove the ColdBox template's postInstall script,
pathExists .env || cp .env.example .env && package set ignore=[]. Each box install that runs
it empties the box.json ignore list. On a server, it can also copy .env.example to .env.
With --yes, or when nobody can answer, setup keeps the script and prints a note.box release check, box release publish, and the .env build stop name any install script
that runs package set ignore.coldbox/, modules/, and testbox/. box install creates these
folders, so the server runs box install after a deploy. Web app zips get much smaller.modules_app/. The package includes that folder."!/coldbox/".box release publish <level> and box release gitflow <level> ask before they finish a
prerelease. patch, minor, and major all finish one. For example, patch changes
1.0.0-beta.15 to 1.0.0. The question shows the command that publishes the next
prerelease instead. Answer n, or press Enter, to stop without changes.--finishPrerelease flag finishes a prerelease without the question. Use it in CI or a
script.box release bump <level> shows the note too. It does not ask, because it publishes nothing.1.4.2 to 2.0.0, shows a note. It does not ask.--finishPrerelease to the command. A release without a
level does not ask, so the GitHub Actions template is not affected.box release publish <level> stops when git pull brings in a different version in
box.json. Run the command again to check the updated project.relese.json to enable test runs when publishingtestRunner in release.json can be a path on the project's CommandBox server, such as
"/tests/runner.cfm". The release finds the server's address when it runs the tests, so
release.json does not repeat the port. A full URL still works.testbox.runner in box.json works too. Before, it stopped every release command
with "testRunner must be a full URL".engines can use its own port. box release test reads
each engine's address after it starts the engine.release.json nor box.json sets a test runner, the release uses
/tests/runner.cfm on the project's server. It used http://127.0.0.1:60299/tests/runner.cfm.
box release init writes the path into new release.json files. box testbox run uses the
same default.testCommand setting in release.json runs the tests with a CommandBox command,
such as "testCommand": "run-script test". Use it for a project whose tests run inside
CommandBox without a web server, such as a CommandBox module. box release test,
box release publish, and box release gitflow run it in a new box process from the
project root. If the command fails, the release stops the same way it stops for failing
tests. --skipTests skips it.testCommand, the release does not check testRunner or need a test server. The
setting cannot be used with engines. release.json with both stops with an error.box release check shows the test command and checks that it can find box.box release init suggests run-script test for a CommandBox module that has a test
script and no TestBox runner URL.hooks.beforePublish setting in release.json runs a CommandBox command after the
tests and the build pass and before anything is published or pushed. For example,
"hooks": { "beforePublish": "deploybot env push --yes" } sends a web app's settings to the
server before the push starts a deploy. box release publish and box release gitflow run
it. If the command fails, the release stops and nothing is published. A practice run shows
the command without running it.box release publish and box release gitflow have a new --skipHooks flag. It skips the
beforePublish command.box release check shows the beforePublish command and checks that it can find box.box release publish and box release gitflow can fix a Gitflow finish that tagged a
version before box.json changed. This happens when you finish a release or hotfix in
GitKraken or git flow before you change the version. The commands show the steps and ask
whether to do them. If you answer y, box release creates hotfix/1.0.1 (or
release/1.1.0 for a minor or major version) from production and deletes the local tag.
Then it changes the version, merges into both branches, publishes, and pushes. A new
--fixTag flag does this without asking, such as in CI. The commands never ask in a practice
run or when nobody can answer. See "Mistakes box release can fix" in the README.prereleaseBranches setting in release.json lists branches that may publish
prerelease versions, such as "prereleaseBranches": ["develop"]. On a listed branch,
box release publish preminor alpha, box release publish prerelease, and
box release publish commit, tag, and push the prerelease on that branch and mark the GitHub
Release as a prerelease. Stable versions still publish from the production branch. A stable
level on a listed branch stops and points to box release gitflow. The list is empty by
default, so existing projects behave as before. See "Publish prereleases from develop" in the
README.box release check shows the prerelease branches and accepts a listed branch when box.json
holds a prerelease.box release package on a prerelease branch no longer adds -snapshot to a prerelease
version. The package gets the build ID, as it does on the production branch.
box release gitflow without a level on develop stops when develop is a prerelease
branch and box.json holds a prerelease that is newer than production. Before, it created a
release branch for the prerelease and published it from production.
When a Gitflow merge into a prerelease branch conflicts on box.json, the manual steps say
which version to keep. This happens when a hotfix meets a prerelease on develop.
When a prerelease line ends with a stable version and [Unreleased] is empty, the error says
that the prerelease notes stay in their own sections and asks for notes for the stable version.
The build stops when the package contains a .env file, such as .env.production. These
files can hold passwords and keys. Example files such as .env.example are still allowed.
Add "**/.env*" to the box.json ignore list to leave them out.
The GitHub Actions workflow template passes skipHooks=true. Copy the change into an
existing .github/workflows/release.yml if you set hooks.beforePublish.
box release gitflow merges the changelog into develop when develop added notes while a
release or hotfix branch was open. It keeps the new notes under [Unreleased] and removes
the notes that the release published. Before, it stopped with the message "The [Unreleased]
notes in CHANGELOG.md changed on both branches" and asked you to merge by hand.
box release publish <level> checks the new version's tag before it changes any files. Before,
it made the "Release x.y.z" commit and then stopped because the tag already existed.git flow can tag a version, such as v1.0.1, before
box.json changes. box release publish and box release gitflow now explain how to fix
this. When the tag is only on your computer, delete it, create hotfix/1.0.1, and run
box release gitflow patch. Before, the message suggested box release bump patch, which
stopped on the same tag.box release publish and box release check
now suggest box release bump prerelease. Before, they suggested box release bump patch,
which would have finished the prerelease.box release gitflow no longer warns that the build skipped the tests after they passed
on the release or hotfix branch. The build now says which branch passed the tests.box release gitflow on a hotfix branch without a level now updates a prerelease. For
example, 1.0.0-beta.2 becomes 1.0.0-beta.3. Before, it published 1.0.0. Use
box release gitflow patch to finish the prerelease. With preid and no level, the hotfix
changes the label, such as 1.0.0-beta.2 to 1.0.0-rc.1.box.json ignore patterns for common files that should not be in a package.box release gitflow now combines the changelog when it is the only file with a merge
conflict. It keeps the [Unreleased] notes on develop and adds the new version section.
A part of the changelog that changed on both branches still stops the command with the
manual merge steps, and so does a conflict in any other file.box release check and box release publish list recommended box.json ignore patterns
that are missing from the project's ignore list. These patterns keep files out of the
package. Run box release init --yes to add them. Missing patterns do not stop a release.node_modules or is
larger than 50 MB.--force, box release init skips the setup questions when release.json exists.
Setup keeps existing settings and changelog files and adds missing ignore patterns.
Use --force to replace those files. Without --yes, setup asks the questions again.box release publish with an existing tag now pushes the production branch when origin
does not have the tagged commit. The checks report this before anything is published.
They stop if origin has commits on that branch that your checkout does not have.box release gitflow merges a release or hotfix branch and publishes the package.
On develop, it creates a release branch first. It changes the version when needed and
runs the tests. It merges into develop and the production branch before publishing.
Then it pushes both branches and deletes the release or hotfix branch by default.remote setting in release.json names the Git remote for releases. The default is
origin.box release publish <level> on a Gitflow release or hotfix branch now suggests
box release gitflow.box release check reports it too.box release check now uses the same tag rule as box release publish. A version tag at the
current commit that is already on the remote is reported as ready. A remote that cannot be
checked is reported as a problem.box release publish and box release resume now accept an annotated tag that is already
on the remote. GitKraken and git flow create annotated tags. Before, the command reported
that the tag pointed to a different commit.box release gitflow now shows SSH key help when git fetch is refused.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.eagerFailure). The standard TestBox runner ignores this option. The README shows the
two-line runner change that turns it on.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.[Unreleased] looks empty because a group heading such as ## Added follows it,
box release bump and box release publish <level> name that heading. They say to use
### Added, because ## starts a new version section.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