- Notifications
You must be signed in to change notification settings - Fork15
The universal Sentry release CLI 🚀
License
getsentry/craft
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
craft
is a command line tool that helps to automate and pipeline package releases. It suggests, andthen enforces a specific workflow for managing release branches, changelogs, artifact publishing, etc.
- Installation
- Usage
- Caveats
- Global Configuration
- Workflow
- Configuration File:
.craft.yml
- Status Provider
- Artifact Provider
- Target Configurations
- Per-target options
- GitHub (
github
) - NPM (
npm
) - Python Package Index (
pypi
) - Sentry internal PyPI (
sentry-pypi
) - Homebrew (
brew
) - NuGet (
nuget
) - Rust Crates (
crates
) - Google Cloud Storage (
gcs
) - GitHub Pages (
gh-pages
) - Sentry Release Registry (
registry
) - Cocoapods (
cocoapods
) - Docker (
docker
) - Ruby Gems Index (
gem
) - AWS Lambda Layer (
aws-lambda-layer
) - Unity Package Manager (
upm
) - Maven central (
maven
) - Symbol Collector (
symbol-collector
) - pub.dev (
pub-dev
) - Hex (
hex
) - Commit on Git Repository (
commit-on-git-repository
)
- Integrating Your Project with
craft
- Pre-release (Version-bumping) Script: Conventions
- Post-release Script: Conventions
- Development
craft
isdistributed as a minified single JS binary.
Recommendation is to used this file directly but one can also installcraft
asanNPM package and can be installed viayarn
ornpm
:
yarn global add @sentry/craft
npm install -g @sentry/craft
$ craft -hcraft<command>Commands: craft prepare NEW-VERSION 🚢 Prepare a new release branch [aliases: p, prerelease, prepublish, prepare, release] craft publish NEW-VERSION 🛫 Publish artifacts [aliases: pp, publish] craft targets List defined targets as JSON array craft config Print the parsed, processed, and validated Craft configforthe current projectin pretty-JSON. craft artifacts<command> 📦 Manage artifacts [aliases: a, artifact]Options: --no-input Suppresses all user prompts [default: false] --dry-run Dry run mode:do not perform any real actions --log-level Logging level [choices:"Fatal","Error","Warn","Log","Info","Success","Debug","Trace","Silent","Verbose"] [default:"Info"] -v, --version Show version number [boolean] -h, --help Showhelp [boolean]
Craft currently supportssemantic versioning (semver)-like versions for theNEW-VERSION
argument passed to itsprepare
andpublish
commands. This means, releases made with craft need to follow a general pattern as follows:
<major>.<minor>.<patch>(-<prerelease>)?(-<build>)?
- The
<major>
,<minor>
and<patch>
numbers are required - The
<prerelease>
and<build>
identifiers are optional
Preview or pre-release identifiersmust include one of the following identifiers
preview|pre|rc|dev|alpha|beta|unstable|a|b
and may additionally include incremental pre-release version numbers.Adding identifiers other than the ones listed above result in Craft either rejecting the release (if not parse-able) or the release being treated by individual targets as a stable release.
Examples:
1.0.0-preview1.0.0-alpha.01.0.0-beta.11.0.0-rc.201.0.0-a// invalid or incorrectly treated1.0.0-foo1.0.0-canary.0
Python has the concept of post releases, which craft handles implicitly. A post release is indicated by a-\d+
suffix to the semver version, for example:1.0.0-1
.Given that we only consider certain identifiers aspre-releases, post releases are considered stable releases.
Craft supports adding a build identifier to your version, for example if you release the same package version for different platforms or architectures.You can also combine build and pre-release identifiers but in this case, the pre-release identifier has to come first.
Examples:
// valid1.0.0+x86_641.0.0-rc.1+x86_64// invalid or incorrectly treated1.0.0+rc.1+x86_641.0.0+x86_64-beta.0
- When interacting with remote GitHub repositories,
craft
uses theremoteorigin
by default. If you have a different setup, set theCRAFT_REMOTE
environment variable or the--remote
option to the git remoteyou are using.
Global configuration forcraft
can be done either by using environmentvariables or by adding values to a configuration file (see below).
All command line flags can be set through environment variables by prefixingthem withCRAFT_
and converting them to UPPERCASE_UNDERSCORED versions:
CRAFT_LOG_LEVEL=DebugCRAFT_DRY_RUN=1CRAFT_NO_INPUT=0
Since Craft heavily relies on GitHub, it needs theGITHUB_TOKEN
environmentvariable to be set to a properGitHub Personal Access Token for almostanything. The token only needsrepo
scope (repo:status
andpublic_repo
subscopes, to be precise).
Additional environment variables may be required when publishing to specifictargets (e.g.TWINE_USERNAME
andTWINE_PASSWORD
for PyPI target).
craft
will read configuration variables (keys, tokens, etc.) from thefollowing locations:
$HOME/.craft.env
$PROJECT_DIR/.craft.env
- the shell's environment
where$HOME
is the current user's home directory, and$PROJECT_DIR
is thedirectory where.craft.yml
is located.
These locations will be checked in the order specified above, with valuesfound in one location overwriting anything found in previous locations. In otherwords, environment variables will take precedence over either configurationfile, and the project-specific file will take precedence over the file in$HOME
.
The env files must be written in shell (sh
/bash
) format.Leadingexport
is allowed.
Example:
# ~/.craft.envGITHUB_TOKEN=token123export NUGET_API_TOKEN=abcdefgh
This command will create a new release branch, check the changelog entries,run a version-bumping script, and push this branch to GitHub. We expectthat CI triggered by pushing this branch will result in release artifactsbeing built and uploaded to the artifact provider you wish to use during thesubsequentpublish
step.
craft prepare NEW-VERSION🚢 Prepare a new release branchPositionals: NEW-VERSION The new version you want to release [string] [required]Options: --no-input Suppresses all user prompts [default: false] --dry-run Dry run mode:do not perform any real actions --log-level Logging level [choices:"Fatal","Error","Warn","Log","Info","Success","Debug","Trace","Silent","Verbose"] [default:"Info"] --rev, -r Source revision (git SHA or tag) to prepare from (if not branch head) [string] --no-push Do not push the release branch [boolean] [default: false] --no-git-checks Ignorelocal git changes and unsynchronized remotes [boolean] [default: false] --no-changelog Do not checkfor changelog entries [boolean] [default: false] --publish Run"publish" right after"release"[boolean] [default: false] --remote The git remote to use when pushing [string] [default:"origin"] -v, --version Show version number [boolean] -h, --help Showhelp [boolean]
The command will find a release branch for the provided version. The normal flowis for this release branch to be created automatically bycraft prepare
, butthat's not strictly necessary. Then, it subscribes to the latest status checks onthat branch. Once the checks pass, it downloads the release artifacts from theartifact provider configured in.craft.yml
and uploads them to the targets namedon the command line (and pre-configured in.craft.yml
).
craft publish NEW-VERSION🛫 Publish artifactsPositionals: NEW-VERSION Version to publish [string] [required]Options: --no-input Suppresses all user prompts [default: false] --dry-run Dry run mode:do not perform any real actions --log-level Logging level [choices:"Fatal","Error","Warn","Log","Info","Success","Debug","Trace","Silent","Verbose"] [default:"Info"] --target, -t Publish to this target [string] [choices:"npm","gcs","registry","docker","github","gh-pages","all","none"] [default:"all"] --rev, -r Source revision (git SHA or tag) to publish (if not release branch head) [string] --no-merge Do not merge the release branch after publishing [boolean] [default: false] --keep-branch Do not remove release branch after merging it [boolean] [default: false] --keep-downloads Keep all downloaded files [boolean] [default: false] --no-status-check Do not checkfor build status [boolean] [default: false] -v, --version Show version number [boolean] -h, --help Showhelp [boolean]
Let's imagine we want to release a new version of our package, and the versionin question is1.2.3
.
We runprepare
command first:
$ craft prepare 1.2.3
After some basic sanity checks this command creates a new release branchrelease/1.2.3
, runs the version-bumping script (scripts/bump-version.sh
),commits the changes made by the script, and then pushes the new branch toGitHub. At this point CI systems kick in, and the results of those builds, aswell as built artifacts (binaries, NPM archives, Python wheels) are graduallyuploaded to GitHub.
To publish the built artifacts we runpublish
:
$ craft publish 1.2.3
This command will find our release branch (release/1.2.3
), check the buildstatus of the respective git revision in GitHub, and then publish availableartifacts to configured targets (for example, to GitHub and NPM in the case ofCraft).
Project configuration forcraft
is stored in.craft.yml
configuration file,located in the project root.
Craft tries to determine the GitHub repo information from the local git repo andits remotes configuration. However, sincepublish
command does not require alocal git checkout, you may want to hard-code this information into theconfiguration itself:
github:owner:getsentryrepo:sentry-javascript
This command will run on your newly created release branch as part ofprepare
command. By default, it is set tobash scripts/bump-version.sh
. Please referto thePre-release version bumping script conventions sectionfor more details.
preReleaseCommand:bash scripts/bump-version.sh
This command will run after a successfulpublish
. By default, it is set tobash scripts/post-release.sh
. It willnot error if the default script ismissing though, as this may not be needed by all projects. Please refer to thePost-release script conventions sectionfor more details.
postReleaseCommand:bash scripts/post-release.sh
This overrides the prefix for the release branch name. The full branch name usedfor a release is{releaseBranchPrefix}/{version}
. The prefix defaults to"release"
.
releaseBranchPrefix:publish
craft
can help you to maintain change logs for your projects. At the moment,craft
supports two approaches:simple
, andauto
to changelog management.
Insimple
mode,craft prepare
will remind you to add a changelog entry to thechangelog file (CHANGELOG.md
by default).
Inauto
mode,craft prepare
will use the following logic:
- If there's already an entry for the given version, use that
- Else if there is an entry named
Unreleased
, rename that to the givenversion - Else, create a new section for the version and populate it with the changessince the last version. It usesGitHubMilestonesto provide a concise and rich changelog. If the PRs are associated with amilestone, the milestone title and description are used as the changelogentry alongside a brief list of associated PRs. Any individual commits andPRs are listed under the "Various improvements & fixes" section at thebottom. Check outCraft's ownreleases as example.
Configuration
Option | Description |
---|---|
changelog | optional. Path to the changelog file. Defaults toCHANGELOG.md |
changelogPolicy | optional. Changelog management mode (none ,simple , orauto ). Defaults tonone . |
Example (simple
):
changelog:CHANGESchangelogPolicy:simple
Valid changelog example:
## 1.3.5* Removed something## 1.3.4* Added something
Example (auto
):
changelog:CHANGESchangelogPolicy:auto
Changelog with staged changes example:
## Unreleased* Removed something## 1.3.4* Added something
Additionally,.craft.yml
is used for listing targets where you want topublish your new release.
It is possible to specify minimalcraft
version that is required to work withyour configuration.
Example:
minVersion:'0.5.0'
You can provide a list of patterns for files thathave to be available beforeproceeding with publishing. In other words, for every pattern in the given listthere has to be a file present that matches that pattern. This might be helpfulto ensure that we're not trying to do an incomplete release.
Example:
requireNames: -/^sentry-craft.*\.tgz$/ -/^gh-pages.zip$/
You can configure which status providerscraft
will use to check for your build status.By default, it will use GitHub but you can add more providers if needed.
Configuration
Option | Description |
---|---|
name | Name of the status provider: onlygithub (default) for now. |
config | In case ofgithub : may includecontexts key that contains a list of required contexts (checks) |
Example:
statusProvider:name:githubconfig:contexts: -Travis CI - Branch
You can configure which artifact providerscraft
will use to fetch artifacts from.By default, GitHub is used, but in case you don't need use any artifacts in yourproject, you can set it tonone
.
Configuration
Option | Description |
---|---|
name | Name of the artifact provider:github (default),gcs , ornone |
Example:
artifactProvider:name:none
The configuration specifies which release targets to run for the repository. Torun more targets, list the target identifiers under thetargets
key in.craft.yml
.
Example:
targets: -name:npm -name:github -name:registryid:browsertype:sdkonlyIfPresent:/^sentry-browser-.*\.tgz$/includeNames:/\.js$/checksums: -algorithm:sha384format:base64config:canonical:'npm:@sentry/browser' -name:registryid:nodetype:sdkonlyIfPresent:/^sentry-node-.*\.tgz$/config:canonical:'npm:@sentry/node'
The following options can be applied to every target individually:
Name | Description |
---|---|
includeNames | optional. Regular expression: only matched files will be processed by the target. There is one special case thatincludeNames supports. |
excludeNames | optional. Regular expression: the matched files will be skipped by the target. Matching is performed after testing for inclusion (viaincludeNames ). |
id | optional. A unique id for the target type so one can refer to that target individually with the-t option with thepublish command like-t registry[browser] . (see the example config above) |
If neither option is included, all artifacts for the release will be processed by the target.
Example:
targets: -name:githubincludeNames:/^.*\.exe$/excludeNames:/^test.exe$/
Create a release on Github. If a Markdown changelog is present in therepository, this target tries to read the release name and description from thechangelog. Otherwise, defaults to the tag name and tag's commit message.
IfpreviewReleases
is set totrue
(which is the default), the releasecreated on GitHub will be marked as a pre-release version if the release namecontains any one ofpre-release identifiers.
Environment
Name | Description |
---|---|
GITHUB_TOKEN | Personal GitHub API token (seehttps://github.com/settings/tokens) |
Configuration
Option | Description |
---|---|
tagPrefix | optional. Prefix for new git tags (e.g. "v"). Empty by default. |
previewReleases | optional. Automatically detect and create preview releases.true by default. |
tagOnly | optional. If set totrue , only create a tag (without a GitHub release).false by default. |
Example:
targets: -name:githubtagPrefix:vpreviewReleases:false
Releases an NPM package to the public registry. This requires a package tarballgenerated bynpm pack
in the artifacts. The file will be uploaded to theregistry withnpm publish
, or withyarn publish
ifnpm
is not found. Thisrequires NPM to be authenticated with sufficient permissions to publish the package.
Environment
Thenpm
utility must be installed on the system.
Name | Description |
---|---|
NPM_TOKEN | Anautomation token allowed to publish. |
NPM_BIN | optional. Path to the npm executable. Defaults tonpm |
YARN_BIN | optional. Path to the yarn executable. Defaults toyarn |
CRAFT_NPM_USE_OTP | optional. If set to "1", you will be asked for an OTP (for 2FA) |
Configuration
Option | Description |
---|---|
access | optional. Visibility for scoped packages:restricted (default) orpublic |
checkPackageName | optional. If defined, check this package on the registry to get the current latest version to compare for thelatest tag. The package(s) to be published will only be tagged withlatest if the new version is greater than the checked package's version |
Example
targets: -name:npmaccess:public
Uploads source dists and wheels to the Python Package Index viatwine.The source code bundles and/or wheels must be in the release assets.
Environment
Thetwine
Python package must be installed on the system.
Name | Description |
---|---|
TWINE_USERNAME | User name for PyPI with access rights for the package |
TWINE_PASSWORD | Password for the PyPI user |
TWINE_BIN | optional. Path to twine. Defaults totwine |
Configuration
none
Example
targets: -name:pypi
Creates a GitHub pull request to import the package into a repo set uplikegetsentry/pypi
Environment
Name | Description |
---|---|
GITHUB_TOKEN | Personal GitHub API token (seehttps://github.com/settings/tokens) |
Configuration
Option | Description |
---|---|
internalPypiRepo | GitHub repo containing pypi metadata |
Example
targets: -name:pypi -name:sentry-pypiinternalPypiRepo:getsentry/pypi
Pushes a new or updated homebrew formula to a brew tap repository. The formulais committed directly to the master branch of the tap on GitHub, therefore thebot needs rights to commit tomaster
on that repository. Therefore, formulasonhomebrew/core
are not supported, yet.
The tap is configured with the mandatorytap
parameter in the same format asthebrew
utility. A tap<org>/<name>
will expand to the GitHub repositorygithub.com:<org>/homebrew-<name>
.
The formula contents are given as configuration value and can be interpolatedwith Mustache template syntax ({{ variable }}
). The interpolation contextcontains the following variables:
version
: The new versionrevision
: The tag's commit SHAchecksums
: A map containing sha256 checksums for every release asset. Usethe full filename to access the sha, e.g.checksums.MyProgram-x86
. If thefilename contains dots (.
), they are being replaced with__
. If thefilename contains the currently released version, it is replaced with__VERSION__
.For example,sentry-wizard-v3.9.3.tgz
checksums will be accessible by the keychecksums.sentry-wizard-v__VERSION____tgz
.
Environment
Name | Description |
---|---|
GITHUB_TOKEN | Personal GitHub API token (seeh ttps://github.com/settings/tokens) |
Configuration
Option | Description |
---|---|
tap | The name of the homebrew tap used to access the GitHub repo |
template | The template for contents of the formula file (ruby code) |
formula | optional. Name of the formula. Defaults to the repository name |
path | optional. Path to store the formula in. Defaults toFormula |
Example
targets: -name:brewtap:octocat/tools# Expands to github.com:octocat/homebrew-toolsformula:myproject# Creates the file myproject.rbpath:HomebrewFormula# Creates the file in HomebrewFormula/template:> class MyProject < Formula desc "This is a test for homebrew formulae" homepage "https://github.com/octocat/my-project" url "https://github.com/octocat/my-project/releases/download/{{version}}/binary-darwin" version "{{version}}" sha256 "{{checksums.binary-darwin}}" def install mv "binary-darwin", "myproject" bin.install "myproject" end end
Uploads packages toNuGet via.NET Core.By default,craft
publishes all packages with.nupkg
extension.
Environment
Thedotnet
tool must be available on the system.
Name | Description |
---|---|
NUGET_API_TOKEN | NuGet personalAPI token |
NUGET_DOTNET_BIN | optional. Path to .NET Core. Defaults todotnet |
Configuration
none
Example
targets: -name:nuget
Publishes a single Rust package or entire workspace on the public crate registry(crates.io). If the workspace contains multiple crates,they are published in an order depending on their dependencies.
Environment
"cargo" must be installed and configured on the system.
Name | Description |
---|---|
CRATES_IO_TOKEN | The access token to the crates.io account |
CARGO_BIN | optional. Path to cargo. Defaults tocargo . |
Configuration
Option | Description |
---|---|
noDevDeps | optional. StripsdevDependencies from crates before publishing. This is useful if a workspace crate uses circular dependencies for docs. Requirescargo-hack installed. Defaults tofalse . |
Example
targets: -name:cratesnoDevDeps:false
Uploads artifacts to a bucket in Google Cloud Storage.
The bucket paths (paths
) can be interpolated using Mustache syntax ({{ variable }}
). The interpolation context contains the following variables:
version
: The new project versionrevision
: The SHA revision of the new version
Environment
Google Cloud credentials can be provided using either of the following two environment variables.
Name | Description |
---|---|
CRAFT_GCS_TARGET_CREDS_PATH | Local filesystem path to Google Cloud credentials (service account file) |
CRAFT_GCS_TARGET_CREDS_JSON | Full service account file contents, as a JSON string |
If defined,CRAFT_GCS_TARGET_CREDS_JSON
will be preferred overCRAFT_GCS_TARGET_CREDS_PATH
.
Note:CRAFT_GCS_TARGET_CREDS_JSON
andCRAFT_GCS_TARGET_CREDS_PATH
were formerly calledCRAFT_GCS_CREDENTIALS_JSON
andCRAFT_GCS_CREDENTIALS_PATH
, respectively. While those names will continue to work for the foreseeable future, you'll receive a warning encouraging you to switch to the new names.
Configuration
Option | Description |
---|---|
bucket | The name of the GCS bucket where artifacts are uploaded. |
paths | A list of path objects that represent bucket paths. |
paths.path | Template-aware bucket path, which can contain{{ version }} and/or{{ revision }} . |
paths.metadata | optionalMetadata for uploaded files. By default, it setsCache-Control to"public, max-age=300" . |
Example
targets: -name:gcsbucket:bucket-namepaths: -path:release/{{version}}/downloadmetadata:cacheControl:`public, max-age=3600` -path:release/{{revision}}/platform/package
Extracts an archive with static assets and pushes them to the specified gitbranch (gh-pages
by default). Thus, it can be used to publish documentationor any other assets toGitHub Pages, so they will be later automatically renderedby GitHub.
By default, this target will look for an artifact namedgh-pages.zip
, extract it,and commit its contents togh-pages
branch.
WARNING! The destination branch will be completely overwritten by the contentsof the archive.
Environment
none
Configuration
Option | Description |
---|---|
branch | optional The name of the branch to push the changes to.gh-pages by default. |
githubOwner | optional GitHub project owner, defaults to the value from the global configuration. |
githubRepo | optional GitHub project name, defaults to the value from the global configuration. |
Example
targets: -name:gh-pagesbranch:gh-pages
The target will update the Sentry release registry repo(https://github.com/getsentry/sentry-release-registry/) with the latest version of theprojectcraft
is used with. The release registry repository will be checked outlocally, and then the new version file will be created there, along with the necessarysymbolic links.
Two package types are supported: "sdk" and "app". Type "sdk" means that the packageis uploaded to one of the public registries (PyPI, NPM, Nuget, etc.), and thatthe corresponding package directory can be found inside "packages" directory of therelease regsitry. Type "app" indicates that the package's version files are locatedin "apps" directory of the registry.
It is strongly discouraged to have multipleregistry
targets in a config as itsupports grouping/batching multiple apps and SDKs in a single target.
Environment
none
Configuration
Option | Description |
---|---|
apps | List ofapp configs as a dict, keyed by their canonical names (example:app:craft ) |
sdks | List ofsdk configs as a dict, keyed by their canonical names (example:maven:io.sentry:sentry ) |
(sdks|apps).urlTemplate | optional URL template that will be used to generate download links for "app" package type. |
(sdks|apps).linkPrereleases | optional Update package versions even if the release is a preview release, "false" by default. |
(sdks|apps).checksums | optional A list of checksums that will be computed for matched files (seeincludeNames ). Every checksum entry is an object with two attributes: algorithm (one ofsha256 ,sha384 , andsha512 ) and format (base64 andhex ). |
(sdks|apps).onlyIfPresent | optional A file pattern. The target will be executedonly when the matched file is found. |
Example
targets: -name:registrysdks:'npm:@sentry/browser':apps:'npm:@sentry/browser':urlTemplate:'https://example.com/{{version}}/{{file}}'checksums: -algorithm:sha256format:hex
Pushes a new podspec to the central cocoapods repository. The Podspec is fetchedfrom the Github repository with the revision that is being released. No releaseassets are required for this target.
Environment
Thecocoapods
gem must be installed on the system.
Name | Description |
---|---|
COCOAPODS_TRUNK_TOKEN | The access token to the cocoapods account |
COCOAPODS_BIN | optional. Path topod executable. |
Configuration
Option | Description |
---|---|
specPath | Path to the Podspec file in the repository |
Example
targets: -name:cocoapodsspecPath:MyProject.podspec
Copies an existing source image tagged with the revision SHA to a new targettagged with the released version. No release assets are required for this targetexcept for the source image at the provided source image location so it would bea good idea to add a status check that ensures the source image exists, otherwisecraft publish
will fail at the copy step, causing an interrupted publish.This is an issue for other, non-idempotent targets, not for the Docker target.
Environment
docker
executable (or something equivalent) with BuildKit must be installed on the system.
Name | Description |
---|---|
DOCKER_USERNAME | The username for the Docker registry. |
DOCKER_PASSWORD | The personal access token for the account. |
DOCKER_BIN | optional. Path todocker executable. |
Configuration
Option | Description |
---|---|
source | Path to the source Docker image to be pulled |
sourceFormat | Format for the source image name. Default:{{{source}}}:{{{revision}}} |
target | Path to the target Docker image to be pushed |
targetFormat | Format for the target image name. Default:{{{target}}}:{{{version}}} |
Example
targets: -name:dockersource:us.gcr.io/sentryio/crafttarget:getsentry/craft# Optional but strongly recommendedstatusProvider:name:githubconfig:contexts: -Travis CI - Branch# or whatever builds and pushes your source image
Pushes a gemRuby Gems.It also requires you to be logged in withgem login
.
Environment
gem
must be installed on the system.
Name | Description |
---|---|
GEM_BIN | optional. Path to "gem" executable. Defaults togem |
Configuration
none
Example
targets: -name:gem
The target will create a new public lambda layer in each available region withthe extracted artifact from the artifact provider, and update the Sentry releaseregistry with the new layer versions afterwards.
Environment
Name | Description |
---|---|
AWS_ACCESS_KEY | The access key of the AWS account to create and publish the layers. |
AWS_SECRET_ACCESS_KEY | The secret access key of the AWS account to create and publish the layers. |
Configuration
Option | Description |
---|---|
linkPrereleases | optional Updates layer versions even if the release is a preview release,false by default. |
includeNames | optional Exists for all targets,see here. It must filter exactly one artifact. |
layerName | The name of the layer to be published. |
compatibleRuntimes | A list of compatible runtimes for the layer. Each compatible runtime consists on the name of the runtime and a list of compatible versions. |
license | The license of the layer. |
Example
targets: -name:aws-lambda-layerincludeNames:/^sentry-node-serverless-\d+(\.\d+)*\.zip$/layerName:SentryNodeServerlessSDKcompatibleRuntimes: -name:nodeversions: -nodejs10.x -nodejs12.xlicense:MIT
Pulls the package as a zipped artifact and pushes the unzipped content to the target repository, tagging it with the provided version.
WARNING! The destination repository will be completely overwritten.
Environment
none
Configuration
Option | Description |
---|---|
releaseRepoOwner | Name of the owner of the release target |
releaseRepoName | Name of the repo of the release target |
Example
targets: -name:upmreleaseRepoOwner:'getsentry'releaseRepoName:'unity'
PGP signs and publishes packages to Maven Central.
Note: in order to see the output of the commands, set thelogging level totrace
.
Environment
Name | Description |
---|---|
OSSRH_USERNAME | Username of Sonatype repository. |
OSSRH_PASSWORD | Password of Sonatype repository. |
GPG_PASSPHRASE | Passphrase for your default GPG Private Key. |
GPG_PRIVATE_KEY | optional GPG Private Key generated viagpg --armor --export-secret-keys YOUR_ID . If not provided, default key from your machine will be used. |
Configuration
Option | Description |
---|---|
mavenCliPath | Path to the Maven CLI. It must be executable by the calling process. |
mavenSettingsPath | Path to the Mavensettings.xml file. |
mavenRepoId | ID of the Maven server in thesettings.xml . |
mavenRepoUrl | URL of the Maven repository. |
android | Android configuration, see below. |
kmp | Kotlin Multiplatform configuration, see below. |
The Kotlin Multiplatform configuration is optional andfalse
by default.If your project isn't related to Android, you don't need this configuration andcan set the option tofalse
. If not, set the following nested elements:
distDirRegex
: pattern of distribution directory names.fileReplaceeRegex
: pattern of substring of distribution module names to be replaced to get the Android distribution file.fileReplacerStr
: string to be replaced in the module names to get the Android distribution file.
Example (without Android config)
targets: -name:mavenmavenCliPath:scripts/mvnw.cmdmavenSettingsPath:scripts/settings.xmlmavenRepoId:ossrhmavenRepoUrl:https://oss.sonatype.org/service/local/staging/deploy/maven2/android:false
Example (with Android config)
targets: -name:mavenmavenCliPath:scripts/mvnw.cmdmavenSettingsPath:scripts/settings.xmlmavenRepoId:ossrhmavenRepoUrl:https://oss.sonatype.org/service/local/staging/deploy/maven2/android:distDirRegex:/^sentry-android-.*$/fileReplaceeRegex:/\d\.\d\.\d(-SNAPSHOT)?/fileReplacerStr:release.aar
Example (with Kotlin Multiplatform config)
targets: -name:mavenmavenCliPath:scripts/mvnw.cmdmavenSettingsPath:scripts/settings.xmlmavenRepoId:ossrhmavenRepoUrl:https://oss.sonatype.org/service/local/staging/deploy/maven2/android:distDirRegex:/^sentry-android-.*$/fileReplaceeRegex:/\d\.\d\.\d(-SNAPSHOT)?/fileReplacerStr:release.aarkmp:rootDistDirRegex:/sentry-kotlin-multiplatform-[0-9]+.*$/appleDistDirRegex:/sentry-kotlin-multiplatform-(macos|ios|tvos|watchos).*/
Using thesymbol-collector
client, uploads native symbols.Thesymbol-collector
needs to be available in the path.
Configuration
Option | Description |
---|---|
serverEndpoint | optional The server endpoint. Defaults tohttps://symbol-collector.services.sentry.io . |
batchType | The batch type of the symbols to be uploaded. I.e:Android ,macOS ,iOS . |
bundleIdPrefix | The prefix of the bundle ID. The new version will be appended to the end of this prefix. |
Example
targets: -name:symbol-collectorincludeNames:/libsentry(-android)?\.so/batchType:AndroidbundleIdPrefix:android-ndk-
Pushes a new Dart or Flutter package topub.dev.
Because there isno automated way to login and obtain required tokens, you need to perform a valid release beforehand, for every package that you configure. This will open up your browser and use Google's OAuth to log you in, and generate an appropriate file with stored credentials.
Based on your environment, you can find this file at either$HOME/.pub-cache/credentials.json
or$HOME/Library/Application\ Support/dart/pub-credentials.json
for OSX and$HOME/.config/dart/pub-credentials.json
for Linux, depending on your setup.
For this target to work correctly, eitherdart
must be installed on the system or a validdartCliPath
must be provided.
Environment
Name | Description |
---|---|
PUBDEV_ACCESS_TOKEN | Value ofaccessToken obtained frompub-credentials.json |
PUBDEV_REFRESH_TOKEN | Value ofrefreshToken obtained frompub-credentials.json |
Configuration
Option | Description |
---|---|
dartCliPath | optional Path to the Dart CLI. It must be executable by the calling process. Defaults todart . |
packages | optional List of directories to be released, relative to the root. Useful when a single repository contains multiple packages. When skipped, root directory is assumed as the only package. |
skipValidation | optional Publishes the package without going through validation steps, such as analyzer & dependency checks. This is useful in particular situations when package maintainers know why the validation fails and wish to side step the issue. For example, there may be analyzer issues due to not following the current (latest) dart SDK recommendation because the package needs to maintain the package compatibility with an old SDK version. This option should be used with caution and only after testing and verifying the reported issue shouldn't affect the package. It is advisable to do an alpha pre-release to further reduce the chance of a potential negative impact. |
Example
targets: -name:pub-devpackages:uno:dos:tres:
Pushes a package to the Elixir / Erlang package managerHex.
Environment
mix
(bundled with theelixir
language) must be installed on the system.
Name | Description |
---|---|
HEX_API_KEY | API Key obtained from hex.pm account |
MIX_BIN | optional. Path to "mix" executable. Defaults tomix |
Configuration
none
Example
targets: -name:hex
Takes a tarball and pushes the unpacked contents to a git repository.
Environment
Name | Description |
---|---|
GITHUB_API_TOKEN | GitHub PAT that will be used for authentication when a therepositoryUrl host isgithub.com . |
Configuration
Option | Description |
---|---|
archive | Regular expression to match a.tgz file in the build artifacts. The content of the found file will be pushed to the git repository. Needs to match exactly one file. |
repositoryUrl | Url to the git remote git repository. Must use http or https protocol! (nogit@... ) |
branch | Which repository branch to push to. |
stripComponents | optional. How many leading path elements should be removed when unpacking the tarball. Default: 0 (seetar --strip-components option) |
createTag | optional. Whether to attach a tag to the created commit. The content of the tag is gonna be equal to the release version passed to craft ("NEW-VERSION"). Default:false |
Example
targets: -name:commit-on-git-repositoryarchive:/^sentry-deno-\d.*\.tgz$/repositoryUrl:https://github.com/getsentry/sentry-denostripComponents:1branch:maincreateTag:true
Uploads a module toPowerShell Gallery or another repositorysupported byPowerShellGet'sPublish-Module
.
The action looks for an artifact named<module>.zip
and extracts it to a temporary directory.The extracted directory is then published as a module.
Thepwsh
executablemust be installed on the system.
Name | Description | Default |
---|---|---|
POWERSHELL_API_KEY | required PowerShell Gallery API key | |
POWERSHELL_BIN | optional Path to PowerShell binary | pwsh |
Option | Description | Default |
---|---|---|
module | required Module name. | |
repository | optional Repository to publish the package to. | PSGallery |
targets: -name:powershellmodule:Sentry
Here is how you can integrate your GitHub project withcraft
:
Set up a workflow that builds your assets and runs your tests. Allow buildingrelease branches (their names follow
release/{VERSION}
by default,configurable throughreleaseBranchPrefix
).on:push:branches: -'release/**'
Use the official
actions/upload-artifact@v2
action to upload your assets.Here is an example config (step) of an archive job:-name:Archive Artifactsuses:actions/upload-artifact@v2with:name:${{ github.sha }}path:| ${{ github.workspace }}/*.tgz ${{ github.workspace }}/packages/tracing/build/** ${{ github.workspace }}/packages/**/*.tgz
A few important things to note:
- The name of the artifacts is very important and needs to be
name: ${{ github.sha }}
. Craft uses this as a unique id to fetch the artifacts. - Keep in mind that this action maintains the folder structure and zips everything together. Craft will download the zip and recursively walk it to find all assets.
- The name of the artifacts is very important and needs to be
Add
.craft.yml
configuration file to your project- List there all the targets you want to publish to
- Configure additional options (changelog management policy, tag prefix, etc.)
Add apre-release script to your project.
Get variousconfiguration tokens
Run
craft prepare <version> --publish
and profit!
Among other actions,craft prepare
runs an external, project-specific commandor script that is responsible for version bumping. By default, this scriptshould be located at:./scripts/bump-version.sh
. The command can be configuredby specifying thepreReleaseCommand
configuration option incraft.yml
.
The following requirements are on the script interface and functionality:
- The script should accept at least two arguments. Craft will pass the old ("from")version and the new ("to") version as the last two arguments, respectively.
- The script must replace all relevant occurrences of the old version stringwith the new one.
- The script must not commit the changes made.
- The script must not change the state of the git repository (e.g. changing branches)
Example
#!/bin/bash### Example of a version-bumping script for an NPM project.### Located at: ./scripts/bump-version.shset -euxOLD_VERSION="${1}"NEW_VERSION="${2}"# Do not tag and commit changes made by "npm version"export npm_config_git_tag_version=falsenpm version"${NEW_VERSION}"
Among other actions,craft publish
runs an external, project-specific commandor script that can do things like bumping the development version. By default,this script should be located at:./scripts/post-release.sh
. Unlike thepre-release command, this script is not mandatory so if the file does not exist,craft
will report this fact and then move along as usual. This command can beconfigured by specifyingpostReleaseCommand
configuration option incraft.yml
.
The following requirements are on the script interface and functionality:
- The script should accept at least two arguments. Craft will pass the old ("from")version and the new ("to") version as the last two arguments, respectively.
- The script is responsible for any and all
git
state management ascraft
willsimply exit after running this script as the final step. This means the scriptis responsible for committing and pushing any changes that it may have made.
Example
#!/bin/bash### Example of a dev-version-bumping script for a Python project### Located at: ./scripts/post-release.shset -euxOLD_VERSION="${1}"NEW_VERSION="${2}"# Ensure master branchgit checkout master# Advance the CalVer release by one-month and add the `.dev0` suffix./scripts/bump-version.sh''$(date -d"$(echo$NEW_VERSION| sed -e's/^\([0-9]\{2\}\)\.\([0-9]\{1,2\}\)\.[0-9]\+$/20\1-\2-1/') 1 month" +%y.%-m.0.dev0)# Only commit if there are changes, make sure to `pull --rebase` before pushing to avoid conflictsgit diff --quiet|| git commit -anm'meta: Bump new development version'&& git pull --rebase&& git push
Logging level forcraft
can be configured via setting theCRAFT_LOG_LEVEL
environment variable or using the--log-level
CLI flag.
Accepted values are:Fatal
,Error
,Warn
,Log
,Info
,Success
,Debug
,Trace
,Silent
,Verbose
Dry-run mode can be enabled via setting theCRAFT_DRY_RUN
environment variableto any truthy value (any value other thanundefined
,null
,""
,0
,false
, andno
). One may also use the--dry-run
CLI flag.
In dry-run mode no destructive actions will be performed (creating remotebranches, pushing tags, committing files, etc.)
Errors you encounter while using Craft can be sent to Sentry. To use thisfeature, addCRAFT_SENTRY_DSN
variable to your environment (or "craft"configuration file) that contains a Sentry project's DSN.
For example:
export CRAFT_SENTRY_DSN='https://1234@sentry.io/2345'
craft
obviously usescraft
for preparing and publishing new releases!
About
The universal Sentry release CLI 🚀