Code Monkey home page Code Monkey logo

multi-labeler's Introduction

Multi Labeler

codecov CodeFactor Release License MIT

Multi labeler for title, body, comments, commit messages, branch, base branch, author or files. Optionally, generate a status check based on the labels.

Who is using fuxingloh/multi-labeler?

Features

  • Single compiled javascript file, extremely fast. Use fewer credits!
  • Append based multi-labeler, using .github/labeler.yml as config.
  • Automatically fail if labeler.yml is malformed, type-checked.
  • Set label to sync for conditional labeling, removed if condition failed.
  • Regex Matcher:
    • PR/Issue title
    • PR/Issue body
    • PR/Issue comments
    • PR commit messages
    • PR branch name
    • PR base (target) branch name
  • File Matcher:
    • Files count
    • Files any glob match
    • Files all glob match
  • Author Matcher
  • Generate status checks:
    • Any label match
    • All label match

Usage

.github/workflow/labeler.yml

on:
  pull_request_target:
  # for OSS with public contributions (forked PR)

  pull_request:
  # Useful for triaging code review, and generate compliance status check.
  # Semantic release? Done.
  # Make a file change in a mono repo. Tag the mono repo getting changed to generate better release!

  issues:
  # Useful for triaging error!
  # '- [x] Is this a bug?' = 'bug' label!

  issue_comment:
  # To pickup comment body in pr or issue and generate a label.
  # Imagine someone comment 'Me too, I get TimeoutException from ...' in comment body.
  # Generate a 'bug/timeout' label for better triaging!

permissions:
  # Setting up permissions in the workflow to limit the scope of what it can do. Optional!
  contents: read # the config file
  issues: write # for labeling issues (on: issues)
  pull-requests: write # for labeling pull requests (on: pull_request_target or on: pull_request)
  statuses: write # to generate status
  checks: write # to generate status

jobs:
  labeler:
    name: Labeler
    runs-on: ubuntu-latest
    steps:
      # follows semantic versioning. Lock to different version: v1, v1.5, v1.5.0 or use a commit hash.
      - uses: fuxingloh/multi-labeler@v4 # v4
        with:
          github-token: ${{secrets.GITHUB_TOKEN}} # optional, default to '${{ github.token }}'
          config-path: .github/labeler.yml # optional, default to '.github/labeler.yml'
          config-repo: my-org/my-repo # optional, default to '${{ github.repository }}'

.github/labeler.yml

# .github/labeler.yml

version: v1

labels:
  - label: 'feat'
    sync: true # remove label if match failed, default: false (pull_request/issue only)
    matcher:
      # Matcher will match on any 8 matchers
      title: '^feat:.*'
      body: '/feat'
      comment: '/feat'
      branch: '^feat/.*'
      baseBranch: '^feat/.*'
      commits: '^feat:.*'
      author:
        - github-actions
        - fuxingloh
      files:
        any: ['app/*']
        all: ['!app/config/**']
        count:
          gte: 1
          lte: 1000

# Optional, if you want labels to generate a success/failure status check
checks:
  - context: 'Status Check'
    url: 'https://go.to/detail'
    description:
      success: 'Ready for review & merge.'
      failure: 'Missing labels for release.'
    labels:
      any:
        - any
        - have
      all:
        - all
        - must
        - have

Examples

Semantic Pull Request

.github/workflow/pr-triage.yml

on:
  pull_request:
    types: [opened, edited, synchronize, ready_for_review]
    branches: [master, main]

jobs:
  labeler:
    name: Labeler
    runs-on: ubuntu-latest
    steps:
      - uses: fuxingloh/multi-labeler@v4

.github/labeler.yml

version: v1

labels:
  - label: 'feat'
    matcher:
      title: '^feat: .*'
      commits: '^feat: .*'

  - label: 'fix'
    matcher:
      title: '^fix: .*'
      commits: '^fix: .*'

  - label: 'chore'
    matcher:
      title: '^chore: .*'
      commits: '^chore: .*'

  - label: 'docs'
    matcher:
      title: '^docs: .*'
      commits: '^docs: .*'

checks:
  - context: 'Semantic Pull Request'
    url: 'https://github.com/fuxingloh/multi-labeler/blob/main/.github/labeler.yml'
    description:
      success: Ready for review & merge.
      failure: Missing semantic label for merge.
    labels:
      any:
        - feat
        - fix
        - chore
        - docs
PR Triage

.github/workflow/pr-triage.yml

on:
  pull_request:
    types: [opened, edited, synchronize, ready_for_review]
    branches: [master, main]

jobs:
  labeler:
    name: Labeler
    runs-on: ubuntu-latest
    steps:
      - uses: fuxingloh/multi-labeler@v4

.github/labeler.yml

version: v1

labels:
  - label: 'feat'
    matcher:
      title: '^feat:.*'
      branch: '^feat/.*'
      commits: '^feat:.*'

  - label: 'fix'
    matcher:
      title: '^fix:.*'
      branch: '^fix/.*'
      commits: '^fix:.*'

  - label: 'release'
    matcher:
      baseBranch: '^release/.*'
Issue Triage

.github/workflow/issue-triage.yml

on:
  issues:
    types: [opened, edited]

jobs:
  labeler:
    name: Labeler
    runs-on: ubuntu-latest
    steps:
      - uses: fuxingloh/multi-labeler@v4

.github/labeler.yml

version: v1

labels:
  - label: 'bug'
    matcher:
      body: "(\\n|.)*- \\[x\\] bug(\\n|.)*"
Comment Triage

.github/workflow/comment-slash.yml

on:
  issue_comment:
    types: [created, edited]

jobs:
  labeler:
    name: Labeler
    runs-on: ubuntu-latest
    steps:
      - uses: fuxingloh/multi-labeler@v4

.github/labeler.yml

version: v1

labels:
  - label: 'coverage'
    matcher:
      comment: "# \\[Codecov\\] .*"

  - label: 'stale'
    matcher:
      comment: '/stale'

Configuration

Once you’ve added fuxingloh/multi-labeler to your repository, it must be enabled by adding a .github/labeler.yml configuration file to the repository. If you want to use a configuration file shared across multiple repositories, you can set theconfig-repo input to point to a different repository. However, make sure to set a github-token that has permissions to access the provided repository, as the default GITHUB_TOKEN only has access to the repository the action is running in.

Matchers

RegEx matcher requires backslash '' to be double slashed '\'. Hence, to match brackets '()' you need a regex of '\(\)'. See #103

PR/Issue Title: RegEx

version: v1

labels:
  - label: 'feat'
    matcher:
      title: '^feat:.*'

PR/Issue Body: RegEx

version: v1

labels:
  - label: 'bug'
    matcher:
      # e.g. '- [x] bug'
      body: "(\\n|.)*- \\[x\\] bug(\\n|.)*"

PR/Issue Comment: RegEx

version: v1

labels:
  - label: 'stale'
    matcher:
      comment: '/stale'

PR Branch: RegEx

version: v1

labels:
  - label: 'feat'
    matcher:
      branch: '^feat/.*'

PR Base Branch: RegEx

version: v1

labels:
  - label: 'release'
    matcher:
      baseBranch: '^release/.*'

PR Commits: RegEx

Check all commits and find any match, max of 250 commits only.

version: v1

labels:
  - label: 'feat'
    matcher:
      commits: '^feat: .*'

PR/Issue Author

Check for pr or issue author match.

version: v1

labels:
  - label: 'single'
    matcher:
      author: 'fuxingloh'
  - label: 'any'
    matcher:
      author:
        - adam
        - claire

PR Files: Glob Matcher

Maximum of 3000 files only. If you use this to audit changes, take note of the 3000 files limitation. Matchers within files are 'and condition'; all must match.

PR Files Basic

version: v1

labels:
  - label: 'github'
    sync: true
    matcher:
      # This is shorthand for any: [".github/**"]
      files: '.github/**'

  - label: 'security'
    sync: true
    matcher:
      # This is shorthand for any: ["web/security/**", "security/**"]
      files: ['web/security/**', 'security/**']

PR Files Count

version: v1

labels:
  - label: 'size: s'
    sync: true
    matcher:
      files:
        count:
          gte: 1
          lte: 4

  - label: 'size: m'
    sync: true
    matcher:
      files:
        count:
          gte: 5
          lte: 10

  - label: 'size: l'
    sync: true
    matcher:
      files:
        count:
          gte: 11

PR Files Any & All

version: v1

labels:
  - label: 'ci'
    sync: true
    matcher:
      files:
        any: ['.github/workflow/**', '.circleci/**']
        all: ['!app/**']

  - label: 'attention'
    sync: true
    matcher:
      files:
        any: ['app/**']
        count:
          neq: 1

PR Status Checks

PR Check any

version: v1

checks:
  - context: 'Release Drafter'
    url: 'https://go.to/detail'
    description:
      success: 'Ready for review & merge.'
      failure: 'Missing labels for release.'
    labels:
      any:
        - feat
        - fix
        - chore
        - docs

PR Check any + all

version: v1

checks:
  - context: 'Merge check'
    description: 'Labels for merge.'
    labels:
      any: ['reviewed', 'size:s']
      all: ['app']

PR Check none

version: v1

checks:
  - context: 'Merge check'
    description: "Disable merging when 'DO NOT MERGE' label is set"
    labels:
      none: ['DO NOT MERGE']

Why?

There are so many labelers why create another? 😧

  1. I want a lightweight labeler written in TypeScript so that it doesn't have to build a docker image every time it runs.
  2. I want a simple match first append based multi-labeler without it being a turing complete solution.
  3. I want to write my rules with .github/labeler.yml for a single source of label truth.
  4. I don't want it to do anything else, labels only.
    1. Assume you are using GitHub branch protection (labels only).
    2. I want to run this in PR triage before everything else (labels only).
    3. Chain this action with another action; this should just be for (labels only).

multi-labeler's People

Contributors

dependabot[bot] avatar flugg avatar fuxingloh avatar fuxingloh-multi-labeler-workflow[bot] avatar giorgiosaud avatar houseful-chisel avatar janos-kasa avatar maxisam avatar renovate[bot] avatar srijan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

multi-labeler's Issues

Valid regex seemingly fails silently?

Hi there.
Just started using this action so if I'm doing something silly please let me know but I can't seem to get valid parenthesis-related regex statements working in my labeler.yml.

PR title is: "build(deps): apply minor and patch dependency updates test" - we use both "^build(deps): ." and "^build(dev-deps): ." commit and PR title tags and I'd like to catch both and apply a "dependencies" label.

The following labeler.yml catches that PR title and succesfully applies the label:

version: v1

labels:
  - label: "dependencies"
    sync: true
    matcher:
      title: "^build.*"
      commits: "^build.*"

However, to use parentheses I am obviously going to have to escape them. \( isn't valid YAML so I went for \x28 instead and came up with the following valid regex:

title: "^build\x28(deps|deps-dev)\x29: .*"

However, the action then does nothing - officially passed but gives no useful logging output and doesn't apply the label.

Is there a debug flag for getting useful logging? And should valid regex like this work?

Any help much appreciated.

Deploy preview failed

There is some kind of error happening right after Label job,

Deploy preview failed
Error: The process '/usr/local/bin/npx' failed with exit code 1

image

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/workflows/ci-package.yml
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • tibdex/github-app-token v2.1.0@3beb63f4bd073e61482598c45c71c1019b59b73a
  • peter-evans/create-pull-request v6.0.5@6d6857d36972b65feb161a90e484f2984215f83e
.github/workflows/ci-use.yml
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
.github/workflows/ci.yml
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
.github/workflows/draft.yml
  • release-drafter/release-drafter v6.0.0@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348
.github/workflows/release.yml
  • actions/checkout v4.1.4@0ad4b8fadaa221de15dcec353f45205ec38ea70b
  • vweevers/additional-tags-action v2.0.0@3bab55b44e81186dcfef7db9f2cbca01a78eb710
npm
package.json
  • @actions/core ^1.10.1
  • @actions/github ^6.0.0
  • fp-ts ^2.16.5
  • io-ts ^2.2.21
  • io-ts-reporters ^2.0.1
  • js-yaml ^4.1.0
  • lodash ^4.17.21
  • minimatch ^9.0.4
  • @vercel/ncc ^0.38.1
nvm
.nvmrc
  • node 20.12.2

  • Check this box to trigger a request for Renovate to run again on this repository

add 'oneof' option in addition to 'any' and 'all'

Quite often we want to be sure that only one of a specific list of labels is present. Current options like any would indicate that it will pass even with 2+ matches, which could cause problems for changelog generation.

Shared configuration

Finally a labeler action that actually works on commit messages! We'll be having a lot of repositories using this action and would like to place the configuration in a central place (the @org/.github repo). How can I configure the action to use a configuration from a different repository?

Support matching target branch of pull request?

I like the super-fast labels-only approach of this action.

But, one of the things I was looking for is: label based on target branch (base branch) of pull request.

For example, I want to add a release label to PRs targeting release/* branches.

Is this something acceptable as a feature here?

Sync options?

Add ability to sync tags and remove tags that does not fit the condition provided inlabeler.yml?

Option to set case sensitivity

It would be really great if there was an option to set case insensitivity.

At present you have to add /i to every line - I'm not sure if this might cause other issues but it's certainly a lot of repetition.

Screen Shot 2022-09-09 at 8 59 36 am

Documents

Thanks for the great tool!

Could you document more on the files.all option and output option?

Both of them are not very clear from the test case.

Here is what I got.

  1. output.labels as an array of labels. (This one is pretty simple)

  2. files.all

it will match all glob expressions in the array. The behavior is like "and", while any is like "or".

Also it seems like the expression doesn't work correctly with !(xxx|zzz)/**

But it seems like it should work according to https://github.com/isaacs/minimatch

PS: if there is a way to pass the option of minimatch, that will be awesome!

action has started failing; Node.js 16 actions are deprecated

Runs for this action have started failing with:

Run fuxingloh/multi-labeler@v2

/home/runner/work/_actions/fuxingloh/multi-labeler/v2/webpack:/multi-labeler/lib/main.js:42
    throw new Error('Could not get issue_number from pull_request or issue from context');
^
Error: Could not get issue_number from pull_request or issue from context

and

Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: fuxingloh/multi-labeler@v2. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.

Looking at the action.yml here I can see:

runs:
  using: 'node16'
  main: 'dist/index.js'

Not being a node user, I'm unsure if this can just be updated to node20 and all will be well again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.