Manipulate keep a changelog files
- Command line utility
- Convert to dict
- Convert from dict
- Release a new version
- Add changelog retrieval REST API endpoint
Convert changelog to dict
Convert changelog markdown file following keep a changelog format into python dict.
import keepachangelog
changes = keepachangelog.to_dict("path/to/CHANGELOG.md")
changes
would look like:
changes = {
"1.1.0": {
"changed": [
"Enhancement 1 (1.1.0)",
"sub enhancement 1",
"sub enhancement 2",
"Enhancement 2 (1.1.0)",
],
"metadata": {
"release_date": "2018-05-31",
"version": "1.1.0",
"semantic_version": {
"major": 1,
"minor": 1,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
},
"1.0.1": {
"fixed": [
"Bug fix 1 (1.0.1)",
"sub bug 1",
"sub bug 2",
"Bug fix 2 (1.0.1)",
],
"metadata": {
"release_date": "2018-05-31",
"version": "1.0.1",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 1,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
},
"1.0.0": {
"deprecated": ["Known issue 1 (1.0.0)", "Known issue 2 (1.0.0)"],
"metadata": {
"release_date": "2017-04-10",
"version": "1.0.0",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
},
}
For a markdown file with the following content:
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Changed
- Release note 1.
- Release note 2.
### Added
- Enhancement 1
- sub enhancement 1
- sub enhancement 2
- Enhancement 2
### Fixed
- Bug fix 1
- sub bug 1
- sub bug 2
- Bug fix 2
### Security
- Known issue 1
- Known issue 2
### Deprecated
- Deprecated feature 1
- Future removal 2
### Removed
- Deprecated feature 2
- Future removal 1
## [1.1.0] - 2018-05-31
### Changed
- Enhancement 1 (1.1.0)
- sub enhancement 1
- sub enhancement 2
- Enhancement 2 (1.1.0)
## [1.0.1] - 2018-05-31
### Fixed
- Bug fix 1 (1.0.1)
- sub bug 1
- sub bug 2
- Bug fix 2 (1.0.1)
## [1.0.0] - 2017-04-10
### Deprecated
- Known issue 1 (1.0.0)
- Known issue 2 (1.0.0)
[Unreleased]: https://github.test_url/test_project/compare/v1.1.0...HEAD
[1.1.0]: https://github.test_url/test_project/compare/v1.0.1...v1.1.0
[1.0.1]: https://github.test_url/test_project/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.test_url/test_project/releases/tag/v1.0.0
show_unreleased
parameter can be specified in order to include Unreleased
section information.
Note that release_date
metadata will be set to None in such as case.
Retrieving the raw content
Using CLI
keepachangelog show 1.0.0
For details on what is actually performed, refer to the section below as it is what is used underneath the hood.
Using python module
If for some reason you would like to retrieve the raw content of a release you can use to_raw_dict
instead.
import keepachangelog
changes = keepachangelog.to_raw_dict("path/to/CHANGELOG.md")
changes
would look like:
changes = {
"1.1.0": {
"raw": """### Changed
- Enhancement 1 (1.1.0)
- sub enhancement 1
- sub enhancement 2
- Enhancement 2 (1.1.0)""",
"metadata": {
"release_date": "2018-05-31",
"version": "1.1.0",
"semantic_version": {
"major": 1,
"minor": 1,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.1...v1.1.0",
},
},
"1.0.1": {
"raw": """### Fixed
- Bug fix 1 (1.0.1)
- sub bug 1
- sub bug 2
- Bug fix 2 (1.0.1)""",
"metadata": {
"release_date": "2018-05-31",
"version": "1.0.1",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 1,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/compare/v1.0.0...v1.0.1",
},
},
"1.0.0": {
"raw": """### Deprecated
- Known issue 1 (1.0.0)
- Known issue 2 (1.0.0)""",
"metadata": {
"release_date": "2017-04-10",
"version": "1.0.0",
"semantic_version": {
"major": 1,
"minor": 0,
"patch": 0,
"prerelease": None,
"buildmetadata": None,
},
"url": "https://github.test_url/test_project/releases/tag/v1.0.0",
},
},
}
Convert dict to changelog
Convert a python dict (resulting from keepachangelog.to_dict
) to a changelog markdown content following keep a changelog format.
import keepachangelog
changes = keepachangelog.to_dict("path/to/CHANGELOG.md")
content = keepachangelog.from_dict(changes)
Release
Using CLI
keepachangelog release
For details on what is actually performed, refer to the section below as it is what is used underneath the hood.
Using python module
You can create a new release by using keepachangelog.release
function.
import keepachangelog
new_version = keepachangelog.release("path/to/CHANGELOG.md")
This will:
- If
new_version
parameter is not provided, guess the new version number and return it:Removed
orChanged
sections will be considered as breaking changes, thus incrementing the major version.- If the only section is
Fixed
, only patch will be incremented. - Otherwise, minor will be incremented.
- Update changelog.
- Unreleased section content will be moved into a new section.
[Unreleased]
link will be updated.- New link will be created corresponding to the new section (based on the format of the Unreleased link).
Usage from command line
keepachangelog
can be used directly via command line.
The main usage is within your CI to be able to Release a new version and then Create the appropriate release body. As in the following sample:
NEW_VERSION=$(keepachangelog release)
GITHUB_RELEASE_BODY=$(keepachangelog show ${NEW_VERSION})
You can use it as a python module:
python -m keepachangelog --help
Or as a shell command:
keepachangelog --help
# usage: keepachangelog [-h] [-v] {show,release} ...
#
# Manipulate keep a changelog files
#
# options:
# -h, --help show this help message and exit
# -v, --version show program's version number and exit
#
# commands:
# {show,release}
# show Show the content of a release from the changelog
# release Create a new release in the changelog
#
# Examples:
#
# keepachangelog show 1.0.0
# keepachangelog show 1.0.0 path/to/CHANGELOG.md
#
# keepachangelog release
# keepachangelog release 1.0.1
# keepachangelog release 1.0.1 -f path/to/CHANGELOG.md
Endpoint
Starlette
A helper function is available to create a starlette endpoint to retrieve changelog as JSON.
from starlette.applications import Starlette
from starlette.routing import Route
from keepachangelog.starlette import changelog_endpoint
# /changelog endpoint will return the dict extracted from the changelog as JSON.
changelog_route = Route("/changelog", endpoint=changelog_endpoint("path/to/CHANGELOG.md"))
app = Starlette(routes=[changelog_route])
Note: starlette module must be installed.
Flask-RestX
A helper function is available to create a Flask-RestX endpoint to retrieve changelog as JSON.
import flask
import flask_restx
from keepachangelog.flask_restx import add_changelog_endpoint
app = flask.Flask(__name__)
api = flask_restx.Api(app)
# /changelog endpoint will return the dict extracted from the changelog as JSON.
add_changelog_endpoint(api, "path/to/CHANGELOG.md")
Note: flask-restx module must be installed.
How to install
- python 3.7+ must be installed
- Use pip to install module:
python -m pip install keepachangelog