Craft Quick Start
This guide goes over the minimal setup needed to publish something via
publish
and craft
. This example will use a PyPI package.
The First Release
This guide assumes this thing has never been released before and has no existing tags. If that's not the case feel free to skip this section!
A tag must exist for the "beginning" of the repository due to a limitation -- it is recommended to tag the first commit of the repository before any meaningful history such that the first changelog includes useful context.
git tag 0.0.0 "$(git log -1 --reverse --format=%h)"
git push origin --tags
CI Requirements
First we need to ensure your repository responds to release/**
branches
and produces an artifact with the right name.
For our example repository that's done using push: branches
and an
artifact instruction.
Setting Up Craft
.craft.yml
We're just interested in making a GitHub release and a PyPI release so our
craft
configuration looks like:
minVersion: 0.28.1
targets:
- name: pypi
- name: github
scripts/bump-version.sh
This script will be invoked by craft
by default when bumping the version.
Since we're specifying version in setup.cfg
this is pretty easy to do with
sed
(we're ignoring $1
which contains the old version):
#!/usr/bin/env bash
set -euxo pipefail
sed -i "s/^version =.*/version = $2/" setup.cfg
Try the script out (but don't commit the changes):
$ ./scripts/bump-version.sh 0.0.0 1.0.0
+ sed -i 's/^version =.*/version = 1.0.0/' setup.cfg
$ git diff | grep '^[-+]'
--- a/setup.cfg
+++ b/setup.cfg
-version = 0.0.0
+version = 1.0.0
$ git checkout -- .
Nice!
.github/workflows/release.yml
This file is used to trigger the release from the GitHub UI.
You'll notice it uses secrets.GH_RELEASE_PAT
-- this should already be
available to your repository automatically!
name: Release
on:
workflow_dispatch:
inputs:
version:
description: Version to release
required: true
force:
description: Force a release even when there are release-blockers (optional)
required: false
jobs:
release:
runs-on: ubuntu-latest
name: "Release a new version"
steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.GH_RELEASE_PAT }}
fetch-depth: 0
- name: Prepare release
uses: getsentry/action-prepare-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GH_RELEASE_PAT }}
with:
version: ${{ github.event.inputs.version }}
force: ${{ github.event.inputs.force }}
Commit + PR
Commit those three files and make a pull request.
Here's an example PR and the follow-up to fix fetch-depth
.
Setting Up Permissions
Give the following teams access to your repository:
engineering
->write
release-bot
->elevated bot
You can do this self-service via the settings page of your repository:
https://github.com/getsentry/REPONAME_HERE/settings/access
Making Your First Release!
Navigate to the actions tab of your repository, locate the release workflow,
and create the first release! I used 1.0.0
as the first version.
This will create an issue in publish
which you'll need an approver to
add a label to.
[Optional] Using Multiple Craft Configs in a Repo
In some cases, we need to maintain multiple or diverging publishing configs in a repository. For example, when we have to maintain multiple major versions of a package we release (e.g. Sentry JavaScript SDK v7 and v8), where we added or removed artifacts or publishing targets.
By default, our publishing process is configured to take the craft.yml
config from the repo's default branch as the single source of truth for publishing.
You can opt your repo into using the config from a specific merge target branch (can be configured when triggering the Prepare Release Action) in two steps:
1. Release Preparation:
Add craft_config_from_merge_target: true
when calling getsentry/action-prepare-release
in your repo's release workflow:
# ...
jobs:
release:
runs-on: ubuntu-latest
name: 'Release a new version'
steps:
# ...
- name: Prepare release
uses: getsentry/action-prepare-release@v1
with:
# ...
craft_config_from_merge_target: true
2. Publish Configuration
Add the branch(es) you want to take the config from to the publish.yml
workflow in getsentry/publish
:
# ...
- name: Set target repo checkout branch
if: |
fromJSON(steps.inputs.outputs.result).repo == 'sentry-javascript' && fromJSON(steps.inputs.outputs.result).merge_target == 'v7'
Note: The branch(es) registered in this step MUST BE protected in the target repository. Disable direct pushing to the branch and require approvals for PRs before they can be merged.
Good job! Now you can let your craft configs diverge across the different merge target branches and the publishing process will pick up the correct config based on the branch you're setting as a merge target.