Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/changelog-guard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Changelog Guard
Comment thread
jamescrosswell marked this conversation as resolved.

on:
pull_request:
branches:
- main
- release/**

permissions:
contents: read

jobs:
no-manual-unreleased-entries:
name: No manual "## Unreleased" entries
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Verify CHANGELOG.md has no manual "## Unreleased" entries
run: ./scripts/verify-changelog.sh
Comment thread
sentry[bot] marked this conversation as resolved.
6 changes: 0 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
# Changelog

## Unreleased

### Features ✨

- feat: Add exponential backoff and log deduplication to Spotlight transport by @mattico in [#5025](https://github.com/getsentry/sentry-dotnet/pull/5025)

## 6.6.0

### Features ✨
Expand Down
23 changes: 3 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,28 +109,11 @@ To do that, run the build locally (i.e: `./build.sh` or `build.cmd`) and commit
## Changelog

We'd love for users to update the SDK everytime and as soon as we make a new release. But in reality most users rarely update the SDK.
To help users see value in updating the SDK, we maintain a changelog file with entries split between two headings:
To help users see value in updating the SDK, we maintain a changelog file with entries split between headings such as `### Features` and `### Fixes`.

1. `### Features`
2. `### Fixes`
**Do not edit `CHANGELOG.md` manually.** The changelog is generated automatically at release time by [craft](https://github.com/getsentry/craft) (`changelogPolicy: auto` in `.craft.yml`) from the pull requests merged since the previous release. Entries are categorized from your [commit message / PR title](https://develop.sentry.dev/engineering-practices/commit-messages/) (e.g. a `feat:` PR becomes a Feature, a `fix:` PR becomes a Fix), so there's nothing to add by hand.
Comment thread
jamescrosswell marked this conversation as resolved.

We add the heading in the first PR that's adding either a feature or fixes in the current release.
After a release, the [changelog file will contain only the last release entries](https://github.com/getsentry/sentry-dotnet/blob/main/CHANGELOG.md).

When you open a PR in such cases, you need to add a heading 2 named `## Unreleased`, which is replaced during release with the version number chosen.
Below that, you'll add heading 3 mentioned above. For example, if you're adding a feature "Attach screenshots when capturing errors on WPF", right after a release, you'd add to the changelog:

```
## Unreleased

### Features

- Attach screenshots when capturing errors on WPF (#PR number)
```

There's a GitHub action check to verify if an entry was added.
If the entry isn't a user-facing change, you can skip the verification with either `#skip-changelog` written to the PR description or the `skip-changelog` label added to the PR.
The bot writes a comment in the PR with a suggestion entry to the changelog based on the PR title.
If the change isn't user-facing and you'd rather it not appear in the changelog at all, add the `skip-changelog` label to the PR or write `#skip-changelog` in the PR description.

## Naming tests

Expand Down
57 changes: 57 additions & 0 deletions scripts/verify-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
#
# Verifies that CHANGELOG.md has no content under an "## Unreleased" heading.
#
# This repository generates its changelog automatically at release time via
# craft (`changelogPolicy: auto` in .craft.yml), from the pull requests merged
# since the previous release. craft only regenerates the section when it is
Comment thread
jamescrosswell marked this conversation as resolved.
Outdated
# empty, so a single leftover manual entry under "## Unreleased" suppresses the
# auto-generation and silently drops every other change from the release notes.
# (This is what broke the 6.7.0 release, which shipped with a single entry.)
Comment thread
jamescrosswell marked this conversation as resolved.
Outdated
#
# Usage: scripts/verify-changelog.sh [path-to-changelog]
set -euo pipefail

CHANGELOG="${1:-CHANGELOG.md}"

if [[ ! -f "$CHANGELOG" ]]; then
echo "Changelog file not found: $CHANGELOG" >&2
exit 2
fi

# Extract the body of the "## Unreleased" section: everything between the
# "## Unreleased" heading and the next "## " (h2) heading. "### " sub-headings
# are not treated as section boundaries.
unreleased_body="$(awk '
/^## / {
if (in_section) exit
if (tolower($0) ~ /^## +unreleased/) { in_section = 1; next }
}
in_section { print }
' "$CHANGELOG")"

# craft trims the section body and skips auto-generation whenever it is
# non-empty (`if (!changeset.body)` after `.trim()`), so ANY non-whitespace
# content under "## Unreleased" -- a bullet, a stray "### Features" sub-heading,
# or loose text -- suppresses generation. Match that exactly: fail on any
# non-blank line. A bare/empty "## Unreleased" heading is fine (craft
# regenerates it).
if printf '%s\n' "$unreleased_body" | grep -Eq '[^[:space:]]'; then
echo "::error file=$CHANGELOG::The '## Unreleased' section is not empty."
echo ""
echo "This repository generates its changelog automatically at release time"
echo "(changelogPolicy: auto in .craft.yml). craft only regenerates the"
echo "'## Unreleased' section when it is empty, so ANY leftover content there"
echo "(entries or even a bare sub-heading) suppresses generation and causes the"
echo "rest of the release notes to be dropped."
echo ""
echo "Offending line(s):"
printf '%s\n' "$unreleased_body" | grep -En '[^[:space:]]' || true
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
echo ""
echo "Please remove them. Your change is added to the changelog automatically,"
echo "based on the PR title / commit message. If it is not user-facing, add the"
Comment thread
jamescrosswell marked this conversation as resolved.
Outdated
echo "'skip-changelog' label or write '#skip-changelog' in the PR description."
exit 1
fi

echo "OK: '## Unreleased' section is empty."
Loading