From 78845372840eae451b8076cd54c0f8a438368ba8 Mon Sep 17 00:00:00 2001 From: Sergei Petrosian Date: Thu, 27 Apr 2023 17:01:03 +0200 Subject: [PATCH] ci: Add commitlint GitHub action to ensure conventional commits with feedback For more information, see Conventional Commits format in Contribute https://linux-system-roles.github.io/contribute.html#conventional-commits-format Signed-off-by: Sergei Petrosian --- .ansible-lint | 2 +- .commitlintrc.js | 141 +++++++++++++++++++++++++++++++ .github/workflows/commitlint.yml | 44 ++++++++++ 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 .commitlintrc.js create mode 100644 .github/workflows/commitlint.yml diff --git a/.ansible-lint b/.ansible-lint index 824879b..d3063d3 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,8 +1,8 @@ --- profile: production extra_vars: - test_playbook: tests_default.yml network_provider: nm + test_playbook: tests_default.yml kinds: - yaml: "**/meta/collection-requirements.yml" - playbook: "**/tests/get_coverage.yml" diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000..f8a39ba --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1,141 @@ +module.exports = { + parserPreset: 'conventional-changelog-conventionalcommits', + rules: { + 'body-leading-blank': [1, 'always'], + 'body-max-line-length': [2, 'always', 100], + 'footer-leading-blank': [1, 'always'], + 'footer-max-line-length': [2, 'always', 100], + 'header-max-length': [2, 'always', 100], + 'subject-case': [ + 2, + 'never', + ['start-case', 'pascal-case', 'upper-case'], + ], + 'subject-empty': [2, 'never'], + 'subject-full-stop': [2, 'never', '.'], + 'type-case': [2, 'always', 'lower-case'], + 'type-empty': [2, 'never'], + 'type-enum': [ + 2, + 'always', + [ + 'build', + 'chore', + 'ci', + 'docs', + 'feat', + 'fix', + 'perf', + 'refactor', + 'revert', + 'style', + 'test', + 'tests', + ], + ], + }, + prompt: { + questions: { + type: { + description: "Select the type of change that you're committing", + enum: { + feat: { + description: 'A new feature', + title: 'Features', + emoji: '✨', + }, + fix: { + description: 'A bug fix', + title: 'Bug Fixes', + emoji: '🐛', + }, + docs: { + description: 'Documentation only changes', + title: 'Documentation', + emoji: '📚', + }, + style: { + description: + 'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)', + title: 'Styles', + emoji: '💎', + }, + refactor: { + description: + 'A code change that neither fixes a bug nor adds a feature', + title: 'Code Refactoring', + emoji: '📦', + }, + perf: { + description: 'A code change that improves performance', + title: 'Performance Improvements', + emoji: '🚀', + }, + test: { + description: 'Adding missing tests or correcting existing tests', + title: 'Tests', + emoji: '🚨', + }, + tests: { + description: 'Adding missing tests or correcting existing tests', + title: 'Tests', + emoji: '🚨', + }, + build: { + description: + 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)', + title: 'Builds', + emoji: '🛠', + }, + ci: { + description: + 'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)', + title: 'Continuous Integrations', + emoji: '⚙️', + }, + chore: { + description: "Other changes that don't modify src or test files", + title: 'Chores', + emoji: '♻️', + }, + revert: { + description: 'Reverts a previous commit', + title: 'Reverts', + emoji: '🗑', + }, + }, + }, + scope: { + description: + 'What is the scope of this change (e.g. component or file name)', + }, + subject: { + description: + 'Write a short, imperative tense description of the change', + }, + body: { + description: 'Provide a longer description of the change', + }, + isBreaking: { + description: 'Are there any breaking changes?', + }, + breakingBody: { + description: + 'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself', + }, + breaking: { + description: 'Describe the breaking changes', + }, + isIssueAffected: { + description: 'Does this change affect any open issues?', + }, + issuesBody: { + description: + 'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself', + }, + issues: { + description: 'Add issue references (e.g. "fix #123", "re #123".)', + }, + }, + }, +}; diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000..720b954 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,44 @@ +name: Commitlint +on: # yamllint disable-line rule:truthy + pull_request: + types: + - opened + - synchronize + - reopened + - edited + merge_group: + branches: + - main + types: + - checks_requested +permissions: + contents: read +jobs: + commit-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install conventional-commit linter + run: npm install @commitlint/config-conventional @commitlint/cli + + # Finding the commit range is not as trivial as it may seem. + # + # At this stage, git's HEAD does not refer to the latest commit in the + # PR, but rather to the merge commit inserted by the PR. So instead we + # have to get 'HEAD' from the PR event. + # + # One cannot use the number of commits + # (github.event.pull_request.commits) to find the start commit + # i.e. HEAD~N does not work, this breaks if there are merge commits. + - name: Run commitlint on commits + run: >- + npx commitlint --from '${{ github.event.pull_request.base.sha }}' + --to '${{ github.event.pull_request.head.sha }}' --verbose + + - name: Run commitlint on PR title + run: >- + echo '${{ github.event.pull_request.title }}' | + npx commitlint --verbose