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