Configuration
Project configuration for Craft is stored in .craft.yml in the project root.
GitHub Project
Craft tries to determine GitHub repo information from the local git repo. You can also hard-code it:
github: owner: getsentry repo: sentry-javascriptPre-release Command
This command runs on your release branch as part of craft prepare. Default: bash scripts/bump-version.sh.
preReleaseCommand: bash scripts/bump-version.shThe script should:
- Accept old and new version as the last two arguments
- Replace version occurrences
- Not commit changes
- Not change git state
Example script:
#!/bin/bashset -euxOLD_VERSION="${1}"NEW_VERSION="${2}"
export npm_config_git_tag_version=falsenpm version "${NEW_VERSION}"Post-release Command
This command runs after a successful craft publish. Default: bash scripts/post-release.sh.
postReleaseCommand: bash scripts/post-release.shRelease Branch Name
Override the release branch prefix. Default: release.
releaseBranchPrefix: publishFull branch name: {releaseBranchPrefix}/{version}
Changelog Policies
Craft supports simple and auto changelog management modes.
Simple Mode
Reminds you to add a changelog entry:
changelog: CHANGESOr with options:
changelog: filePath: CHANGES.md policy: simpleAuto Mode
Automatically generates changelog from commits:
changelog: policy: autoAuto mode uses .github/release.yml to categorize PRs. This file follows GitHub’s release.yml format with Craft-specific extensions.
Craft Extensions to release.yml
Craft extends GitHub’s format with two additional fields:
| Field | Description |
|---|---|
commit_patterns | Array of regex patterns to match commit/PR titles (in addition to labels) |
semver | Version bump type for auto-versioning: major, minor, or patch |
Default Configuration
If .github/release.yml doesn’t exist, Craft uses these defaults based on Conventional Commits:
changelog: exclude: labels: - skip-changelog categories: - title: Breaking Changes 🛠 commit_patterns: - "^(?<type>\\w+(?:\\((?<scope>[^)]+)\\))?!:\\s*)" semver: major - title: New Features ✨ commit_patterns: - "^(?<type>feat(?:\\((?<scope>[^)]+)\\))?!?:\\s*)" semver: minor - title: Bug Fixes 🐛 commit_patterns: - "^(?<type>fix(?:\\((?<scope>[^)]+)\\))?!?:\\s*)" - "^Revert \"" semver: patch - title: Documentation 📚 commit_patterns: - "^(?<type>docs?(?:\\((?<scope>[^)]+)\\))?!?:\\s*)" semver: patch - title: Build / dependencies / internal 🔧 commit_patterns: - "^(?<type>(?:build|refactor|meta|chore|ci|ref|perf)(?:\\((?<scope>[^)]+)\\))?!?:\\s*)" semver: patchExample Configuration
changelog: categories: - title: Features labels: - enhancement commit_patterns: - "^(?<type>feat(?:\\((?<scope>[^)]+)\\))?!?:\\s*)" semver: minor - title: Bug Fixes labels: - bug commit_patterns: - "^(?<type>fix(?:\\((?<scope>[^)]+)\\))?!?:\\s*)" semver: patchCustom Changelog Entries from PR Descriptions
By default, the changelog entry for a PR is generated from its title. However, PR authors can override this by adding a “Changelog Entry” section to the PR description. This allows for more detailed, user-facing changelog entries without cluttering the PR title.
To use this feature, add a markdown heading (level 2 or 3) titled “Changelog Entry” to your PR description, followed by the desired changelog text:
### Description
Add `foo` function, and add unit tests to thoroughly check all edge cases.
### Changelog Entry
Add a new function called `foo` which prints "Hello, world!"
### Issues
Closes #123The text under “Changelog Entry” will be used verbatim in the changelog instead of the PR title. If no such section is present, the PR title is used as usual.
Advanced Features
-
Multiple Entries: If you use multiple top-level bullet points in the “Changelog Entry” section, each bullet will become a separate changelog entry:
### Changelog Entry- Add OAuth2 authentication- Add two-factor authentication- Add session management -
Nested Content: Indented bullets (4+ spaces or tabs) are preserved as nested content under their parent entry:
### Changelog Entry- Add authentication system- OAuth2 support- Two-factor authentication- Session managementThis will generate:
- Add authentication system by @user in [#123](url)- OAuth2 support- Two-factor authentication- Session managementNote: Nested items do NOT get author/PR attribution - only the top-level entry does.
-
Plain Text: If no bullets are used, the entire content is treated as a single changelog entry. Multi-line text is automatically joined with spaces to ensure valid markdown output.
-
Content Isolation: Only content within the “Changelog Entry” section is included in the changelog. Other sections (Description, Issues, etc.) are ignored.
Scope Grouping
Changes are automatically grouped by scope (e.g., feat(api): groups under “Api”):
changelog: policy: auto scopeGrouping: true # defaultScope headers are only shown for scopes with more than one entry. Entries without a scope are listed at the bottom of each category section without a sub-header.
Example output with scope grouping:
### New Features
#### Api
- Add user endpoint by @alice in [#1](https://github.com/...)- Add auth endpoint by @bob in [#2](https://github.com/...)
#### Ui
- Add dashboard by @charlie in [#3](https://github.com/...)
- General improvement by @dave in [#4](https://github.com/...)Title Stripping (Default Behavior)
By default, conventional commit prefixes are stripped from changelog entries.
The type (e.g., feat:) is removed, and the scope is preserved when entries
aren’t grouped under a scope header.
This behavior is controlled by named capture groups in commit_patterns:
(?<type>...)- The type prefix to strip (includes type, scope, and colon)(?<scope>...)- Scope to preserve when not under a scope header
| Original Title | Scope Header | Displayed Title |
|---|---|---|
feat(api): add endpoint | Yes (Api) | Add endpoint |
feat(api): add endpoint | No | (api) Add endpoint |
feat: add endpoint | N/A | Add endpoint |
To disable stripping, provide custom patterns using non-capturing groups:
commit_patterns: - "^feat(?:\\([^)]+\\))?!?:" # No named groups = no strippingSkipping Changelog Entries
You can exclude PRs or commits from the changelog in several ways:
Magic Word
Add #skip-changelog anywhere in your commit message or PR body:
chore: Update dependencies
#skip-changelogSkip Label
PRs with the skip-changelog label are automatically excluded.
Configuration
Configure exclusions in .github/release.yml:
changelog: exclude: labels: - skip-changelog - dependencies authors: - dependabot[bot] - renovate[bot]Configuration Options
| Option | Description |
|---|---|
changelog | Path to changelog file (string) OR configuration object |
changelog.filePath | Path to changelog file. Default: CHANGELOG.md |
changelog.policy | Mode: none, simple, or auto. Default: none |
changelog.scopeGrouping | Enable scope-based grouping. Default: true |
Versioning
Configure default versioning behavior:
versioning: policy: auto # auto, manual, or calverVersioning Policies
| Policy | Description |
|---|---|
auto | Analyze commits to determine version bump (default when using craft prepare auto) |
manual | Require explicit version argument |
calver | Use calendar-based versioning |
Calendar Versioning (CalVer)
For projects using calendar-based versions:
versioning: policy: calver calver: format: "%y.%-m" # e.g., 24.12 for December 2024 offset: 14 # Days to look back for date calculationFormat supports:
%y- 2-digit year%m- Zero-padded month%-m- Month without padding
Minimal Version
Require a minimum Craft version:
minVersion: '0.5.0'Required Files
Ensure specific artifacts exist before publishing:
requireNames: - /^sentry-craft.*\.tgz$/ - /^gh-pages.zip$/Status Provider
Configure build status checks:
statusProvider: name: github config: contexts: - Travis CI - BranchArtifact Provider
Configure where to fetch artifacts from:
artifactProvider: name: github # or 'gcs' or 'none'Targets
List release targets in your configuration:
targets: - name: npm - name: github - name: registry id: browser type: sdk onlyIfPresent: /^sentry-browser-.*\.tgz$/See Target Configurations for details on each target.
Per-target Options
These options apply to all targets:
| Option | Description |
|---|---|
includeNames | Regex: only matched files are processed |
excludeNames | Regex: matched files are skipped |
id | Unique ID for the target (use with -t target[id]) |
Example:
targets: - name: github includeNames: /^.*\.exe$/ excludeNames: /^test.exe$/