UNPKG

39.7 kBMarkdownView Raw
1<p align="center">
2 <img src="img/logo.svg" width="280">
3 <br />
4</p>
5
6# Craft: Universal Release Tool (And More) <!-- omit in toc -->
7
8[![Travis](https://img.shields.io/travis/getsentry/craft.svg)](https://travis-ci.org/getsentry/craft)
9[![GitHub release](https://img.shields.io/github/release/getsentry/craft.svg)](https://github.com/getsentry/craft/releases/latest)
10[![npm version](https://img.shields.io/npm/v/@sentry/craft.svg)](https://www.npmjs.com/package/@sentry/craft)
11[![license](https://img.shields.io/github/license/getsentry/craft.svg)](https://github.com/getsentry/craft/blob/master/LICENSE)
12
13`craft` is a command line tool that helps to automate and pipeline package releases. It suggests, and
14then enforces a specific workflow for managing release branches, changelogs, artifact publishing, etc.
15
16## Table of Contents <!-- omit in toc -->
17
18- [Installation](#installation)
19- [Usage](#usage)
20- [Caveats](#caveats)
21- [Global Configuration](#global-configuration)
22 - [Environment Files](#environment-files)
23- [Workflow](#workflow)
24 - [`craft prepare`: Preparing a New Release](#craft-prepare-preparing-a-new-release)
25 - [`craft publish`: Publishing the Release](#craft-publish-publishing-the-release)
26 - [Example](#example)
27- [Configuration File: `.craft.yml`](#configuration-file-craftyml)
28 - [GitHub project](#github-project)
29 - [Pre-release Command](#pre-release-command)
30 - [Release Branch Name](#release-branch-name)
31 - [Changelog Policies](#changelog-policies)
32 - [Minimal Version](#minimal-version)
33 - [Required Files](#required-files)
34- [Status Provider](#status-provider)
35- [Artifact Provider](#artifact-provider)
36 - [Using Github Actions with Github Artifact Provider](#using-github-actions-with-github-artifact-provider)
37- [Target Configurations](#target-configurations)
38 - [Per-target options](#per-target-options)
39 - [GitHub (`github`)](#github-github)
40 - [NPM (`npm`)](#npm-npm)
41 - [Python Package Index (`pypi`)](#python-package-index-pypi)
42 - [Homebrew (`brew`)](#homebrew-brew)
43 - [NuGet (`nuget`)](#nuget-nuget)
44 - [Rust Crates (`crates`)](#rust-crates-crates)
45 - [Google Cloud Storage (`gcs`)](#google-cloud-storage-gcs)
46 - [GitHub Pages (`gh-pages`)](#github-pages-gh-pages)
47 - [Sentry Release Registry (`registry`)](#sentry-release-registry-registry)
48 - [Cocoapods (`cocoapods`)](#cocoapods-cocoapods)
49 - [Docker (`docker`)](#docker-docker)
50 - [Ruby Gems Index (`gem`)](#ruby-gems-index-gem)
51- [Integrating Your Project with `craft`](#integrating-your-project-with-craft)
52- [Pre-release (Version-bumping) Script: Conventions](#pre-release-version-bumping-script-conventions)
53- [Development](#development)
54 - [Logging Level](#logging-level)
55 - [Dry-run Mode](#dry-run-mode)
56 - [Sentry Support](#sentry-support)
57 - [Releasing](#releasing)
58
59## Installation
60
61The tool is distributed as an NPM package and can be installed via `npm` or `yarn`:
62
63```bash
64yarn global add @sentry/craft
65
66# Or (not preferred):
67
68npm install -g @sentry/craft
69```
70
71## Usage
72
73```plain
74$ craft -h
75craft <command>
76
77Commands:
78 craft prepare NEW-VERSION 🚢 Prepare a new release branch
79 [aliases: p, prerelease, prepublish, prepare, release]
80 craft publish NEW-VERSION 🛫 Publish artifacts [aliases: pp, publish]
81
82Options:
83 --no-input Suppresses all user prompts [boolean] [default: false]
84 --dry-run Dry run mode: do not perform any real actions
85 [boolean] [default: false]
86 -v, --version Show version number [boolean]
87 -h, --help Show help [boolean]
88```
89
90## Caveats
91
92- When interacting with remote GitHub repositories, `craft` uses by default the
93 "origin" remote. If you have a different setup, set the `CRAFT_REMOTE`
94 environment variable.
95
96## Global Configuration
97
98Global configuration for `craft` can be done either by using environment variables
99or by adding values to a configuration file (see below).
100
101In either case, at least the following two values must be configured in order
102for craft to function properly:
103
104- `GITHUB_TOKEN`
105
106 Get your personal GitHub API token here: https://github.com/settings/tokens
107
108 The token only needs "repo" scope ("repo:status" and "public_repo" subscopes, to be even more precise).
109
110- `ZEUS_API_TOKEN`
111
112 You can generate your personal Zeus token here: https://zeus.ci/settings/token
113
114 Required only for `craft publish`.
115
116Additional configuration may be required when publishing to specific
117targets (e.g. `TWINE_USERNAME` and `TWINE_PASSWORD` for PyPI target).
118
119### Environment Files
120
121`craft` will read configuration variables (keys, tokens, etc.) from the
122following locations:
123
124- `$HOME/.craft.env`
125- `$PROJECT_DIR/.craft.env`
126- the shell's environment
127
128...where `$HOME` is the current user's home directory, and `$PROJECT_DIR` is the directory where `.craft.yml` is located.
129
130The above locations will be checked in the order specified above, with values
131found in one location overwriting anything found in previous locations. In other
132words, environment variables will take precedence over either configuration
133file, and the project-specific file will take precedence over the file in
134`$HOME`.
135
136The files must be written in shell (`sh`/`bash`) format. Leading `export` is allowed.
137
138Example:
139
140```sh
141# ~/.craft.env
142GITHUB_TOKEN=token123
143export NUGET_API_TOKEN=abcdefgh
144```
145
146## Workflow
147
148### `craft prepare`: Preparing a New Release
149
150This command will create a new release branch, check the changelog entries,
151run a version-bumping script, and push the new branch to GitHub.
152
153```plain
154craft prepare NEW-VERSION
155
156🚢 Prepare a new release branch
157
158Positionals:
159 NEW-VERSION The new version you want to release [string] [required]
160
161Options:
162 --no-input Suppresses all user prompts [boolean] [default: false]
163 --dry-run Dry run mode: do not perform any real actions
164 [boolean] [default: false]
165 --no-push Do not push the release branch [boolean] [default: false]
166 --no-git-checks Ignore local git changes and unsynchronized remotes
167 [boolean] [default: false]
168 --no-changelog Do not check for changelog entries [boolean] [default: false]
169 --publish Run "publish" right after "release"[boolean] [default: false]
170```
171
172### `craft publish`: Publishing the Release
173
174The command will find a release branch for the provided version (tag) and
175publish the existing artifacts from the configured artifact provider to selected targets.
176
177```plain
178craft publish NEW-VERSION
179
180🛫 Publish artifacts
181
182Positionals:
183 NEW-VERSION Version to publish [string] [required]
184
185Options:
186 --no-input Suppresses all user prompts [boolean] [default: false]
187 --dry-run Dry run mode: do not perform any real actions
188 [boolean] [default: false]
189 --target, -t Publish to this target
190 [string] [choices: "brew", "cocoapods", "crates", "gcs", "gh-pages", "github",
191 "npm", "nuget", "pypi", "registry", "all", "none"] [default: "all"]
192 --rev, -r Source revision to publish [string]
193 --no-merge Do not merge the release branch after publishing
194 [boolean] [default: false]
195 --keep-branch Do not remove release branch after merging it
196 [boolean] [default: false]
197 --keep-downloads Keep all downloaded files [boolean] [default: false]
198 --no-status-check Do not check for build status in Zeus
199 [boolean] [default: false]
200```
201
202### Example
203
204Let's imagine we want to release a new version of our package, and the version
205in question is `1.2.3`.
206
207We run `prepare` command first:
208
209`$ craft prepare 1.2.3`
210
211After some basic sanity checks this command creates a new release branch
212`release/1.2.3`, runs the version-bumping script (`scripts/bump-version.sh`),
213commits the changes made by the script, and then pushes the new branch to
214GitHub. At this point CI systems kick in, and the results of those builds, as
215well as built artifacts (binaries, NPM archives, Python wheels) are gradually
216uploaded to Zeus.
217
218To publish the built artifacts we run `publish`:
219
220`$ craft publish 1.2.3`
221
222This command will find our release branch (`release/1.2.3`), check the build
223status of the respective git revision in Zeus, and then publish available
224artifacts to configured targets (for example, to GitHub and NPM in the case of
225Craft).
226
227## Configuration File: `.craft.yml`
228
229Project configuration for `craft` is stored in `.craft.yml` configuration file,
230located in the project root.
231
232### GitHub project
233
234One of the required settings you need to specify is GitHub project parameters. For example:
235
236```yaml
237github:
238 owner: getsentry
239 repo: sentry-javascript
240```
241
242### Pre-release Command
243
244This command will run on your newly created release branch as part of `prepare`
245command. By default, it is set to `bash scripts/bump-version.sh`. Please refer
246to the [Pre-release version bumping script conventions section](#pre-release-version-bumping-script-conventions)
247for more details.
248
249```yaml
250preReleaseCommand: bash scripts/bump-version.sh
251```
252
253### Post-release Command
254
255This command will run after a successful `publish`. By default, it is set to
256`bash scripts/post-release.sh`. It will *not* error if the default script is
257missing though, as this may not be needed by all projects. Please refer to the
258[Post-release script conventions section](#post-release-script-conventions)
259for more details.
260
261```yaml
262postReleaseCommand: bash scripts/post-release.sh
263```
264
265### Release Branch Name
266
267This overrides the prefix for the release branch name. The full branch name used
268for a release is `{releaseBranchPrefix}/{version}`. The prefix defaults to
269`"release"`.
270
271```yaml
272releaseBranchPrefix: publish
273```
274
275### Changelog Policies
276
277`craft` can help you to maintain change logs for your projects. At the moment,
278`craft` supports two approaches: `simple`, and `auto` to changelog management.
279
280In `simple` mode, `craft prepare` will remind you to add a changelog entry to the
281changelog file (`CHANGELOG.md` by default).
282
283In `auto` mode, `craft prepare` will use the following logic:
284
2851. If there's already an entry for the given version, use that
2862. Else if there is an entry named `Unreleased`, rename that to the given
287 version
2883. Else, create a new section for the version and populate it with a default
289 text: `- No documented changes for this release.`
290
291**Configuration**
292
293| Option | Description |
294| ----------------- | ------------------------------------------------------------------------------------------ |
295| `changelog` | **optional**. Path to the changelog file. Defaults to `CHANGELOG.md` |
296| `changelogPolicy` | **optional**. Changelog management mode (`none`, `simple`, or `auto`). Defaults to `none`. |
297
298**Example (`simple`):**
299
300```yaml
301changelog: CHANGES
302changelogPolicy: simple
303```
304
305**Valid changelog example:**
306
307```text
308## 1.3.5
309
310* Removed something
311
312## 1.3.4
313
314* Added something
315```
316
317**Example (`auto`):**
318
319```yaml
320changelog: CHANGES
321changelogPolicy: auto
322```
323
324**Changelog with staged changes example:**
325
326```text
327## Unreleased
328
329* Removed something
330
331## 1.3.4
332
333* Added something
334```
335
336Additionally, `.craft.yml` is used for listing targets where you want to
337publish your new release.
338
339### Minimal Version
340
341It is possible to specify minimal `craft` version that is required to work with
342your configuration.
343
344**Example:**
345
346```yaml
347minVersion: '0.5.0'
348```
349
350### Required Files
351
352You can provide a list of patterns for files that _have to be_ available before
353proceeding with publishing. In other words, for every pattern in the given list
354there has to be a file present that matches that pattern. This might be helpful
355to ensure that we're not trying to do an incomplete release.
356
357**Example:**
358
359```yaml
360requireNames:
361 - /^sentry-craft.*\.tgz$/
362 - /^gh-pages.zip$/
363```
364
365## Status Provider
366
367You can configure which status providers `craft` will use to check for your build status.
368By default, it will take Zeus but you can also use GitHub directly.
369This is helpful if you don't want to rely on Zeus for asking if you build is green or not.
370
371**Configuration**
372
373| Option | Description |
374| -------- | -------------------------------------------------------------------------------------------------- |
375| `name` | Name of the status provider: either `zeus` (default) or `github` |
376| `config` | In case of `github`: may include `contexts` key that contains a list of required contexts (checks) |
377
378**Example:**
379
380```yaml
381statusProvider:
382 name: github
383 config:
384 contexts:
385 - Travis CI - Branch
386```
387
388## Artifact Provider
389
390You can configure which artifact providers `craft` will use to fetch artifacts from.
391By default, Zeus is used, but in case you don't need use any artifacts in your
392project, you can set it to `none`.
393
394**Configuration**
395
396| Option | Description |
397| ------ | -------------------------------------------------------------------------- |
398| `name` | Name of the artifact provider: can be `zeus` (default), `github` or `none` |
399
400**Example:**
401
402```yaml
403artifactProvider:
404 name: none
405```
406
407### Using Github Actions with Github Artifact Provider
408
409When using Github Action you can use the Github Artifact Provider for managing your release artifacts.
410The way it works is simple, use the official GHA `actions/upload-artifact@v2` action to upload your assets.
411Craft can work with them and use it instead of Zeus.
412Here is an example config (step) of an archive job:
413
414```yaml
415- name: Archive Artifacts
416 uses: actions/upload-artifact@v2
417 with:
418 name: ${{ github.sha }}
419 path: |
420 ${{ github.workspace }}/*.tgz
421 ${{ github.workspace }}/packages/tracing/build/**
422 ${{ github.workspace }}/packages/**/*.tgz
423```
424
425A few important things to note:
426- 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.
427- 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.
428
429
430## Target Configurations
431
432The configuration specifies which release targets to run for the repository. To
433run more targets, list the target identifiers under the `targets` key in
434`.craft.yml`.
435
436**Example:**
437
438```yaml
439targets:
440 - name: github
441 - name: npm
442```
443
444### Per-target options
445
446The following options can be applied to every target individually:
447
448| Name | Description |
449| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
450| `includeNames` | **optional**. Regular expression: only matched files will be processed by the target. There is one special case that `includeNames` supports, if your build doesn't any artifacts you can write `includeNames: /none/`, this will skip the check for artifacts towards Zeus entirely. |
451| `excludeNames` | **optional**. Regular expression: the matched files will be skipped by the target. Matching is performed after testing for inclusion (via `includeNames`). |
452
453If neither option is included, all artifacts for the release will be processed by the target.
454
455**Example:**
456
457```yaml
458targets:
459 - name: github
460 includeNames: /^.*\.exe$/
461 excludeNames: /^test.exe$/
462```
463
464### GitHub (`github`)
465
466Create a release on Github. If a Markdown changelog is present in the
467repository, this target tries to read the release name and description from the
468changelog. Otherwise, defaults to the tag name and tag's commit message.
469
470If `previewReleases` is set to `true` (which is the default), the release
471created on GitHub will be marked as a pre-release version if the release name
472contains any one of `preview`, `pre`, `rc`, `dev`,`alpha`, `beta`, `unstable`,
473`a`, or `b`.
474
475**Environment**
476
477| Name | Description |
478| ------------------ | ------------------------------------------------------------------ |
479| `GITHUB_TOKEN` | Personal GitHub API token (see https://github.com/settings/tokens) |
480
481**Configuration**
482
483| Option | Description |
484| ----------------- | -------------------------------------------------------------------------------------------- |
485| `tagPrefix` | **optional**. Prefix for new git tags (e.g. "v"). Empty by default. |
486| `previewReleases` | **optional**. Automatically detect and create preview releases. `true` by default. |
487| `annotatedTag` | **optional**. Creates an annotated tag, set to false for lightweight tag. `true` by default. |
488
489**Example:**
490
491```yaml
492targets:
493 - name: github
494 tagPrefix: v
495 previewReleases: false
496 annotatedTag: false
497```
498
499### NPM (`npm`)
500
501Releases an NPM package to the public registry. This requires a package tarball
502generated by `npm pack` in the artifacts. The file will be uploaded to the
503registry with `npm publish`, or with `yarn publish` if `npm` is not found. This
504requires NPM to be authenticated with sufficient permissions to publish the package.
505
506**Environment**
507
508The `npm` utility must be installed on the system.
509
510| Name | Description |
511| ------------------- | ------------------------------------------------------------------- |
512| `NPM_TOKEN` | An [automation token][npm-automation-token] allowed to publish. |
513| `NPM_BIN` | **optional**. Path to the npm executable. Defaults to `npm` |
514| `YARN_BIN` | **optional**. Path to the yarn executable. Defaults to `yarn` |
515| `CRAFT_NPM_USE_OTP` | **optional**. If set to "1", you will be asked for an OTP (for 2FA) |
516
517[npm-automation-token]: https://docs.npmjs.com/creating-and-viewing-access-tokens
518
519**Configuration**
520
521| Option | Description |
522| -------- | -------------------------------------------------------------------------------- |
523| `access` | **optional**. Visibility for scoped packages: `restricted` (default) or `public` |
524
525**Example**
526
527```yaml
528targets:
529 - name: npm
530 access: public
531```
532
533### Python Package Index (`pypi`)
534
535Uploads source dists and wheels to the Python Package Index via [twine](https://pypi.org/project/twine/).
536The source code bundles and/or wheels must be in the release assets.
537
538**Environment**
539
540The `twine` Python package must be installed on the system.
541
542| Name | Description |
543| ---------------- | ----------------------------------------------------- |
544| `TWINE_USERNAME` | User name for PyPI with access rights for the package |
545| `TWINE_PASSWORD` | Password for the PyPI user |
546| `TWINE_BIN` | **optional**. Path to twine. Defaults to `twine` |
547
548**Configuration**
549
550_none_
551
552**Example**
553
554```yaml
555targets:
556 - name: pypi
557```
558
559### Homebrew (`brew`)
560
561Pushes a new or updated homebrew formula to a brew tap repository. The formula
562is committed directly to the master branch of the tap on GitHub, therefore the
563bot needs rights to commit to `master` on that repository. Therefore, formulas
564on `homebrew/core` are not supported, yet.
565
566The tap is configured with the mandatory `tap` parameter in the same format as
567the `brew` utility. A tap `<org>/<name>` will expand to the GitHub repository
568`github.com:<org>/homebrew-<name>`.
569
570The formula contents are given as configuration value and can be interpolated
571with Mustache template syntax (`{{ variable }}`). The interpolation context
572contains the following variables:
573
574- `version`: The new version
575- `revision`: The tag's commit SHA
576- `checksums`: A map containing sha256 checksums for every release asset. Use
577 the full filename to access the sha, e.g. `checksums.MyProgram-x86`
578
579**Environment**
580
581| Name | Description |
582| ------------------ | ------------------------------------------------------------------ |
583| `GITHUB_TOKEN` | Personal GitHub API token (seeh ttps://github.com/settings/tokens) |
584
585**Configuration**
586
587| Option | Description |
588| ---------- | ------------------------------------------------------------------ |
589| `tap` | The name of the homebrew tap used to access the GitHub repo |
590| `template` | The template for contents of the formula file (ruby code) |
591| `formula` | **optional**. Name of the formula. Defaults to the repository name |
592| `path` | **optional**. Path to store the formula in. Defaults to `Formula` |
593
594**Example**
595
596```yaml
597targets:
598 - name: brew
599 tap: octocat/tools # Expands to github.com:octocat/homebrew-tools
600 formula: myproject # Creates the file myproject.rb
601 path: HomebrewFormula # Creates the file in HomebrewFormula/
602 template: >
603 class MyProject < Formula
604 desc "This is a test for homebrew formulae"
605 homepage "https://github.com/octocat/my-project"
606 url "https://github.com/octocat/my-project/releases/download/{{version}}/binary-darwin"
607 version "{{version}}"
608 sha256 "{{checksums.binary-darwin}}"
609
610 def install
611 mv "binary-darwin", "myproject"
612 bin.install "myproject"
613 end
614 end
615```
616
617### NuGet (`nuget`)
618
619Uploads packages to [NuGet](https://www.nuget.org/) via [.NET Core](https://github.com/dotnet/core).
620By default, `craft` publishes all packages with `.nupkg` extension.
621
622**Environment**
623
624The `dotnet` tool must be available on the system.
625
626| Name | Description |
627| ------------------ | ---------------------------------------------------------------- |
628| `NUGET_API_TOKEN` | NuGet personal API token (https://www.nuget.org/account/apikeys) |
629| `NUGET_DOTNET_BIN` | **optional**. Path to .NET Core. Defaults to `dotnet` |
630
631**Configuration**
632
633_none_
634
635**Example**
636
637```yaml
638targets:
639 - name: nuget
640```
641
642### Rust Crates (`crates`)
643
644Publishes a single Rust package or entire workspace on the public crate registry
645([crates.io](https://crates.io)). If the workspace contains multiple crates,
646they are published in an order depending on their dependencies.
647
648**Environment**
649
650"cargo" must be installed and configured on the system.
651
652| Name | Description |
653| ----------------- | ------------------------------------------------- |
654| `CRATES_IO_TOKEN` | The access token to the crates.io account |
655| `CARGO_BIN` | **optional**. Path to cargo. Defaults to `cargo`. |
656
657**Configuration**
658
659| Option | Description |
660| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
661| `noDevDeps` | **optional**. Strips `devDependencies` from crates before publishing. This is useful if a workspace crate uses circular dependencies for docs. Requires [`cargo-hack`](https://github.com/taiki-e/cargo-hack#readme) installed. Defaults to `false`. |
662
663**Example**
664
665```yaml
666targets:
667 - name: crates
668 noDevDeps: false
669```
670
671### Google Cloud Storage (`gcs`)
672
673Uploads artifacts to a bucket in Google Cloud Storage.
674
675The bucket paths (`paths`) can be interpolated using Mustache syntax (`{{ variable }}`). The interpolation context contains the following variables:
676
677- `version`: The new project version
678- `revision`: The SHA revision of the new version
679
680**Environment**
681
682Google Cloud credentials can be provided using either of the following two environment variables.
683
684| Name | Description |
685| ----------------------------- | ------------------------------------------------------------------------ |
686| `CRAFT_GCS_TARGET_CREDS_PATH` | Local filesystem path to Google Cloud credentials (service account file) |
687| `CRAFT_GCS_TARGET_CREDS_JSON` | Full service account file contents, as a JSON string |
688
689If defined, `CRAFT_GCS_TARGET_CREDS_JSON` will be preferred over `CRAFT_GCS_TARGET_CREDS_PATH`.
690
691_Note:_ `CRAFT_GCS_TARGET_CREDS_JSON` and `CRAFT_GCS_TARGET_CREDS_PATH` were formerly called `CRAFT_GCS_CREDENTIALS_JSON` and `CRAFT_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.
692
693**Configuration**
694
695| Option | Description |
696| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
697| `bucket` | The name of the GCS bucket where artifacts are uploaded. |
698| `paths` | A list of path objects that represent bucket paths. |
699| `paths.path` | Template-aware bucket path, which can contain `{{ version }}` and/or `{{ revision }}`. |
700| `paths.metadata` | **optional** [Metadata](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request_properties_JSON) for uploaded files. By default, it sets `Cache-Control` to `"public, max-age=300"`. |
701
702**Example**
703
704```yaml
705targets:
706 - name: gcs
707 bucket: bucket-name
708 paths:
709 - path: release/{{version}}/download
710 metadata:
711 cacheControl: `public, max-age=3600`
712 - path: release/{{revision}}/platform/package
713```
714
715### GitHub Pages (`gh-pages`)
716
717Extracts an archive with static assets and pushes them to the specified git
718branch (`gh-pages` by default). Thus, it can be used to publish documentation
719or any other assets to [GitHub Pages](https://pages.github.com/), so they will be later automatically rendered
720by GitHub.
721
722By default, this target will look for an artifact named `gh-pages.zip`, extract it,
723and commit its contents to `gh-pages` branch.
724
725_WARNING!_ The destination branch will be completely overwritten by the contents
726of the archive.
727
728**Environment**
729
730_none_
731
732**Configuration**
733
734| Option | Description |
735| ------------- | --------------------------------------------------------------------------------------- |
736| `branch` | **optional** The name of the branch to push the changes to. `gh-pages` by default. |
737| `githubOwner` | **optional** GitHub project owner, defaults to the value from the global configuration. |
738| `githubRepo` | **optional** GitHub project name, defaults to the value from the global configuration. |
739
740**Example**
741
742```yaml
743targets:
744 - name: gh-pages
745 branch: gh-pages
746```
747
748### Sentry Release Registry (`registry`)
749
750The target will update the Sentry release registry repo(https://github.com/getsentry/sentry-release-registry/) with the latest version of the
751project `craft` is used with. The release registry repository will be checked out
752locally, and then the new version file will be created there, along with the necessary
753symbolic links.
754
755Two package types are supported: "sdk" and "app". Type "sdk" means that the package
756is uploaded to one of the public registries (PyPI, NPM, Nuget, etc.), and that
757the corresponding package directory can be found inside "packages" directory of the
758release regsitry. Type "app" indicates that the package's version files are located
759in "apps" directory of the registry.
760
761**Environment**
762
763_none_
764
765**Configuration**
766
767| Option | Description |
768| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
769| `type` | Type of the package: can be "sdk" or "app". |
770| `config.canonical` | Canonical name of the package that includes package registry name (e.g. NPM, PyPI) and the full package name. |
771| `urlTemplate` | **optional** URL template that will be used to generate download links for "app" package type. |
772| `linkPrereleases` | **optional** Update package versions even if the release is a preview release, "false" by default. |
773| `checksums` | **optional** A list of checksums that will be computed for matched files (see `includeNames`). Every checksum entry is an object with two attributes: algorithm (one of "sha256", "sha384", and "sha512) and format ("base64" and "hex"). |
774| `onlyIfPresent` | **optional** A file pattern. The target will be executed _only_ when the matched file is found. |
775
776**Example**
777
778```yaml
779targets:
780 - name: registry
781 type: sdk
782 config:
783 canonical: 'npm:@sentry/browser'
784
785 - name: registry
786 type: app
787 urlTemplate: 'https://example.com/{{version}}/{{file}}'
788 config:
789 canonical: 'npm:@sentry/browser'
790 checksums:
791 - algorithm: sha256
792 format: hex
793```
794
795### Cocoapods (`cocoapods`)
796
797Pushes a new podspec to the central cocoapods repository. The Podspec is fetched
798from the Github repository with the revision that is being released. No release
799assets are required for this target.
800
801**Environment**
802
803The `cocoapods` gem must be installed on the system.
804
805| Name | Description |
806| ----------------------- | ----------------------------------------- |
807| `COCOAPODS_TRUNK_TOKEN` | The access token to the cocoapods account |
808| `COCOAPODS_BIN` | **optional**. Path to `pod` executable. |
809
810**Configuration**
811
812| Option | Description |
813| ---------- | ------------------------------------------ |
814| `specPath` | Path to the Podspec file in the repository |
815
816**Example**
817
818```yaml
819targets:
820 - name: cocoapods
821 specPath: MyProject.podspec
822```
823
824### Docker (`docker`)
825
826Pulls an existing source image tagged with the revision SHA, and then pushed it
827to a new target tagged with the released version. No release
828assets are required for this target except for the source image at the provided
829source image location so it would be a good idea to add a status check that
830ensures the source image exists, otherwise `craft publish` will fail at the
831`docker pull` step, causing an interrupted publish. This is an issue for other,
832non-idempotent targets, not for the Docker target.
833
834**Environment**
835
836`docker` executable (or something equivalent) must be installed on the system.
837
838| Name | Description |
839| ----------------- | ------------------------------------------ |
840| `DOCKER_USERNAME` | The username for the Docker registry. |
841| `DOCKER_PASSWORD` | The personal access token for the account. |
842| `DOCKER_BIN` | **optional**. Path to `docker` executable. |
843
844**Configuration**
845
846| Option | Description |
847| -------------- | ------------------------------------------------------------------------ |
848| `source` | Path to the source Docker image to be pulled |
849| `sourceFormat` | Format for the source image name. Default: `{{{source}}}:{{{revision}}}` |
850| `target` | Path to the target Docker image to be pushed |
851| `targetFormat` | Format for the target image name. Default: `{{{target}}}:{{{version}}}` |
852
853**Example**
854
855```yaml
856targets:
857 - name: docker
858 source: us.gcr.io/sentryio/craft
859 target: getsentry/craft
860# Optional but strongly recommended
861statusProvider:
862 name: github
863 config:
864 contexts:
865 - Travis CI - Branch # or whatever builds and pushes your source image
866```
867
868### Ruby Gems Index (`gem`)
869
870Pushes a gem [Ruby Gems](https://rubygems.org).
871It also requires you to be logged in with `gem login`.
872
873**Environment**
874
875`gem` must be installed on the system.
876
877| Name | Description |
878| --------- | --------------------------------------------------------- |
879| `GEM_BIN` | **optional**. Path to "gem" executable. Defaults to `gem` |
880
881**Configuration**
882
883_none_
884
885**Example**
886
887```yaml
888targets:
889 - name: gem
890```
891
892## Integrating Your Project with `craft`
893
894Here is how you can integrate your GitHub project with `craft`:
895
896- Enable your project in Zeus: https://zeus.ci/settings/github/repos
897- Configure your CI systems (Travis, AppVeyor, etc.) to send build artifacts to Zeus
898 - Allow building release branches (their names follow `release/{VERSION}` by
899 default, configurable through `releaseBranchPrefix`)
900 - Add ZEUS_HOOK_BASE as protected to CI environment
901- Add `.craft.yml` configuration file to your project
902 - List there all the targets you want to publish to
903 - Configure additional options (changelog management policy, tag prefix, etc.)
904- Add a [pre-release script](#pre-release-version-bumping-script-conventions) to your project.
905- Get various [configuration tokens](#global-configuration)
906- Start releasing!
907
908## Pre-release (Version-bumping) Script: Conventions
909
910Among other actions, `craft prepare` runs an external, project-specific command
911or script that is responsible for version bumping. By default, this script
912should be located at: `./scripts/bump-version.sh`. The command can be configured
913by specifying the `preReleaseCommand` configuration option in `craft.yml`.
914
915The following requirements are on the script interface and functionality:
916
917- The script should accept at least two arguments. Craft will pass the old ("from")
918 version and the new ("to") version as the last two arguments, respectively.
919- The script must replace all relevant occurrences of the old version string
920 with the new one.
921- The script must not commit the changes made.
922- The script must not change the state of the git repository (e.g. changing branches)
923
924**Example**
925
926```bash
927#!/bin/bash
928### Example of a version-bumping script for an NPM project.
929### Located at: ./scripts/bump-version.sh
930set -eux
931OLD_VERSION="${1}"
932NEW_VERSION="${2}"
933
934# Do not tag and commit changes made by "npm version"
935export npm_config_git_tag_version=false
936npm version "${NEW_VERSION}"
937```
938
939## Post-release Script: Conventions
940
941Among other actions, `craft publish` runs an external, project-specific command
942or script that can do things like bumping the development version. By default,
943this script should be located at: `./scripts/post-release.sh`. Unlike the
944pre-release command, this script is not mandatory so if the file does not exist,
945`craft` will report this fact and then move along as usual. This command can be
946configured by specifying `postReleaseCommand` configuration option in `craft.yml`.
947
948The following requirements are on the script interface and functionality:
949
950- The script should accept at least two arguments. Craft will pass the old ("from")
951 version and the new ("to") version as the last two arguments, respectively.
952- The script is responsible for any and all `git` state management as `craft` will
953 simply exit after running this script as the final step. This means the script
954 is responsible for committing and pushing any changes that it may have made.
955
956**Example**
957
958```bash
959#!/bin/bash
960### Example of a dev-version-bumping script for a Python project
961### Located at: ./scripts/post-release.sh
962set -eux
963OLD_VERSION="${1}"
964NEW_VERSION="${2}"
965
966# Ensure master branch
967git checkout master
968# Advance the CalVer release by one-month and add the `.dev0` suffix
969./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)
970# Only commit if there are changes, make sure to `pull --rebase` before pushing to avoid conflicts
971git diff --quiet || git commit -anm 'meta: Bump new development version' && git pull --rebase && git push
972```
973
974## Development
975
976### Logging Level
977
978Logging level for `craft` can be configured via setting `CRAFT_LOG_LEVEL`
979environment variable.
980
981Accepted values are: `debug`, `success` (default), `info`, `warn`, `error`.
982
983### Dry-run Mode
984
985Dry-run mode can be enabled via setting `DRY_RUN` environment variable to any
986truthy value (any value other than `unset`, `""`, `0`, `false` and `no`).
987
988In dry-run mode no destructive actions will be performed (creating branches,
989pushing tags, committing files, etc.)
990
991### Sentry Support
992
993Errors you encounter while using Craft can be sent to Sentry. To use this feature,
994add `CRAFT_SENTRY_DSN` variable to your environment (or "craft" configuration file) that
995contains a Sentry project's DSN.
996
997For example:
998
999```bash
1000export CRAFT_SENTRY_DSN='https://1234@sentry.io/2345'
1001```
1002
1003### Releasing
1004
1005`craft` obviously uses `craft` for preparing and publishing new releases!