Skip to content

Assign labels to pull-request parsing conventional commits standard

License

Notifications You must be signed in to change notification settings

mauroalderete/action-assign-labels

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

action-assign-labels

Assign labels to pull-request parsing conventional commits standard

 

 

Content

 

👋 Introducing action-assign-labels

action-assign-labels is a Javascript GitHub Action that allows you to automate the label assignment to help you to identify and categorize a pull request.

It finds into commits pushed in a pull request to set the conventional-commits types to determine which labels must be assigned and which must be removed.

With a simple scheme written in yaml format, you will be able to customize the combinations between conventional-commits nouns and your labels names to integrate them easily into your unique workflow.

🔥 Features

Fix, Feature, BREAKING CHANGE and more

action-assign-labels uses the conventional-commits convention to extract the prefix from the commits and determine what labels will be assigned.

-- What nouns are available? -- The ones you need!

You can use a simple conventional-commits scheme from a file or direct entry to customize your own convention.

Assign Labels when you need it

It is not necessary to execute action-assign-labels just later pull_request or pull_request_target events are triggered. You can use the optional entry pull-request-number to assign labels to the specific pull requests at any time.

Output detailed

Through the outputs, you can access details of all label lists affected by the action. You can know the labels added, and removed and at the same time, you can get a snapshot of the previous status and new status. In this way, you can available all data to take a better workflow decision and integrate it easily with others' actions.

By the way, did you already take a look at action-verify-labels? It works great with action-assign-labels.

Ommite changes in server

Using the apply-changes entry you will be able to execute the action without it making any changes to the server. This will allow you to take advantage of the available outputs and make the best decisions for your workflow.

Status API

action-assign-labels provide the action-status and action-message outputs to notify you about any error event during the execution. In this way, you can take a better decision.

Summary

action-assign-labels generate a friendly summary to that you can see speedily the operation result, pull request associated and end status.

💻 How to use action-assign-labels

Simply add a checkout to your repository. Then, add a new step in your workflow using the mauroalderete/action-assign-labels action. And ready, you can start to configure it with the behaviour that you wish. See examples

  - name: Execute assign labels
    id: action-assign-labels
    uses: mauroalderete/action-assign-labels@v1
    with:
      pull-request-number: ${{ github.event.pull_request.number }}
      github-token: ${{ secrets.GITHUB_TOKEN }}
      conventional-commits: |
        conventional-commits:
          - type: 'fix'
            nouns: ['FIX', 'Fix', 'fix', 'FIXED', 'Fixed', 'fixed']
            labels: ['bug']
          - type: 'feature'
            nouns: ['FEATURE', 'Feature', 'feature', 'FEAT', 'Feat', 'feat']
            labels: ['feature']
          - type: 'breaking_change'
            nouns: ['BREAKING CHANGE', 'BREAKING', 'MAJOR']
            labels: ['BREAKING CHANGE']
      maintain-labels-not-matched: false
      apply-changes: true

Inputs

Input Data type Required Default Description
github-token string true '' The Github token.
conventional-commits string true '' String with the YAML object or path to file YAML that contains a list with conventional commits and the labels matching that must be assigned
pull-request-number number false 0 The pull request's number where labels will be assigned
maintain-labels-not-matched boolean false false You should keep the conventional commit tags assigned to the pull-request, even though they are no longer referenced within commits.
apply-changes boolean false true Should will be executing the action and save any change to the repository.

github-token

It is always required, it doesn't matter if changes will be applied to the repository or not. It is used to request data about pull requests, his labels and his commits from GitHub REST API.

conventional-commits

This entry receives a conventional-commits scheme in YAML format.

This scheme is used to relate a specific conventional-commit type with the labels that must be assigned when a commit contains a prefix equal to some noun indicated in the scheme.

A conventional-commit type consists of three elements:

- type: 'fix'
  nouns: ['fix', 'fixed']
  labels: ['bug']
  • type, is a simple title to identify the conventional-commit type that we are defining.
  • nouns, is a list of all prefix variants that indicate to us if a commit belongs to the conventional-commits type that we are defining.
  • labels, is a list of the all labels that must be assigned to a pull request in case of that it contains some commit of the conventional-commit type that we are defining.

A conventional-commits scheme complete consist of a list of the conventional-commit types:

conventional-commits:
        - type: 'fix'
          nouns: ['fix', 'fixed']
          labels: ['bug']
        - type: 'feature'
          nouns: ['feat', 'feature']
          labels: ['enhancement']
        - type: 'breaking_change'
          nouns: ['BREAKING CHANGE']
          labels: ['BREAKING CHANGE']

This way, you can create all conventional-commits types that you need easily.

There is two way to enter a scheme in the action. One way is entry a multiline string with the yaml object:

- uses: mauroalderete/action-assign-labels@v1
  with:
    conventional-commits: |
      conventional-commits:
        - type: 'fix'
          nouns: ['FIX', 'Fix', 'fix', 'FIXED', 'Fixed', 'fixed']
          labels: ['bug']
        - type: 'feature'
          nouns: ['FEATURE', 'Feature', 'feature', 'FEAT', 'Feat', 'feat']
          labels: ['feature']
        - type: 'breaking_change'
          nouns: ['BREAKING CHANGE', 'BREAKING', 'MAJOR']
          labels: ['BREAKING CHANGE']

The other way is entry a path to the yaml file that contains the scheme.

- uses: mauroalderete/action-assign-labels@v1
  with:
    conventional-commits: './some/place/MyConventionalCommitScheme.yaml'

If you choose to pass a file, remember entry with workdir path or relative path.

pull-request-number

This is an optional entry. If you use action-assign-label when a type event pull_request or pull_requesttarget is triggered the pull request number is getting directly from the GitHub Action context. You don't need to provide it.

Otherwise, if you plan to use this action on another type of event then is needed to provide a pull request number valid, since this value will isn't available in the GitHub Action context.

A pull request number valid is any integer positive non-zero.

maintain-labels-not-matched

It determines if labels from the pull requests and configured in the scheme must or not be removed when none of the commits pushed reference it.

By default is false. This means that when a label assigned is not matched any commit, this label will be removed.

This flag only has effect over labels defines in the conventional-commits scheme. This means that any label assigned that it isn't contained in the scheme will be ignored.

For example, we suppose a pull request has the bug label assigned that according to the conventional-commits scheme, only must be assigned if some commit contains the prefix fix:. What should happen to the label if suddenly the pull request no longer has any commits with the fixed prefix?

For this situations, the maintain-labels-not-matched entry allows you to determine if the 'bug' label must to remove or conserved.

Why would you want to conserve it? May be you need to be more flexible with the labels assignment and, you wish to allow them can be assigned manually.

Why would you want to removed it? May be you need to be more strict with the label assignment and, garantee a unique way of the assign them.

apply-changes

Indique if the action must send a request to set the labels in the pull request or, otherwise, it mustn't make any change in the pull request.

You may use apply-changes in false to check the next label's status that the pull request should have without any risk.

Allows you to extend the assignment conditions to evaluate the outputs snapshots with additional criteria.

Outputs

Output Description
labels-previous List of the labels assigned before the updating
labels-assigned List of the labels added
labels-removed List of the labels removed
labels-next List of the labels assigned after the updating
action-status Execution status of the action
action-message Message associated to the current status of the action

Action status

We can use the action-status and action-message outputs to check if the action passed or had a problem.

There are many statuses possible. In case of error, the action-message contains a description of the error. The status reveals the last operation that action-assign-labels was executing before it was interrupted.

If the action-status is END means the action-assign-labels ended correctly.

action-status description
LOAD_DEPENDENCIES Something was wrong when to try inject and initialize dependencies
LOAD_CONTEXT Failed to read and parse the GitHub Action context file
PARSE_AND_ASSIGN There was a problem with parsing or assignment labels
OUTPUT Failed the treatment of the outputs
END The action finished successfully

Examples

Here are some common examples:

Basic use

name: Labels Test

on:
  pull_request:
    branches: [main]
    types:
      [opened, reopened, labeled, unlabeled]

jobs:
  assign-labels:
    runs-on: ubuntu-latest
    name: Assign labels in pull request
    if: github.event.pull_request.merged == false
    steps:
      - uses: actions/checkout@v3

      - uses: mauroalderete/action-assign-labels@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          conventional-commits: |
            conventional-commits:
              - type: 'fix'
                nouns: ['FIX', 'Fix', 'fix', 'FIXED', 'Fixed', 'fixed']
                labels: ['bug']

Extended use

  - name: Execute assign labels
    id: action-assign-labels
    uses: mauroalderete/action-assign-labels@v1
    with:
      pull-request-number: ${{ github.event.pull_request.number }}
      github-token: ${{ secrets.GITHUB_TOKEN }}
      conventional-commits: |
        conventional-commits:
          - type: 'fix'
            nouns: ['FIX', 'Fix', 'fix', 'FIXED', 'Fixed', 'fixed']
            labels: ['bug']
          - type: 'feature'
            nouns: ['FEATURE', 'Feature', 'feature', 'FEAT', 'Feat', 'feat']
            labels: ['feature']
          - type: 'breaking_change'
            nouns: ['BREAKING CHANGE', 'BREAKING', 'MAJOR']
            labels: ['BREAKING CHANGE']
          - type: 'documentation'
            nouns: ['doc','docu','document','documentation']
            labels: ['documentation']
          - type: 'build'
            nouns: ['build','rebuild']
            labels: ['build']
          - type: 'config'
            nouns: ['config', 'conf', 'cofiguration', 'configure']
            labels: ['config']
      maintain-labels-not-matched: false
      apply-changes: true

Without apply and parsing output

  - name: Execute assign labels
    id: action-assign-labels
    uses: mauroalderete/action-assign-labels@v1
    with:
      github-token: ${{ secrets.GITHUB_TOKEN }}
      conventional-commits: |
        conventional-commits:
          - type: 'fix'
            nouns: ['FIX', 'Fix', 'fix', 'FIXED', 'Fixed', 'fixed']
            labels: ['bug']
      apply-changes: false

  - name: Stuff something if PR not contain a fix commit type
    if: ${{ contains(fromJson( steps.action-assign-labels.labels-next ), 'bug') }}
    run:
      ...
  
  - name: Stuff something if label bug was removed
    if: ${{ contains(fromJson( steps.action-assign-labels.labels-removed ), 'bug') }}
    run:
      ...

🔨 How to Set up action-assign-labels for Development?

You set up action-assign-labels locally with a few easy steps.

  1. Clone the repository
git clone https://github.com/mauroalderete/action-assign-labels
  1. Change the working directory
cd action-assign-labels
  1. Install dependencies
npm install
  1. Install development tools
curl https://get.volta.sh | bash
export VOLTA_HOME=$HOME/.volta
export PATH=$VOLTA_HOME:$PATH
npm install -g @vercel/ncc

For bash, zsh, and fish, the Volta installer updates your console login scripts so that you won't need to export VOLTA_HOME or update PATH again. See Volta's Getting Started page for more details.

Scripts

Lint

npm run lint

Unit tests

npm run test

Build

It execute lint and unit tests previously. It makes a distributable version into /dist folder.

npm run build

Deploy

To deploy and implement the changes in the GitHub Action, you need to generate a new build and push the changes to the repository, including the dist folder.

npm run build

The action.yml invokes the dist/index.js when a node runner executes it.

This build command uses @vercel/ncc to package the source code into a single file. Follow the GitHub Action guide to Creating a JavaScript Action for more details.

ncc is added as a development dependency.

🔧 How to work?

The action runs on ubuntu runner as javascript action through node v20.x.

The objective of this project is to provide a scalable project to handle label assignments according to conventional-commits spec. This way can be integrated into most workflow that searches a standard environment development.

To easily maintain, the source is divided into many layers. Use injection dependency pattern to handle the dependencies and simplify the testing.

Each layer joins a series of modules with constructor, class and implementation of uses cases.

This project has the minimum external dependencies:

In some cases, I decided to extract and adapt the single code lines directly from thirty repositories in place of importing all library for a simple feature. In this case, the regexp to identify a noun and scope from the commit message used by conventional-commits-parser package.

Unlike the other GitHub Actions, the entry point of action-assign-labels contains a unique line code that invokes the main method in the app layer. It allows us to execute tests with the maximum coverage, and improve meanly the maintainability and stability of the solution.

To handle the execution flow it contains a simple pattern to trace the action state.

You can find all source code is documented through jsdoc convention adapted to vscode limitations.

If you have any questions, felt you free to make a comment through a issue.

If you want to improve action-assign-labels o simply report a bug, please check the contributing section to know how to do it.

Supported Versions

At this time, these are the supported versions:

Version Supported
1.5 or higher
<= 1.4.9 uses node@16 but GitHub Action left Node16 support

🛡️ License

This project is licensed under the MIT License - see the LICENSE file for details.

🤝 Contributing to action-assign-labels

Any kind of positive contribution is welcome! Please help us to grow by contributing to the project.

If you wish to contribute, you can work on any issue or create one on your own. After adding your code, please send us a Pull Request.

Please read CONTRIBUTING for details on our CODE OF CONDUCT, and the process for submitting pull requests to us.

🙏 Support

We all need support and motivation. action-assign-labels is not an exception. Please give this project a ⭐ start to encourage and show that you liked it. Don't forget to leave a ⭐ star before you move away.

If you found the app helpful, consider supporting us with a coffee.

Invitame un café en cafecito.app

About

Assign labels to pull-request parsing conventional commits standard

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published