diff --git a/nix/general/default.nix b/nix/general/default.nix index 7973b08..60f29b1 100644 --- a/nix/general/default.nix +++ b/nix/general/default.nix @@ -8,7 +8,9 @@ importingFlake: { imports = [ ./action-versions.nix (importApply ./devshell.nix args) + (importApply ./git-cliff.nix args) (importApply ./pre-commit-hooks.nix args) + ./ff-merge_workflow.nix ]; # Install all defined GitHub workflows diff --git a/nix/general/devshell.nix b/nix/general/devshell.nix index 8fb6ad4..00ca493 100644 --- a/nix/general/devshell.nix +++ b/nix/general/devshell.nix @@ -2,7 +2,9 @@ importingFlake: { perSystem = { lib, pkgs, ... }: { - devshells.general.packages = lib.attrValues { inherit (pkgs) prek; }; + devshells.general.packages = lib.attrValues { + inherit (pkgs) prek git-cliff; + }; filegen.settings.files = [ { diff --git a/nix/general/ff-merge_workflow.nix b/nix/general/ff-merge_workflow.nix new file mode 100644 index 0000000..b00da0f --- /dev/null +++ b/nix/general/ff-merge_workflow.nix @@ -0,0 +1,43 @@ +{ config, ... }: +let + allowed-actions = config.famedly.standards.allowed-action-versions; +in +{ + perSystem = + { ... }: + { + githubActions.workflows.ff-merge = { + name = "fast-forward"; + + on.issueComment.types = [ + "created" + "edited" + ]; + + jobs.fast-forward = { + if_ = "\${{ contains(github.event.comment.body, '/fast-forward') && github.event.issue.pull_request }}"; + + runsOn = "ubuntu-latest"; + + permissions = { + contents = "write"; + pull-requests = "write"; + issues = "write"; + }; + + steps = [ + { + name = "Fast forwarding"; + uses = allowed-actions."sequoia-pgp/fast-forward".uses; + with_ = { + merge = true; + # Only post comments about fast-forwarding if + # there is an error. + comment = "on-error"; + }; + } + ]; + }; + }; + }; +} diff --git a/nix/general/git-cliff.nix b/nix/general/git-cliff.nix new file mode 100644 index 0000000..29654b6 --- /dev/null +++ b/nix/general/git-cliff.nix @@ -0,0 +1,14 @@ +importingFlake: { + perSystem = + { ... }: + { + filegen.settings.files = [ + { + type = "copy"; + target = "./.config/cliff.toml"; + source = ../../standards/cliff.toml; + clobber = true; + } + ]; + }; +} diff --git a/standards/allowed-github-actions.toml b/standards/allowed-github-actions.toml index 7f5dec8..d669aff 100644 --- a/standards/allowed-github-actions.toml +++ b/standards/allowed-github-actions.toml @@ -9,3 +9,7 @@ ref = "51f3067b56fe8ae331890c77d4e454f6d60615ff" ["cachix/cachix-action"] rev = "v17" ref = "1eb2ef646ac0255473d23a5907ad7b04ce94065c" + +["sequoia-pgp/fast-forward"] +rev = "v1.0.0" +ref = "ea7628bedcb0b0b96e94383ada458d812fca4979" diff --git a/standards/cliff.toml b/standards/cliff.toml new file mode 100644 index 0000000..807e8cd --- /dev/null +++ b/standards/cliff.toml @@ -0,0 +1,83 @@ +# git-cliff ~ default configuration file +# https://git-cliff.org/docs/configuration +# +# Lines starting with "#" are comments. +# Configuration options are organized into tables and keys. +# See documentation for more information on available options. + +[changelog] +# template for the changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#introduction +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in commits %} + - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ + {% if commit.breaking %}[**breaking**] {% endif %}\ + {{ commit.message | upper_first }}\ + {% endfor %} +{% endfor %}\n +""" +# template for the changelog footer +footer = """ + +""" +# remove the leading and trailing s +trim = true +# postprocessors +postprocessors = [ + # { pattern = '', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL +] +# render body even when there are no releases to process +# render_always = true +# output file path +# output = "test.md" + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + # Replace issue numbers + #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, + # Check spelling of the commit with https://github.com/crate-ci/typos + # If the spelling is incorrect, it will be automatically fixed. + #{ pattern = '.*', replace_command = 'typos --write-changes -' }, +] +# regex for parsing and grouping commits +commit_parsers = [ + { 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\\(deps.*\\)", skip = true }, + { message = "^chore\\(pr\\)", skip = true }, + { message = "^chore\\(pull\\)", skip = true }, + { message = "^chore|^ci", group = "Miscellaneous Tasks" }, + { body = ".*security", group = "Security" }, + { message = "^revert", group = "Revert" }, +] +# filter out the commits that are not matched by commit parsers +filter_commits = false +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest"