Skip to content

Commit 839c3b9

Browse files
committed
add towncrier to manage changelogs
1 parent 0d9f0c5 commit 839c3b9

23 files changed

Lines changed: 182 additions & 1 deletion

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: changelog
2+
3+
permissions:
4+
contents: read
5+
6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.event.pull_request.id }}
8+
cancel-in-progress: true
9+
10+
on:
11+
pull_request:
12+
branches: ["main"]
13+
14+
jobs:
15+
changelog:
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 10
18+
steps:
19+
- name: Check for skip-changelog label
20+
id: skip
21+
shell: bash
22+
run: |
23+
if ${{ contains(github.event.pull_request.labels.*.name, 'skip-changelog') }}; then
24+
echo "skip=true" >> "$GITHUB_OUTPUT"
25+
echo "PR has 'skip-changelog' label; bypassing changelog check."
26+
else
27+
echo "skip=false" >> "$GITHUB_OUTPUT"
28+
fi
29+
- uses: actions/checkout@v4
30+
if: steps.skip.outputs.skip != 'true'
31+
with:
32+
fetch-depth: 0
33+
- uses: ./.github/actions/setup_build_env
34+
if: steps.skip.outputs.skip != 'true'
35+
with:
36+
python-version: "3.14"
37+
run-uv-sync: true
38+
- name: Determine affected packages
39+
if: steps.skip.outputs.skip != 'true'
40+
id: affected
41+
shell: bash
42+
run: |
43+
set -euo pipefail
44+
changed=$(git diff --name-only origin/main...HEAD)
45+
affected=()
46+
if printf '%s\n' "$changed" | grep -qE '^reflex/'; then
47+
affected+=(".")
48+
fi
49+
for pkg_dir in packages/*/; do
50+
pkg=$(basename "$pkg_dir")
51+
[[ "$pkg" == "integrations-docs" ]] && continue
52+
if printf '%s\n' "$changed" | grep -qE "^packages/$pkg/src/"; then
53+
affected+=("${pkg_dir%/}")
54+
fi
55+
done
56+
printf '%s\n' "${affected[@]}" > affected.txt
57+
echo "Affected packages:"
58+
cat affected.txt
59+
- name: Check for news fragments
60+
if: steps.skip.outputs.skip != 'true'
61+
shell: bash
62+
run: |
63+
set -euo pipefail
64+
if [ ! -s affected.txt ]; then
65+
echo "No packaged source changes in this PR; no changelog fragments required."
66+
exit 0
67+
fi
68+
failed=0
69+
while IFS= read -r pkg_dir; do
70+
[ -z "$pkg_dir" ] && continue
71+
echo "::group::towncrier check ($pkg_dir)"
72+
if ! uv run towncrier check --config pyproject.toml --dir "$pkg_dir" --compare-with origin/main; then
73+
failed=1
74+
fi
75+
echo "::endgroup::"
76+
done < affected.txt
77+
if [ "$failed" -ne 0 ]; then
78+
echo ""
79+
echo "One or more affected packages is missing a news fragment under <package>/news/."
80+
echo "Add a fragment named <pr-number>.<type>.md where <type> is one of:"
81+
echo " breaking, deprecation, feature, bugfix, performance, docs, misc"
82+
echo "Or apply the 'skip-changelog' label if the change is genuinely not user-facing."
83+
exit 1
84+
fi

β€ŽCONTRIBUTING.mdβ€Ž

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,38 @@ Within the 'test' directory of Reflex you can add to a test file already there o
5858
- Any edge cases or potential problem areas.
5959
- Any interactions between different parts of the code.
6060

61+
## πŸ“ Changelog Fragments
62+
63+
Each PR that changes the source of a published package must add a news fragment describing the change. Fragments are assembled into `CHANGELOG.md` at release time by [towncrier](https://towncrier.readthedocs.io/).
64+
65+
**Where:** add the fragment under the affected package's `news/` directory. For the main `reflex` package, that's the repo-root `news/`. For sub-packages it's `packages/<name>/news/`.
66+
67+
**Filename:** `<pr-or-issue-number>.<type>.md`, where `<type>` is one of:
68+
69+
| Type | When to use |
70+
| --- | --- |
71+
| `breaking` | Backwards-incompatible change users need to adapt to |
72+
| `deprecation` | API marked deprecated but still functional |
73+
| `feature` | New user-facing functionality |
74+
| `bugfix` | Fix for an incorrect behavior |
75+
| `performance` | Speed, memory, or startup improvement |
76+
| `docs` | Documentation or docstring changes |
77+
| `misc` | Internal refactor, build, or dependency change that still warrants mention |
78+
79+
**Content:** one or two sentences, written for users reading release notes (not reviewers of the diff).
80+
81+
**Create a fragment from the CLI:**
82+
83+
```bash
84+
uv run towncrier create --config pyproject.toml --dir packages/reflex-ui 1234.feature.md
85+
```
86+
87+
Drop `--dir` for a fragment against the main `reflex` package.
88+
89+
If you don't yet know the PR number, use an [orphan fragment](https://towncrier.readthedocs.io/en/stable/cli.html#towncrier-create) (`+.feature.md`) and rename it after opening the PR.
90+
91+
**Skipping the fragment check:** for PRs that are genuinely not user-facing (CI-only tweaks, script fixes, test-only changes), apply the `skip-changelog` label on the PR to bypass the changelog CI check.
92+
6193
## βœ… Making a PR
6294

6395
Once you solve a current issue or improvement to Reflex, you can make a PR, and we will review the changes.

β€Žnews/+towncrier.misc.mdβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Introduced towncrier-based changelog management. Each PR that changes package source now adds a fragment under the affected package's `news/` directory; fragments are assembled into `CHANGELOG.md` at release time. See CONTRIBUTING.md for the full workflow.

β€Žnews/.gitkeepβ€Ž

Whitespace-only changes.

β€Žpackages/hatch-reflex-pyi/news/.gitkeepβ€Ž

Whitespace-only changes.

β€Žpackages/reflex-base/news/.gitkeepβ€Ž

Whitespace-only changes.

β€Žpackages/reflex-components-code/news/.gitkeepβ€Ž

Whitespace-only changes.

β€Žpackages/reflex-components-core/news/.gitkeepβ€Ž

Whitespace-only changes.

β€Žpackages/reflex-components-dataeditor/news/.gitkeepβ€Ž

Whitespace-only changes.

β€Žpackages/reflex-components-gridjs/news/.gitkeepβ€Ž

Whitespace-only changes.

0 commit comments

Comments
Β (0)