From 8f9d022818244477159671160fda0bf18349c2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 26 Jul 2024 10:42:00 +0200 Subject: [PATCH] Allow the usage of git-trailers for changelog messages and security issues --- CONTRIBUTING.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ cliff.toml | 31 ++++++++++++++++--- 2 files changed, 109 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f165ddd5..5032b054 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,88 @@ Thank you for taking the time to contribute to Matrix! This is the repository for Vodozemac, a Rust implementation of Olm and Megolm. +# Writing changelog entries + +We aim to maintain clear and informative changelogs that accurately reflect the +changes in our project. This guide will help you write useful changelog entries +using git-cliff, which fetches changelog entries from commit messages. + +## Commit Message Format + +We support the default Conventional Commits format, along with a specific git +trailer Changelog and Changelog(category). + +### Conventional Commits + +Conventional Commits are structured as follows: + +``` +(): +``` + +The type of changes which will be included in changelogs is one of the following: + + feat: A new feature + fix: A bug fix + doc: Documentation changes + refactor: Code refactoring + perf: Performance improvements + ci: Changes to CI configuration files and scripts + +The scope is optional and can specify the area of the codebase affected (e.g., +olm, cipher). + +### Changelog Trailer + +In addition to the conventional commit format, you can use a git trailer to +specify the changelog message explicitly. When the Changelog trailer is defined, +the value from the trailer will be used in the changelog instead of the commit's +first line. + + +#### Example Commit Message +``` +feat: Add a method to encode Ed25519 public keys to Base64 + +This patch adds the Ed25519PublicKey::to_base64() method, which allows us to +stringify Ed25519 and thus present them to users. It's also commonly used when +Ed25519 keys need to be inserted into JSON. + +Changelog: Added the Ed25519PublicKey::to_base64() method which can be used to +stringify the Ed25519 public key. +``` + +### Security fixes + +Please only use the Git trailer style for changelog entries related to security +issues since you need to specify and link to the relevant CVE and Github +advisories. Including all the necessary information is not possible if we'd like +to adhere to the convention of the first line in the commit message being bellow +72 characters. + +Example: + +``` +fix: Use a constant-time Base64 encoder for secret key material + +This patch fixes a security issue around a side-channel vulnerability[1] +when decoding secret key material using Base64. + +In some circumstances an attacker can obtain information about secret +secret key material via a controlled-channel and side-channel attack. + +This patch avoids the side-channel by switching to the base64ct crate +for the encoding, and more importantly, the decoding of secret key +material. + +Security-Impact: Low +CVE: CVE-2024-40640 +GitHub-Advisory: GHSA-j8cm-g7r6-hfpq + +Changelog: Use a constant-time Base64 encoder for secret key material +to mitigate side-channel attacks leaking secret key material. +``` + ## Sign off We ask that everybody who contributes to this project signs off their diff --git a/cliff.toml b/cliff.toml index e3a2463b..ab1ad538 100644 --- a/cliff.toml +++ b/cliff.toml @@ -17,7 +17,28 @@ body = """ {% for group, commits in commits | group_by(attribute="group") %} ### {{ group | upper_first }} {% for commit in commits %} - - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\ + {% set_global commit_message = commit.message -%} + {% set_global breaking = commit.breaking -%} + {% for footer in commit.footers -%} + {% if footer.token | lower == "changelog" -%} + {% set_global commit_message = footer.value -%} + {% elif footer.token | lower == "security-impact" -%} + {% set_global security_impact = footer.value -%} + {% elif footer.token | lower == "cve" -%} + {% set_global cve = footer.value -%} + {% elif footer.token | lower == "github-advisory" -%} + {% set_global github_advisory = footer.value -%} + {% endif -%} + {% endfor -%} + - {% if breaking %}[**breaking**] {% endif %}{{ commit_message | upper_first }} + {% if security_impact -%} + (\ + {{ security_impact | upper_first }}\ + {% if cve -%}, [{{ cve | upper }}](https://www.cve.org/CVERecord?id={{ cve }}){% endif -%}\ + {% if github_advisory -%}, [{{ github_advisory | upper }}](https://github.com/matrix-org/vodozemac/security/advisories/{{ github_advisory }}){% endif -%} + ) + {% endif -%} + {# TODO: Undefine all the variables here #} {% endfor %} {% endfor %}\n """ @@ -39,16 +60,18 @@ commit_preprocessors = [ ] # regex for parsing and grouping commits commit_parsers = [ - { message = ".*[sS]ecurity", group = "Security"}, + { footer = "Security-Impact:", group = "Security" }, + { footer = "CVE:", group = "Security" }, + { footer = "GitHub-Advisory:", group = "Security" }, { message = "^feat", group = "Features"}, { message = "^fix", group = "Bug Fixes"}, { message = "^doc", group = "Documentation"}, { message = "^perf", group = "Performance"}, { message = "^refactor", group = "Refactor"}, - { message = "^style", group = "Styling"}, - { message = "^test", group = "Testing"}, { message = "^chore\\(release\\): prepare for", skip = true}, { message = "^chore", skip = true}, + { message = "^style", group = "Styling", skip = true}, + { message = "^test", skip = true}, { message = "^ci", skip = true}, ] # filter out the commits that are not matched by commit parsers