Changelogs local generation (#1411)

This PR introduces a script and some templates to use the prdoc involved
in a release and build:
- the changelog
- a simple draft of audience documentation

Since the prdoc presence was enforced in the middle of the version
1.5.0, not all PRs did come with a `prdoc` file.
This PR creates all the missing `prdoc` files with some minimum content
allowing to properly generate the changelog.
The generated content is **not** suitable for the audience
documentation.

The audience documentation will be possible with the next version, when
all PR come with a proper `prdoc`.

## Assumptions

- the prdoc files for release `vX.Y.Z` have been moved under
`prdoc/X.Y.Z`
- the changelog requires for now for the prdoc files to contain author +
topic. Thos fields are optional.

The build script can  be called as:
```
VERSION=X.Y.Z ./scripts/release/build-changelogs.sh
```

Related:
-  #1408

---------

Co-authored-by: EgorPopelyaev <egor@parity.io>
This commit is contained in:
Chevdor
2023-12-12 15:29:56 +01:00
committed by GitHub
parent 6b5995ffd1
commit 42a3afba94
98 changed files with 643 additions and 27 deletions
Generated
+2 -2
View File
@@ -11786,7 +11786,7 @@ dependencies = [
[[package]]
name = "polkadot"
version = "1.1.0"
version = "1.5.0"
dependencies = [
"assert_cmd",
"color-eyre",
@@ -12756,7 +12756,7 @@ dependencies = [
[[package]]
name = "polkadot-parachain-bin"
version = "1.1.0"
version = "1.5.0"
dependencies = [
"assert_cmd",
"asset-hub-rococo-runtime",
@@ -112,7 +112,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("statemine"),
impl_name: create_runtime_str!("statemine"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 13,
@@ -125,7 +125,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("statemine"),
impl_name: create_runtime_str!("statemine"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 13,
@@ -109,7 +109,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("westmint"),
impl_name: create_runtime_str!("westmint"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 13,
@@ -171,7 +171,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("bridge-hub-rococo"),
impl_name: create_runtime_str!("bridge-hub-rococo"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 3,
@@ -172,7 +172,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("bridge-hub-westend"),
impl_name: create_runtime_str!("bridge-hub-westend"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 3,
@@ -114,7 +114,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("collectives-westend"),
impl_name: create_runtime_str!("collectives-westend"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 5,
@@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("contracts-rococo"),
impl_name: create_runtime_str!("contracts-rococo"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 6,
@@ -99,7 +99,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("glutton-westend"),
impl_name: create_runtime_str!("glutton-westend"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
@@ -106,7 +106,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("test-parachain"),
impl_name: create_runtime_str!("test-parachain"),
authoring_version: 1,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 6,
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "polkadot-parachain-bin"
version = "1.1.0"
version = "1.5.0"
authors.workspace = true
build = "build.rs"
edition.workspace = true
+1 -1
View File
@@ -18,7 +18,7 @@ rust-version = "1.64.0"
readme = "README.md"
authors.workspace = true
edition.workspace = true
version = "1.1.0"
version = "1.5.0"
default-run = "polkadot"
[dependencies]
+1 -1
View File
@@ -58,7 +58,7 @@ pub use disputes::{
/// relatively rare.
///
/// The associated worker binaries should use the same version as the node that spawns them.
pub const NODE_VERSION: &'static str = "1.1.0";
pub const NODE_VERSION: &'static str = "1.5.0";
// For a 16-ary Merkle Prefix Trie, we can expect at most 16 32-byte hashes per node
// plus some overhead:
+1 -1
View File
@@ -149,7 +149,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("rococo"),
impl_name: create_runtime_str!("parity-rococo-v2.0"),
authoring_version: 0,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 22,
+1 -1
View File
@@ -145,7 +145,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("westend"),
impl_name: create_runtime_str!("parity-westend"),
authoring_version: 2,
spec_version: 1_004_000,
spec_version: 1_005_000,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 22,
+2
View File
@@ -0,0 +1,2 @@
Version 1.3.0 does not support `prddoc` yet.
Some prdoc files are provided but the list is NOT complete.
+2
View File
@@ -0,0 +1,2 @@
Version 1.4.0 does not support `prddoc` yet.
Some prdoc files are provided but the list is NOT complete.
+9
View File
@@ -0,0 +1,9 @@
title: Rework the event system of `sc-network`
author: altonen
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
@@ -1,6 +1,9 @@
# This PR does not need a prdoc but it is provided in order to test
title: PRdoc check
author: chevdor
topic: documentation
doc:
- audience: Node Dev
description: |
+9
View File
@@ -0,0 +1,9 @@
title: Update tick collator for async backing
author: Sophia-Gold
topic: Tests
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Preserve artifact cache unless stale
author: eagr
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
@@ -3,6 +3,9 @@
title: New PRDoc Schema
author: chevdor
topic: documentation
doc:
- audience: Node Dev
description: &desc |
+9
View File
@@ -0,0 +1,9 @@
title: Enable parallel key scraping
author: eagr
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "cumulus-consensus-common: block import: `delayed_best_block` flag added"
author: michalkucharczyk
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "PVF: Add test instructions"
author: mrcnski
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
@@ -1,5 +1,8 @@
title: Cleanup XCMP `QueueConfigData`
author: serban300
topic: runtime
doc:
- audience: Runtime Dev
description: Removes obsolete fields from the `QueueConfigData` structure. For the remaining fields, if they use the old defaults, we replace them with the new defaults.
+9
View File
@@ -0,0 +1,9 @@
title: "add pallet nomination-pools versioned migration to kitchensink"
author: brunopgalvao
topic: Tests
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "chain-spec-builder: cleanup"
author: michalkucharczyk
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "remove retry from backers on failed candidate validation"
author: Jpserrat
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Zombienet tests - disputes on finalized blocks
author: Overkillus
topic: Tests
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "PVF worker: switch on seccomp networking restrictions"
author: mrcnski
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "crypto: `lazy_static` removed, light parser for address URI added"
author: michalkucharczyk
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
@@ -3,6 +3,9 @@
title: Different builder pattern constructors for XCM
author: franciscoaguirre
topic: runtime
doc:
- audience: Runtime Dev
description: |
+9
View File
@@ -0,0 +1,9 @@
title: Remove im-online pallet from Rococo and Westend
author: s0me0ne-unkn0wn
topic: Pallets
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: '[testnet] Remove Wococo stuff from BridgeHubRococo/AssetHubRococo'
author: bkontur 
topic: Bridges
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "frame-system: Add last_runtime_upgrade_spec_version"
author: bkchr
topic: Frame
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Fix Typo: `PalletXcmExtrinsicsBenchmark`"
author: joepetrowski
topic: Benchmarks
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "[ci] Enable zombienet jobs in PRs"
author: alvicsam
topic: Tests
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "implementers-guide: update github link"
author: ordian
topic: Documentation
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "[NPoS] Check if staker is exposed in paged exposure storage entries"
author: Ank4n
topic: Pallets
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "fix typo"
author: cuteolaf
topic: Documentation
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Beefy: small fixes"
author: serban300
topic: Bridges
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Deprecate `RewardDestination::Controller`
author: rossbulat
topic: XCM
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Make collator RPC mode non-experimental
author: skunert
topic: Cumulus
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Relax `force_default_xcm_version` for testnet system parachains"
author: bkontur
topic: Cumulus
doc:
- audience: Runtime Dev
description: n/a
crates: []
@@ -3,8 +3,11 @@
title: Add new flexible `pallet_xcm::transfer_assets()` call/extrinsic
author: acatangiu
topic: runtime
doc:
- audience: Builder
- audience: Runtime Dev
description: |
For complex combinations of asset transfers where assets and fees may have different reserves or
different reserve/teleport trust configurations, users can use the newly added `transfer_assets()`
@@ -21,6 +24,7 @@ migrations:
runtime: []
crates: pallet-xcm
crates:
- name: pallet-xcm
host_functions: []
+9
View File
@@ -0,0 +1,9 @@
title: "Pools: Add `MaxUnbonding` to metadata"
author: rossbulat
topic: Pallets
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Refactor ValidationError
author: eagr
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "polkadot-node-subsystems: `ChainApiBackend` added + polkadot-debug image version fixed"
author: michalkucharczyk
topic: Tests
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Update documentation for `SafeMode` and `TxPause` Pallets"
author: wilwade
topic: Documentation
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "PVF: Fix unshare `no such file or directory` error"
author: mrcnski
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "pallet-staking: Converts all math operations to safe"
author: gpestanaar
topic: Pallets
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Fixes cumulus README instructions"
author: gpestana
topic: Documentation
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "sp-api: Move macro related re-exports to `__private`"
author: bkchr
topic: Runtime API
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Adapt test worker to profile flag
author: eagr
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Remove `RuntimeApi` dependency on system parachain runtime code"
author: seadanda
topic: "System Parachains"
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "polkadot-parachain: one chain-spec for all"
author: michalkucharczyk
topic: "System Parachains"
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: '[NPoS] Use `EraInfo` to manipulate exposure in fast-unstake tests'
author: Ank4n
topic: Pallets,Tests
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "PVF: remove audit log access"
author: mrcnski
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "relay-chain-consensus: set a fork_choice"
author: michalkucharczyk
topic: Node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Add `on-chain-release-build` feature for Collectives Westend
author: liamaharon
topic: System Parachains
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Pools: Add ability to configure commission claiming permissions"
author: rossbulat
topic: Pallets
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Remove `dmp-queue`` pallet from Rococo Asset Hub and Bridge Hub
author: liamaharon
topic: Frame
doc:
- audience: Runtime Dev
description: n/a
crates: []
@@ -1,5 +1,8 @@
title: "PVF: Add Secure Validator Mode"
author: mrcnski
topic: node
doc:
- audience: Node Operator
description: |
+9
View File
@@ -0,0 +1,9 @@
title: "Do not pollute global base path with export genesis/wasm"
author: bkchr
topic: Cumulus
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Staking: `chill_other` takes stash instead of controller"
author: rossbulat
topic: Pallets
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: "Breaking: Remove long deprecated `AllPalletsWithoutSystemReversed`"
author: skunert
topic: Frame
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Set `frame_system::LastRuntimeUpgrade` after running `try-runtime migrations`
author: liamaharon
topic: Frame
doc:
- audience: Runtime Dev
description: n/a
crates: []
+9
View File
@@ -0,0 +1,9 @@
title: Remove `dmp_queue pallet` from Westend SP runtimes
author: liamaharon
topic: Frame
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: 'substrate-node: `NativeElseWasmExecutor` is no longer used'
author: michalkucharczyk
topic: node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: Remove `pov-recovery` race condition/Improve zombienet test
author: skunert
topic: testing
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: Withdraw Assets Before Checking Out in OnReapIdentity impl
author: joepetrowski
topic: xcm
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: Remove dependency on rand's SliceRandom shuffle implementation in `gossip-support`
author: rphmeier
topic: node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: Add missing glossary to ref docs
author: juangirini
topic: documentation
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: "impl guide: update PVF host page; add diagrams"
author: mrcnsk
topic: documentation
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: 'Bandersnatch: `ring-context` generic over domain size'
author: davxy
topic: node
doc:
- audience: Runtime Dev
description: n/a
crates: []
+12
View File
@@ -0,0 +1,12 @@
title: Ensure to cleanup state in `remove_member`
author: bkchr
topic: runtime
doc:
- audience: Runtime Dev
description: |
Cleans up the state properly if a member of a ranked collective is removed.
crates:
- name: pallet-ranked-collective
+10
View File
@@ -0,0 +1,10 @@
title: 'Bridges subtree update'
author: bkontur
topic: bridges
doc:
- audience: Runtime Dev
description: n/a
crates: []
+10
View File
@@ -0,0 +1,10 @@
title: Bridges update subtree
author: bkontur
topic: bridges
doc:
- audience: Runtime Dev
description: n/a
crates: []
+2
View File
@@ -0,0 +1,2 @@
Version 1.5.0 does not fully support `prddoc` yet.
While the list is complete, not all prdoc files have a valid or accurate content.
-9
View File
@@ -1,9 +0,0 @@
title: Ensure to cleanup state in remove_member
doc:
- audience: Runtime Dev
description: |
Cleanes up the state properly if a member of a ranked collective is removed.
crates:
- name: pallet-ranked-collective
+10
View File
@@ -17,6 +17,16 @@
"type": "string",
"description": "Title for the PR. This is what will show up in the release notes.\nif needed, you may provide a different title override for each audience in the `doc` property."
},
"author": {
"title": "Author handle",
"type": "string",
"description": "Author handle"
},
"topic": {
"title": "Topic",
"type": "string",
"description": "Topic"
},
"doc": {
"type": "array",
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
export PRODUCT=polkadot
export VERSION=${VERSION:-1.5.0}
PROJECT_ROOT=`git rev-parse --show-toplevel`
echo $PROJECT_ROOT
TMP=$(mktemp -d)
TEMPLATE_AUDIENCE="${PROJECT_ROOT}/scripts/release/templates/audience.md.tera"
TEMPLATE_CHANGELOG="${PROJECT_ROOT}/scripts/release/templates/changelog.md.tera"
DATA_JSON="${TMP}/data.json"
CONTEXT_JSON="${TMP}/context.json"
echo -e "TEMPLATE_AUDIENCE: \t$TEMPLATE_AUDIENCE"
echo -e "DATA_JSON: \t\t$DATA_JSON"
echo -e "CONTEXT_JSON: \t\t$CONTEXT_JSON"
# Create output folder
OUTPUT="${TMP}/changelogs/$PRODUCT/$VERSION"
echo -e "OUTPUT: \t\t$OUTPUT"
mkdir -p $OUTPUT
prdoc load -d "$PROJECT_ROOT/prdoc/$VERSION" --json > $DATA_JSON
# ls -al $DATA_JSON
cat $DATA_JSON | jq ' { "prdoc" : .}' > $CONTEXT_JSON
# ls -al $CONTEXT_JSON
# Fetch the list of valid audiences
SCHEMA_URL=https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
SCHEMA=$(curl -s $SCHEMA_URL | sed 's|^//.*||')
AUDIENCE_ARRAY=$(echo -E $SCHEMA | jq -r '."$defs".audience.oneOf[] | .const')
readarray -t audiences < <(echo "$AUDIENCE_ARRAY")
declare -p audiences
# Generate a changelog
echo "Generating changelog..."
tera -t "${TEMPLATE_CHANGELOG}" --env --env-key env "${CONTEXT_JSON}" > "$OUTPUT/changelog.md"
echo "Changelog ready in $OUTPUT/changelog.md"
# Generate a release notes doc per audience
for audience in "${audiences[@]}"; do
audience_id="$(tr [A-Z] [a-z] <<< "$audience")"
audience_id="$(tr ' ' '_' <<< "$audience_id")"
echo "Processing audience: $audience ($audience_id)"
export TARGET_AUDIENCE=$audience
tera -t "${TEMPLATE_AUDIENCE}" --env --env-key env "${CONTEXT_JSON}" > "$OUTPUT/relnote_${audience_id}.md"
done
# Show the files
tree -s -h -c $OUTPUT/
@@ -0,0 +1,13 @@
## Release {{ env.PRODUCT }} {{ env.VERSION }}
Changelog for `{{ env.TARGET_AUDIENCE }}`.
{% for file in prdoc -%}
#### PR #{{file.doc_filename.number}}: {{ file.content.title }}
{% for doc_item in file.content.doc %}
{%- if doc_item.audience == env.TARGET_AUDIENCE %}
{{ doc_item.description }}
{% endif -%}
{%- endfor %}
{%- endfor %}
@@ -0,0 +1,7 @@
## Changelog for `{{ env.PRODUCT | capitalize }} v{{ env.VERSION }}`
{% for file in prdoc | sort(attribute="doc_filename.number") -%}
{%- set author= file.content.author | default(value="n/a") -%}
{%- set topic= file.content.topic | default(value="n/a") -%}
- #{{file.doc_filename.number}}: {{ file.content.title }} (@{{ author }}) [{{ topic | capitalize }}]
{% endfor -%}