Skip to content

Commit 2588f00

Browse files
Add towncrier
1 parent c0507d1 commit 2588f00

File tree

8 files changed

+130
-33
lines changed

8 files changed

+130
-33
lines changed

.github/workflows/ci.yml

+3-6
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,9 @@ jobs:
2929
run: python -m pip install --upgrade nox pip setuptools
3030
- name: Run linters
3131
run: nox -vs lint
32-
- name: Validate changelog
33-
# Library was designed to be used with pull requests only.
34-
if: ${{ github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }}
35-
uses: zattoo/changelog@v1
36-
with:
37-
token: ${{ github.token }}
32+
- name: Validate new changelog entries
33+
run: if [ -z "$(git diff --diff-filter=A --name-only origin/${{ github.event.pull_request.base.ref }} changelog.d)" ];
34+
then echo no changelog item added; exit 1; fi
3835
build:
3936
needs: lint
4037
runs-on: ubuntu-latest

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased]
7+
This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the changes for the
8+
upcoming release can be found in [changelog.d](changelog.d).
9+
10+
<!-- towncrier release notes start -->
811

912
## [1.25.0] - 2023-11-15
1013

CONTRIBUTING.md

+39-3
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,58 @@
11
# Contributing to B2 Python SDK
22

3-
We encourage outside contributors to perform changes on our codebase. Many such changes have been merged already. In order to make it easier to contribute, core developers of this project:
3+
We encourage outside contributors to perform changes on our codebase. Many such changes have been merged already.
4+
In order to make it easier to contribute, core developers of this project:
45

56
* provide guidance (through the issue reporting system)
67
* provide tool assisted code review (through the Pull Request system)
78
* maintain a set of unit tests
89
* maintain a set of integration tests (run with a production cloud)
910
* maintain development automation tools using [nox](https://github.com/theacodes/nox) that can easily:
10-
* format the code using [yapf](https://github.com/google/yapf)
11+
* format the code using [yapf](https://github.com/google/yapf) and [ruff](https://github.com/astral-sh/ruff)
1112
* runs linters to find subtle/potential issues with maintainability
1213
* run the test suite on multiple Python versions using [pytest](https://github.com/pytest-dev/pytest)
1314
* maintain Continuous Integration (by using GitHub Actions) that:
1415
* runs all sorts of linters
1516
* checks if the Python distribution can be built
16-
* runs all tests on a matrix of 6 versions of Python (including pypy) and 3 operating systems (Linux, Mac OS X and Windows)
17+
* runs all tests on a matrix of 6 versions of Python (including pypy) and 3 operating systems
18+
(Linux, Mac OS X and Windows)
1719
* checks if the documentation can be built properly
1820
* maintain other Continuous Integration tools (coverage tracker)
1921

22+
## Versioning
23+
24+
This package's versions adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and the versions are
25+
established by reading git tags, i.e. no code or manifest file changes are required when working on PRs.
26+
27+
## Changelog
28+
29+
Each PR needs to have at least one changelog (aka news) item added. This is done by creating files in `changelog.d`.
30+
`towncrier` is used for compiling these files into [CHANGELOG.md](CHANGELOG.md). There are several types of changes
31+
(news):
32+
33+
1. fixed
34+
2. changed
35+
3. added
36+
4. deprecated
37+
5. removed
38+
6. infrastructure
39+
7. doc
40+
41+
42+
The `changelog.d` file name convention is:
43+
44+
1. If the PR closes a github issue: `{issue_number}.{type}.md` e.g. `157.fixed.md`. Note that the
45+
change description still has to be complete, linking an issue is just there for convenience, a change like
46+
`fixed #157` will not be accepted.
47+
2. If the PR is not related to a github issue: `+{unique_string}.{type}.md` e.g. `+foobar.fixed.md`.
48+
49+
These files can either be created manually, or using `towncrier` e.g.
50+
51+
towncrier create -c 'write your description here' 157.fixed.md
52+
53+
`towncrier create` also takes care of duplicates automatically (if there is more than 1 news fragment of one type
54+
for a given github issue).
55+
2056
## Developer Info
2157

2258
You'll need to have [nox](https://github.com/theacodes/nox) installed:

README.release.md

+1-23
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,3 @@
11
# Release Process
22

3-
- Get the Nox:
4-
- `pip install -U nox`
5-
- Update the release history in `CHANGELOG.md`:
6-
- Change "Unreleased" to the current release version and date.
7-
- Create empty "Unreleased" section.
8-
- Add proper link to the new release (at the bottom of the file). Use GitHub [compare feature](https://docs.github.com/en/free-pro-team@latest/github/committing-changes-to-your-project/comparing-commits#comparing-tags) between two tags.
9-
- Update "Unreleased" link (at the bottom of the file).
10-
- Run linters and tests:
11-
- `export B2_TEST_APPLICATION_KEY=your_app_key`
12-
- `export B2_TEST_APPLICATION_KEY_ID=your_app_key_id`
13-
- `nox -x`
14-
- Build docs locally:
15-
- `nox --non-interactive -xs doc`
16-
- Commit and push to GitHub, then wait for CI workflow to complete successfully.
17-
- No need to make a branch. Push straight to `master`.
18-
- Tag in git and push tag to origin. (Version tags look like "v0.4.6".)
19-
- `git tag vx.x.x`
20-
- `git push origin vx.x.x`
21-
- Wait for CD workflow to complete successfully.
22-
- Verify that the GitHub release is created
23-
- Verify that the release has been uploaded to the PyPI
24-
- Install using pip and verify that it gets the correct version:
25-
- `pip install -U b2sdk`
3+
- Run `nox -s make_release_commit -- X.Y.Z` where `X.Y.Z` is the version you're releasing, and follow the instructions
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Towncrier changelog generation - to avoid conflicts when simultaneously working on PRs

changelog.d/.gitkeep

Whitespace-only changes.

noxfile.py

+39
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from __future__ import annotations
1111

1212
import os
13+
import re
14+
import subprocess
1315

1416
import nox
1517

@@ -32,6 +34,7 @@
3234

3335
REQUIREMENTS_FORMAT = ['yapf==0.27', 'ruff==0.0.270']
3436
REQUIREMENTS_LINT = REQUIREMENTS_FORMAT + ['pytest==6.2.5', 'liccheck==0.6.2']
37+
REQUIREMENTS_RELEASE = ['towncrier==23.11.0']
3538
REQUIREMENTS_TEST = [
3639
"pytest==6.2.5",
3740
"pytest-cov==3.0.0",
@@ -206,3 +209,39 @@ def doc_cover(session):
206209
# If there is no undocumented files, the report should have only 2 lines (header)
207210
if sum(1 for _ in fd) != 2:
208211
session.error('sphinx coverage has failed')
212+
213+
214+
@nox.session(python=PYTHON_DEFAULT_VERSION)
215+
def make_release_commit(session):
216+
"""
217+
Runs `towncrier build`, commits changes, tags, all that is left to do is pushing
218+
"""
219+
if session.posargs:
220+
version = session.posargs[0]
221+
else:
222+
session.error('Provide -- {release_version} (X.Y.Z - without leading "v")')
223+
224+
if not re.match(r'^\d+\.\d+\.\d+$', version):
225+
session.error(
226+
f'Provided version="{version}". Version must be of the form X.Y.Z where '
227+
f'X, Y and Z are integers'
228+
)
229+
230+
local_changes = subprocess.check_output(['git', 'diff', '--stat'])
231+
if local_changes:
232+
session.error('Uncommitted changes detected')
233+
234+
current_branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).decode()
235+
if current_branch != 'master':
236+
session.log('WARNING: releasing from a branch different than master')
237+
238+
session.run('pip', 'install', *REQUIREMENTS_RELEASE)
239+
session.run('towncrier', 'build', '--yes', '--version', version)
240+
241+
session.log(
242+
f'CHANGELOG updated, changes ready to commit and push\n'
243+
f' git commit -m release {version}\n'
244+
f' git tag v{version}\n'
245+
f' git push {{UPSTREAM_NAME}} v{version}\n'
246+
f' git push {{UPSTREAM_NAME}} {current_branch}'
247+
)

pyproject.toml

+43
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,46 @@ target-version = "py37"
1515
"b2sdk/v*/**" = ["I", "F403", "F405"]
1616
"b2sdk/_v*/**" = ["I", "F403", "F405"]
1717
"test/**" = ["D", "F403", "F405"]
18+
19+
[tool.towncrier]
20+
directory = "changelog.d"
21+
filename = "CHANGELOG.md"
22+
start_string = "<!-- towncrier release notes start -->\n"
23+
underlines = ["", "", ""]
24+
title_format = "## {version} - {project_date}"
25+
issue_format = "[#{issue}](https://github.com/Backblaze/b2-sdk-python/issues/{issue})"
26+
27+
[[tool.towncrier.type]]
28+
directory = "removed"
29+
name = "Removed"
30+
showcontent = true
31+
32+
[[tool.towncrier.type]]
33+
directory = "changed"
34+
name = "Changed"
35+
showcontent = true
36+
37+
[[tool.towncrier.type]]
38+
directory = "fixed"
39+
name = "Fixed"
40+
showcontent = true
41+
42+
[[tool.towncrier.type]]
43+
directory = "deprecated"
44+
name = "Deprecated"
45+
showcontent = true
46+
47+
[[tool.towncrier.type]]
48+
directory = "added"
49+
name = "Added"
50+
showcontent = true
51+
52+
[[tool.towncrier.type]]
53+
directory = "doc"
54+
name = "Doc"
55+
showcontent = true
56+
57+
[[tool.towncrier.type]]
58+
directory = "infrastructure"
59+
name = "Infrastructure"
60+
showcontent = true

0 commit comments

Comments
 (0)