• Stars
    star
    964
  • Rank 47,452 (Top 1.0 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 5 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A GitHub Action that ensures that your PR title matches the Conventional Commits spec

action-semantic-pull-request

This is a GitHub Action that ensures that your pull request titles match the Conventional Commits spec. Typically, this is used in combination with a tool like semantic-release to automate releases.

Used by: Electron · Vite · Excalidraw · Apache · Vercel · Microsoft · Firebase · AWS – and many more.

Examples

Valid pull request titles:

  • fix: Correct typo
  • feat: Add support for Node.js 18
  • refactor!: Drop support for Node.js 12
  • feat(ui): Add Button component

Note that since pull request titles only have a single line, you have to use ! to indicate breaking changes.

See Conventional Commits for more examples.

Installation

  1. If your goal is to create squashed commits that will be used for automated releases, you'll want to configure your GitHub repository to use the squash & merge strategy and tick the option "Default to PR title for squash merge commits".
  2. Add the action with the following configuration:
name: "Lint PR"

on:
  pull_request_target:
    types:
      - opened
      - edited
      - synchronize

permissions:
  pull-requests: read

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

See the event triggers documentation below to learn more about what pull_request_target means.

Configuration

The action works without configuration, however you can provide options for customization.

The following terminology helps to understand the configuration options:

feat(ui): Add `Button` component
^    ^    ^
|    |    |__ Subject
|    |_______ Scope
|____________ Type
        with:
          # Configure which types are allowed (newline-delimited).
          # Default: https://github.com/commitizen/conventional-commit-types
          types: |
            fix
            feat
          # Configure which scopes are allowed (newline-delimited).
          # These are regex patterns auto-wrapped in `^ $`.
          scopes: |
            core
            ui
            JIRA-\d+
          # Configure that a scope must always be provided.
          requireScope: true
          # Configure which scopes are disallowed in PR titles (newline-delimited).
          # For instance by setting the value below, `chore(release): ...` (lowercase)
          # and `ci(e2e,release): ...` (unknown scope) will be rejected.
          # These are regex patterns auto-wrapped in `^ $`.
          disallowScopes: |
            release
            [A-Z]+
          # Configure additional validation for the subject based on a regex.
          # This example ensures the subject doesn't start with an uppercase character.
          subjectPattern: ^(?![A-Z]).+$
          # If `subjectPattern` is configured, you can use this property to override
          # the default error message that is shown when the pattern doesn't match.
          # The variables `subject` and `title` can be used within the message.
          subjectPatternError: |
            The subject "{subject}" found in the pull request title "{title}"
            didn't match the configured pattern. Please ensure that the subject
            doesn't start with an uppercase character.
          # If you use GitHub Enterprise, you can set this to the URL of your server
          githubBaseUrl: https://github.myorg.com/api/v3
          # If the PR contains one of these newline-delimited labels, the
          # validation is skipped. If you want to rerun the validation when
          # labels change, you might want to use the `labeled` and `unlabeled`
          # event triggers in your workflow.
          ignoreLabels: |
            bot
            ignore-semantic-pull-request
          # If you're using a format for the PR title that differs from the traditional Conventional
          # Commits spec, you can use these options to customize the parsing of the type, scope and
          # subject. The `headerPattern` should contain a regex where the capturing groups in parentheses
          # correspond to the parts listed in `headerPatternCorrespondence`.
          # See: https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-commits-parser#headerpattern
          headerPattern: '^(\w*)(?:\(([\w$.\-*/ ]*)\))?: (.*)$'
          headerPatternCorrespondence: type, scope, subject

Work-in-progress pull requests

For work-in-progress PRs you can typically use draft pull requests from GitHub. However, private repositories on the free plan don't have this option and therefore this action allows you to opt-in to using the special "[WIP]" prefix to indicate this state.

Example:

[WIP] feat: Add support for Node.js 18

This will prevent the PR title from being validated, and pull request checks will remain pending.

Attention: If you want to use the this feature, you need to grant the pull-requests: write permission to the GitHub Action. This is because the action will update the status of the PR to remain in a pending state while [WIP] is present in the PR title.

name: "Lint PR"

permissions:
  pull-requests: write

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          wip: true

Legacy configuration for validating single commits

When using "Squash and merge" on a PR with only one commit, GitHub will suggest using that commit message instead of the PR title for the merge commit. As it's easy to commit this by mistake this action supports two configuration options to provide additional validation for this case.

          # If the PR only contains a single commit, the action will validate that
          # it matches the configured pattern.
          validateSingleCommit: true
          # Related to `validateSingleCommit` you can opt-in to validate that the PR
          # title matches a single commit to avoid confusion.
          validateSingleCommitMatchesPrTitle: true

However, GitHub has introduced an option to streamline this behaviour, so using that instead should be preferred.

Event triggers

There are two events that can be used as triggers for this action, each with different characteristics:

  1. pull_request_target: This allows the action to be used in a fork-based workflow, where e.g. you want to accept pull requests in a public repository. In this case, the configuration from the main branch of your repository will be used for the check. This means that you need to have this configuration in the main branch for the action to run at all (e.g. it won't run within a PR that adds the action initially). Also if you change the configuration in a PR, the changes will not be reflected for the current PR – only subsequent ones after the changes are in the main branch.
  2. pull_request: This configuration uses the latest configuration that is available in the current branch. It will only work if the branch is based in the repository itself. If this configuration is used and a pull request from a fork is opened, you'll encounter an error as the GitHub token environment parameter is not available. This option is viable if all contributors have write access to the repository.

Outputs

In case the validation fails, this action will populate the error_message ouput.

An output can be used in other steps, for example to comment the error message onto the pull request.

Example
name: "Lint PR"

on:
  pull_request_target:
    types:
      - opened
      - edited
      - synchronize

permissions:
  pull-requests: write

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5
        id: lint_pr_title
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - uses: marocchino/sticky-pull-request-comment@v2
        # When the previous steps fails, the workflow would stop. By adding this
        # condition you can continue the execution with the populated error message.
        if: always() && (steps.lint_pr_title.outputs.error_message != null)
        with:
          header: pr-title-lint-error
          message: |
            Hey there and thank you for opening this pull request! 👋🏼
            
            We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.

            Details:
            
            ```
            ${{ steps.lint_pr_title.outputs.error_message }}
            ```

      # Delete a previous comment when the issue has been resolved
      - if: ${{ steps.lint_pr_title.outputs.error_message == null }}
        uses: marocchino/sticky-pull-request-comment@v2
        with:   
          header: pr-title-lint-error
          delete: true

More Repositories

1

next-intl

🌐 Internationalization (i18n) for Next.js
TypeScript
2,442
star
2

next-query-params

Convenient state management of query parameters in Next.js apps
TypeScript
163
star
3

next-client-script

Supercharge the performance of your Next.js apps by using a minimal client runtime 🚀
TypeScript
77
star
4

react-keep-state

Make React components keep their state, even if they're unmounted.
JavaScript
30
star
5

dokku-node-hello-world

An instruction on how to deploy a node app to a server that is running dokku.
JavaScript
29
star
6

react-hooks

A collection of commonly used hooks for React apps
TypeScript
16
star
7

friends-ui

An animation experiment.
JavaScript
13
star
8

street-photography-viewer

TypeScript
12
star
9

atom-format-javascript-comment

Formats your JavaScript comments
JavaScript
8
star
10

gulp-wordpress-template

A very basic proof-of-concept, showing that gulp can work as a replacement for MAMP/XAMPP and also extend their features for SASS compiling for example.
PHP
7
star
11

multi-sitemap

Painless creation of large dynamic sitemaps that consist of multiple files
TypeScript
6
star
12

next-intl-example-rsc

TypeScript
6
star
13

amann.work

My personal website featuring some projects I've worked on.
JavaScript
4
star
14

graphql-filter-fragment

Filters a data structure by a GraphQL fragment
TypeScript
3
star
15

jest-globals-bug

JavaScript
3
star
16

animated-routes

JavaScript
2
star
17

semantic-release-test

Only for personal testing …
JavaScript
2
star
18

webpack-top-level-await

JavaScript
2
star
19

ea-ss24-sem4

TypeScript
2
star
20

next-dynamic-loading

CSS
1
star
21

eslint-plugin-react-test

TypeScript
1
star
22

nextjs-tsconfig-paths

JavaScript
1
star
23

nextjs-commerce-example

TypeScript
1
star
24

babel-preset-react-hot

Babel preset for React hot module replacement and error catching
JavaScript
1
star
25

nextjs-server-context

TypeScript
1
star
26

next-compile-bug

TypeScript
1
star
27

photo-gallery

A gesture-based photo gallery
SCSS
1
star
28

nextjs-bug-use-server

JavaScript
1
star
29

nextjs13-query-params

TypeScript
1
star
30

vite-plugin-pretty-css-modules

Use prettier generated class names in development, while applying minification in production.
TypeScript
1
star
31

nextjs-bugrepro-sitemap

TypeScript
1
star
32

next-intl-mixed-routing

TypeScript
1
star
33

nextjs-bug-repro-middleware-import

TypeScript
1
star
34

nodejs-esm-test

JavaScript
1
star