mkdocs-decision-records
Manage decision records with mkdocs in a customizable and minimal fashion.
Features
- Customizable status colors and lifecycle
- Enforces information to be present for ADRs
- Allows description being kept as markdown
- Opt-in generated index page listing all decision records
Demo
You can find a Demo on GitHub Pages
Installation
- Install
mkdocs-decision-recordsfrom the PyPi registry using your favorite package manager - Configure your
mkdocs.ymlplugins: - decision-records: # Folder where your decision records are located, defaults to adr decisions_folder: adr # Optional prefix to prepend to ticket numbers ticket_url_prefix: https://ticket.example.com/ # Configure amount of required deciders required_deciders_count: 1 # Configure the length of decision IDs (default: 3) decision_id_length: 3 # Enable validation that IDs match the configured length (default: false) # When enabled, IDs that don't match the configured length will be rejected validate_id_length: false # Generate an index.md listing all decision records (default: false) generate_index_page: false # Configure available stages and the badge colors lifecycle_stages: {status}: {color}
- Create your ADRs ensuring to add the frontmatter meta data:
--- id: 000 status: proposed | rejected | accepted | deprecated | … | superseded [superseded_by: <id it has been replaced with>] date: YYYY-MM-DD deciders: - decider 1 - decider 2 # Optional ticket ticket: FOO-1 --- ## Context and Problem Statement [Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.] ## Decision Drivers <!-- optional --> * [driver 1, e.g., a force, facing concern, …] * [driver 2, e.g., a force, facing concern, …] * … <!-- numbers of drivers can vary --> ## Considered Options * [option 1] * [option 2] * [option 3] ## Decision Outcome Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … | comes out best (see below)]. ## Pros and Cons of the Options <!-- optional --> ### [option 1] [example | description | pointer to more information | …] <!-- optional --> * Good, because [argument a] * Good, because [argument b] * Bad, because [argument c] * … <!-- numbers of pros and cons can vary --> ### [option 2] [example | description | pointer to more information | …] <!-- optional --> * Good, because [argument a] * Good, because [argument b] * Bad, because [argument c] * … <!-- numbers of pros and cons can vary --> ### [option 3] [example | description | pointer to more information | …] <!-- optional --> * Good, because [argument a] * Good, because [argument b] * Bad, because [argument c] * … <!-- numbers of pros and cons can vary --> ## Links <!-- optional --> * [Link type] [Link to ADR] <!-- example: Refined by [ADR-0005](0005-example.md) --> * … <!-- numbers of links can vary -->
Superseding ADRs
This plugin is opinionated about using superseded status.
When setting the status to superseded, make to sure also set superseded_by to the ADR id it has been replaced with.
---
# adr details
status: superseded
superseded_by: 123
---
<!-- Deprecated ADR -->
Generated decision index
On every build, the plugin writes a decision_index.json to the root of the built site (e.g. site/decision_index.json).
It contains one entry per decision record (templates excluded), and can be used to build custom search or listing
features on top of the generated site.
Each entry has the shape:
{
"id": "000",
"date": "2024-01-01",
"title": "Example decision",
"status": "accepted",
"url": "adr/000-example-decision/",
"deciders": ["Jane Doe"],
"ticket": "FOO-123",
"toc": "...",
"sections": [
{ "title": "Context and Problem Statement", "text": "..." }
],
"superseded_by": "001"
}
urlis the rendered page's URL, relative to the site root (join it with the site's base URL to get a link to the decision record)decidersandticketmirror the record's frontmatter;decidersis[]andticketisnullwhen not settocis the page's table of contents, as produced by MkDocssectionslists the page's headings with their rendered text contentsuperseded_byis only present whenstatusissuperseded
Generated index page
With generate_index_page: true, the plugin writes an index.md into the decisions folder (e.g.
adr/index.md) listing every decision record as a markdown table:
| ID | Date | Title | Status | Ticket | Deciders |
|---|---|---|---|---|---|
| 001 | 2021-03-26 | Mechanism to validate mjml code | accepted | FOO-100 | Jane, John, Jill |
- The template record (
id: 000) is never listed; if it is the only record, no file is written at all. - Rows are sorted by ID in ascending numeric order.
- The title cell links to the decision record and drops the id prefix the record pages show.
- The status cell renders the configured lifecycle badge.
- The
Ticketcolumn only exists whenticket_url_prefixis configured. - Only the first three deciders are listed; additional ones are summarized as
.... - While the option is enabled, an existing
index.mdin the decisions folder is overwritten.
The generated page is rendered like any other documentation page, so it works as a section landing
page for plugins that pick up a folder's index.md.
Motivation
I love ADRs and documenting decisions in general. This plugin makes it a bit easier, enforcing basic meta information while keeping the format open enough so you can do your thing.
Contributing
I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the configuration
- Submitting a fix
- Proposing new features
- Becoming a maintainer
To get started please read the Contribution Guidelines.
Development
Requirements
- Python 3.12+
- Poetry
Build
poetry install
Alternatives
- mkdocs-material
- Needs to use the theme
- ADR graph
- mkdocs-macros-adr-summary
- works entirely with macros
- no metadata table at the top
Metadata
Release files for mkdocs-decision-records 3.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mkdocs_decision_records-3.2.0.tar.gz | 24.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mkdocs_decision_records-3.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 53.1 kB
Release files / mkdocs_decision_records-3.2.0.tar.gz
| Download URL | mkdocs_decision_records-3.2.0.tar.gz |
|---|---|
| Size | 24.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
28d8be33260e71176acdc6d1c5de5e30ed72449b85ffb69a0fb75eb1ebe0531e
|
|
BLAKE2b-256 checksum How to use checksums |
f3a6d39cfbbd7d12a17ea74b3ff6697d20cca2c4977a95244f4196199c518977
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / mkdocs_decision_records-3.2.0-py3-none-any.whl
| Download URL | mkdocs_decision_records-3.2.0-py3-none-any.whl |
|---|---|
| Size | 28.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
42c0c6f2075bf61f223763bc41435c0ee018c073b514ef0371ca19a72e451e08
|
|
BLAKE2b-256 checksum How to use checksums |
2f31a2b84a4591d82b6114560c03a5302cba08813f25dc4e491e6d340f7fe2cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for mkdocs-decision-records 3.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.