Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions .generated.NoMobile.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<Folder Name="/.github/workflows/">
<File Path=".github/workflows/alpine.yml" />
<File Path=".github/workflows/build.yml" />
<File Path=".github/workflows/changelog-guard.yml" />
<File Path=".github/workflows/changelog-preview.yml" />
<File Path=".github/workflows/codeql-analysis.yml" />
<File Path=".github/workflows/danger.yml" />
Expand Down Expand Up @@ -136,6 +137,7 @@
<File Path="scripts/update-cli.ps1" />
<File Path="scripts/update-java.ps1" />
<File Path="scripts/update-project-xml.ps1" />
<File Path="scripts/verify-changelog.sh" />
<File Path="scripts/watch-upstream.sh" />
</Folder>
<Folder Name="/src/">
Expand Down
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.
12 changes: 12 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Agent Instructions

## Getting Started

**Check out the submodules first.** The native SDKs and several build/tooling projects live in git submodules under `modules/` (e.g. `sentry-native`, `sentry-cocoa`, `perfview`). Without them, builds, solution-filter generation, and other tooling break in confusing ways — e.g. `scripts/generate-solution-filters.ps1` silently drops the missing projects from the `*.slnf` files.

The bootstrap step handles this for you (it runs `git submodule update --init --recursive` plus a full restore):

```sh
./dev.cs cleanslate
```

If you only need to sync submodules (e.g. in a fresh worktree), run `./dev.cs subup` or `git submodule update --init --recursive` directly.

## Build System

Uses the .NET SDK (`dotnet` CLI). Key files:
Expand Down
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: 4 additions & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,28 +109,13 @@ 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).
If the PR title doesn't capture the change well — you want more detail, or a single PR should produce several entries — add a `### Changelog Entry` section to the PR description. craft uses the text under that heading verbatim instead of the PR title. See [Custom changelog entries from PR descriptions](https://craft.sentry.dev/configuration/#custom-changelog-entries-from-pr-descriptions).

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
2 changes: 2 additions & 0 deletions Sentry.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<Folder Name="/.github/workflows/">
<File Path=".github/workflows/alpine.yml" />
<File Path=".github/workflows/build.yml" />
<File Path=".github/workflows/changelog-guard.yml" />
<File Path=".github/workflows/changelog-preview.yml" />
<File Path=".github/workflows/codeql-analysis.yml" />
<File Path=".github/workflows/danger.yml" />
Expand Down Expand Up @@ -136,6 +137,7 @@
<File Path="scripts/update-cli.ps1" />
<File Path="scripts/update-java.ps1" />
<File Path="scripts/update-project-xml.ps1" />
<File Path="scripts/verify-changelog.sh" />
<File Path="scripts/watch-upstream.sh" />
</Folder>
<Folder Name="/src/">
Expand Down
60 changes: 60 additions & 0 deletions scripts/verify-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/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
# empty, so a single leftover manual entry under "## Unreleased" suppresses the
# auto-generation and silently drops every other change from the release notes.
#
# 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

# Find non-blank lines in the "## Unreleased" section -- everything between the
# "## Unreleased" heading and the next "## " (h2) heading; "### " sub-headings
# are not treated as section boundaries. Each match is emitted as
# "<file-line-number>:<content>" so reported locations point at CHANGELOG.md.
#
# 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).
offending="$(awk '
/^## / {
if (in_section) { in_section = 0 }
if (tolower($0) ~ /^## +unreleased/) { in_section = 1; next }
}
in_section && /[^[:space:]]/ { printf "%d:%s\n", NR, $0 }
' "$CHANGELOG")"

if [[ -n "$offending" ]]; 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) in $CHANGELOG:"
printf '%s\n' "$offending"
echo ""
echo "Please remove them. Your change is added to the changelog automatically,"
echo "based on the PR title / commit message -- or a '### Changelog Entry' section"
echo "in the PR description if you want a more detailed entry. If it is not"
echo "user-facing, add the 'skip-changelog' label or write '#skip-changelog' in the"
echo "PR description."
exit 1
fi

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