Sphinx Github Changelog: Build a sphinx changelog from GitHub Releases
Sphinx-github-changelog is a Sphinx plugin that builds a changelog section based on a repository’s GitHub Releases content.
How ? (the short version)
In your Sphinx documentation conf.py
:
extensions = [
..., # your other extensions
"sphinx_github_changelog",
]
In your documentation:
.. changelog::
:changelog-url: https://your-project.readthedocs.io/en/stable/#changelog
:github: https://github.com/you/your-project/releases/
:pypi: https://pypi.org/project/your-project/
or more minimally (but not necessarily recommended):
.. changelog::
See the end result for this project on ReadTheDocs.
Why ?
On the way to continuous delivery, it’s important to be able to release easily. One of the criteria for easy releases is that the release doesn’t require a commit and a Pull Request. Release Pull Requests usually include 2 parts:
Changing the version
Updating the changelog (if you keep a changelog, let’s assume you do)
Commitless releases need a way to store the version and the changelog, as close as possible to the code, but actually not in the code.
Setting aside the “version” question, sphinx-github-changelog
aims at providing
a good way of managing the “changelog” part:
The best solution we’ve found so far for the changelog is to store it in the body of GitHub Releases. That’s very practical for maintainers, but it may not be the first place people will look for it. As far as we’ve seen, people expect the changelog to be:
in the repo, in
CHANGELOG.rst
,in the documentation.
Having the changelog in CHANGELOG.rst
causes a few problems:
Either each PR adds its single line of changelog, but:
you’ll most probably run into countless merge conflicts,
the changelog won’t tell you which contribution was part of which release
This reduces the interest for the whole thing.
Or your changelog is edited at release time. Maybe you’re using towncrier for fragment-based changelog, but you’re not doing commitless releases anymore. You could imagine that the release commit is done by your CI, but this can quickly become annoying, especially if you require Pull Requests.
But there is another way. Instead of providing the changelog, the CHANGELOG.rst
file can hold a link to the changelog. This makes things much easier.
sphinx-github-changelog
encourages you to do that.
Reference documentation
Automatic Configuration
The extension can automatically detect the GitHub repository URL from your git remotes in this order:
upstream
remoteorigin
remote
The GraphQL API and GitHub root URL are derived from this URL.
If for any reason, you’d rather provide the repository explicitly (e.g. the doc
repo doesn’t match the repo you’re releasing from, or anything else), you can
define the :github:
attribute to the directive. See directive for
details.
Authentication
The extension uses the GitHub GraphQL API to retrieve the changelog. This requires authentication using a GitHub API token.
However if you use git over HTTPS, or the gh
CLI, you probably already have a
suitable token, which sphinx-github-changelog
will automatically use.
In CI like GitHub Actions you can pass a token explicitly as an environment variable:
- name: Build documentation
run: make html
env:
SPHINX_GITHUB_CHANGELOG_TOKEN: ${{ github.token }}
In remaining cases you may need to create a personal access token. If the
repository is public, the token doesn’t need any special access (you can
uncheck eveything). For private and internal repositories, the token must
have repo
scope (classic tokens) or contents: read
access (fine-grained
tokens).
Pass the token as the SPHINX_GITHUB_CHANGELOG_TOKEN
environment variable.
You can also set the token as sphinx_github_changelog_token
in conf.py
but you should never commit secrets such as this.
Extension options (conf.py
)
sphinx_github_changelog_token
: GitHub API token, if needed.
Two options are accepted for backwards compatibility, but are likely detected
automatically from the :github:
parameter to the directive:
sphinx_github_changelog_root_repo
(optional): Root URL to the repository.sphinx_github_changelog_graphql_url
(optional): URL to GraphQL API.
Directive
.. changelog::
:changelog-url: https://your-project.readthedocs.io/en/stable/changelog.html
:github: https://github.com/you/your-project/releases/
:pypi: https://pypi.org/project/your-project/
Attributes
github
(optional): URL to the releases page of the repository. If not provided, auto‑detected from your git remote, as described above.changelog-url
(optional): URL to the built version of your changelog.sphinx-github-changelog
will display a link to your built changelog if the GitHub token is not provided (hopefully, this does not happen in your built documentation)pypi
(optional): URL to the PyPI page of the repository. This allows the changelog to display links to each PyPI release.
You’ll notice that each parameter here is not requested in the simplest form but as very specific URLs from which the program extracts the needed information. This is done on purpose. If people browse the unbuilt version of your documentation (e.g. on GitHub or PyPI directly), they’ll still be presented with links to the pages that contain the information they will need, instead of unhelping directives.
Changelog
This documentation itself is “drinking its own champagne”: it uses
sphinx-github-changelog
. Here’s what it looks like.
1.7.1
Released on 2025-05-11 - GitHub - PyPI
What's Changed
- Remove outdated paragraph in the README by @ewjoachim in #158
Full Changelog: 1.7.0...1.7.1
1.7.0
Released on 2025-05-11 - GitHub - PyPI
What's Changed
- Specify Python versions in metadata. Drop python 3.8 by @ewjoachim in #155
- Fix github repo badge style by @ewjoachim in #156
- Update README.rst by @ewjoachim in #157
Full Changelog: 1.6.2...1.7.0
1.6.2
Released on 2025-05-11 - GitHub - PyPI
What's Changed
- Licence, Renovate, Codeowner by @ewjoachim in #151
- Remove outdated script
publish
by @ewjoachim in #153 - Add license file to metadata by @ewjoachim in #154
Full Changelog: 1.6.1...1.6.2
1.6.1
Released on 2025-05-08 - GitHub - PyPI
What's Changed
- Fix release by @ewjoachim in #150
Full Changelog: 1.6.0...1.6.1
1.6.0
Released on 2025-05-08 - GitHub - PyPI
What's Changed
- Modernize repository boilerplate by @ewjoachim in #149
Note: we removed the following top-level metadata attributes: __author__
, __author_email__
, __license__
, __url__
, __version__
Full Changelog: 1.5.0...1.6.0
1.5.0
Released on 2025-05-08 - GitHub - PyPI
What's Changed
- Bump setuptools from 68.0.0 to 70.0.0 by @dependabot in #136
- [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in #141
- Configure extension automatically from git/gh by @lordmauve in #147
New Contributors
- @lordmauve made their first contribution in #147
Full Changelog: 1.4.0...1.5.0
1.4.0
Released on 2024-08-09 - GitHub - PyPI
What's Changed
New Contributors
Full Changelog: 1.3.0...1.4.0
1.3.0
Released on 2024-03-09 - GitHub - PyPI
- Fix crashes (#124)
- Bump jinja2 from 3.1.2 to 3.1.3 (#119)
- [pre-commit.ci] pre-commit autoupdate (#118)
- Bump urllib3 from 2.0.6 to 2.0.7 (#117)
- Bump urllib3 from 2.0.4 to 2.0.6 (#115)
- [pre-commit.ci] pre-commit autoupdate (#116)
- remove line referencing tox in MANIFEST (#113)
- Drop py3.7 and upgrade all deps (#112)
1.2.1
Released on 2023-02-15 - GitHub - PyPI
- fix error message when PyPI url is incorrect (#105)
- [pre-commit.ci] pre-commit autoupdate (#103, #102, #99, #97, #96, #95, #93, #92, #91, #90, #88, #86, #85, #84, #83, #82, #81, #80, #79, #78, #77, #76, #75, #74, #73, #69, #68, #67, #66, #65, #64, #63, #62, #61, #60, #59)
- Bump certifi from 2022.6.15 to 2022.12.7 (#94)
- Update .pre-commit-config.yaml (#72)
Kudos:
1.2.0
1.1.0
Released on 2022-01-03 - GitHub - PyPI
- [pre-commit.ci] pre-commit autoupdate (#54, #52, #51, #50, #49, #48, #47, #46, #45, #44, #42, #41, #40, #39, #37, #36, #35, #34, #32, #28, #27, #26, #25, #24, #22, #21, #20)
- Add support for Sphinx v4 (#53)
- Replace codecov with coverage-comment (#43)
- Fix CI python-version (#38)
- Fix mypy (#31)
- Delete unused requirements.txt (#23)
Kudos:
1.0.8
Released on 2021-04-17 - GitHub - PyPI
Miscellaneous
- Badges (#19)
Kudos:
1.0.7
Released on 2021-04-17 - GitHub - PyPI
Bug Fixes
- Readthedocs fail on warning (#18)
Kudos:
1.0.6
Released on 2021-04-17 - GitHub - PyPI
Miscellaneous
Kudos:
1.0.5
Released on 2021-04-17 - GitHub - PyPI
Bug Fixes
- publish restores the file (#12)
Miscellaneous
- iterate on CI (#14)
- Improve cache & publish (#13)
- pre-commit.ci is now responsible for the linting (#15)
Kudos:
@ewjoachim and @pre-commit-ci[bot]
1.0.4: Add missing dependency dunamai
Released on 2021-04-16 - GitHub - PyPI
Bug Fixes
- Add dunamai (#11)
Kudos:
1.0.3: Redo boilerplate, fix crash when there are draft releases
Released on 2021-04-16 - GitHub - PyPI
Bug Fixes
Miscellaneous
Kudos:
1.0.2: Fix for Release Drafts
Released on 2020-07-31 - GitHub - PyPI
Bug Fixes
- Fix crash in case of draft release (#6)
Misc
- Check lint in CI (#5)
1.0.1: Travis PyPI deployment
Released on 2020-07-27 - GitHub - PyPI
- Add PyPI token to Travis (#4)
1.0.0: A fresh start
Released on 2020-07-27 - GitHub - PyPI
Features
- Initial code (#2)
Bug Fixes
- Main branch is actually called main (#3)
Test
The following text is just to test the changelog markup
A title
- #1 by @ewjoachim
- example.com
- unordered list
- ordered list
- a
- b
- bold, italics, both,
strikethrough