{"id":16261322,"url":"https://github.com/fuxingloh/multi-labeler","last_synced_at":"2025-04-06T16:13:48.374Z","repository":{"id":37032289,"uuid":"329257641","full_name":"fuxingloh/multi-labeler","owner":"fuxingloh","description":"Multi labeler for title, body, comments, commit messages, branch, author or files with automated status checks.","archived":false,"fork":false,"pushed_at":"2025-03-30T14:38:21.000Z","size":7364,"stargazers_count":37,"open_issues_count":11,"forks_count":15,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-02T00:49:53.601Z","etag":null,"topics":["commits","conventional-commits","files","github-actions","github-marketplace","multi-labeler","pr-description","pr-title","pull-requests","status","status-check"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fuxingloh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-13T09:32:38.000Z","updated_at":"2025-03-30T14:37:33.000Z","dependencies_parsed_at":"2023-09-29T23:56:01.288Z","dependency_job_id":"6eb00986-b27f-4b9b-bf39-ab2bec3e0c39","html_url":"https://github.com/fuxingloh/multi-labeler","commit_stats":{"total_commits":208,"total_committers":11,"mean_commits":18.90909090909091,"dds":0.6586538461538461,"last_synced_commit":"a2bf6dcbcb7c1d549bce0f8339a2ef082d99bab4"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":"actions/typescript-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuxingloh%2Fmulti-labeler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuxingloh%2Fmulti-labeler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuxingloh%2Fmulti-labeler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuxingloh%2Fmulti-labeler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fuxingloh","download_url":"https://codeload.github.com/fuxingloh/multi-labeler/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247509237,"owners_count":20950232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commits","conventional-commits","files","github-actions","github-marketplace","multi-labeler","pr-description","pr-title","pull-requests","status","status-check"],"created_at":"2024-10-10T16:41:07.438Z","updated_at":"2025-04-06T16:13:48.337Z","avatar_url":"https://github.com/fuxingloh.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Multi Labeler\n\n[![codecov](https://codecov.io/gh/fuxingloh/multi-labeler/branch/main/graph/badge.svg?token=SOWIV1VVM1)](https://codecov.io/gh/fuxingloh/multi-labeler)\n[![CodeFactor](https://www.codefactor.io/repository/github/fuxingloh/multi-labeler/badge)](https://www.codefactor.io/repository/github/fuxingloh/multi-labeler)\n[![Release](https://img.shields.io/github/v/release/fuxingloh/multi-labeler)](https://github.com/fuxingloh/multi-labeler/releases)\n[![License MIT](https://img.shields.io/github/license/fuxingloh/multi-labeler)](https://github.com/fuxingloh/multi-labeler/blob/main/LICENSE)\n\nMulti labeler for title, body, comments, commit messages, branch, base branch, author or files.\nOptionally, generate a status check based on the labels.\n\n[Who is using `fuxingloh/multi-labeler`?](https://github.com/search?o=desc\u0026q=fuxingloh+%2F+multi-labeler\u0026s=indexed\u0026type=Code)\n\n## Features\n\n- Single compiled javascript file, extremely fast. Use fewer credits!\n- Append based multi-labeler, using `.github/labeler.yml` as config.\n- Automatically fail if `labeler.yml` is malformed, type-checked.\n- Set label to sync for conditional labeling, removed if condition failed.\n- Regex Matcher:\n  - PR/Issue title\n  - PR/Issue body\n  - PR/Issue comments\n  - PR commit messages\n  - PR branch name\n  - PR base (target) branch name\n- File Matcher:\n  - Files count\n  - Files any glob match\n  - Files all glob match\n- Author Matcher\n- Generate status checks:\n  - Any label match\n  - All label match\n\n## Usage\n\n#### `.github/workflows/labeler.yml`\n\n```yml\non:\n  pull_request_target:\n  # for OSS with public contributions (forked PR)\n\n  pull_request:\n  # Useful for triaging code review, and generate compliance status check.\n  # Semantic release? Done.\n  # Make a file change in a mono repo. Tag the mono repo getting changed to generate better release!\n\n  issues:\n  # Useful for triaging error!\n  # '- [x] Is this a bug?' = 'bug' label!\n\n  issue_comment:\n  # To pickup comment body in pr or issue and generate a label.\n  # Imagine someone comment 'Me too, I get TimeoutException from ...' in comment body.\n  # Generate a 'bug/timeout' label for better triaging!\n\npermissions:\n  # Setting up permissions in the workflow to limit the scope of what it can do. Optional!\n  contents: read # the config file\n  issues: write # for labeling issues (on: issues)\n  pull-requests: write # for labeling pull requests (on: pull_request_target or on: pull_request)\n  statuses: write # to generate status\n  checks: write # to generate status\n\njobs:\n  labeler:\n    name: Labeler\n    runs-on: ubuntu-latest\n    steps:\n      # follows semantic versioning. Lock to different version: v1, v1.5, v1.5.0 or use a commit hash.\n      - uses: fuxingloh/multi-labeler@v4 # v4\n        with:\n          github-token: ${{secrets.GITHUB_TOKEN}} # optional, default to '${{ github.token }}'\n          config-path: .github/labeler.yml # optional, default to '.github/labeler.yml'\n          config-repo: my-org/my-repo # optional, default to '${{ github.repository }}'\n```\n\n#### `.github/labeler.yml`\n\n```yml\n# .github/labeler.yml\n\nversion: v1\n\nlabels:\n  - label: 'feat'\n    sync: true # remove label if match failed, default: false (pull_request/issue only)\n    matcher:\n      # Matcher will match on any 8 matchers\n      title: '^feat:.*'\n      body: '/feat'\n      comment: '/feat'\n      branch: '^feat/.*'\n      baseBranch: '^feat/.*'\n      commits: '^feat:.*'\n      author:\n        - github-actions\n        - fuxingloh\n      files:\n        any: ['app/*']\n        all: ['!app/config/**']\n        count:\n          gte: 1\n          lte: 1000\n\n# Optional, if you want labels to generate a success/failure status check\nchecks:\n  - context: 'Status Check'\n    url: 'https://go.to/detail'\n    description:\n      success: 'Ready for review \u0026 merge.'\n      failure: 'Missing labels for release.'\n    labels:\n      any:\n        - any\n        - have\n      all:\n        - all\n        - must\n        - have\n```\n\n### Examples\n\n\u003cdetails\u003e\n  \u003csummary\u003eSemantic Pull Request\u003c/summary\u003e\n\n#### `.github/workflow/pr-triage.yml`\n\n```yml\non:\n  pull_request:\n    types: [opened, edited, synchronize, ready_for_review]\n    branches: [master, main]\n\njobs:\n  labeler:\n    name: Labeler\n    runs-on: ubuntu-latest\n    steps:\n      - uses: fuxingloh/multi-labeler@v4\n```\n\n#### `.github/labeler.yml`\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'feat'\n    matcher:\n      title: '^feat: .*'\n      commits: '^feat: .*'\n\n  - label: 'fix'\n    matcher:\n      title: '^fix: .*'\n      commits: '^fix: .*'\n\n  - label: 'chore'\n    matcher:\n      title: '^chore: .*'\n      commits: '^chore: .*'\n\n  - label: 'docs'\n    matcher:\n      title: '^docs: .*'\n      commits: '^docs: .*'\n\nchecks:\n  - context: 'Semantic Pull Request'\n    url: 'https://github.com/fuxingloh/multi-labeler/blob/main/.github/labeler.yml'\n    description:\n      success: Ready for review \u0026 merge.\n      failure: Missing semantic label for merge.\n    labels:\n      any:\n        - feat\n        - fix\n        - chore\n        - docs\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003ePR Triage\u003c/summary\u003e\n\n#### `.github/workflow/pr-triage.yml`\n\n```yml\non:\n  pull_request:\n    types: [opened, edited, synchronize, ready_for_review]\n    branches: [master, main]\n\njobs:\n  labeler:\n    name: Labeler\n    runs-on: ubuntu-latest\n    steps:\n      - uses: fuxingloh/multi-labeler@v4\n```\n\n#### `.github/labeler.yml`\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'feat'\n    matcher:\n      title: '^feat:.*'\n      branch: '^feat/.*'\n      commits: '^feat:.*'\n\n  - label: 'fix'\n    matcher:\n      title: '^fix:.*'\n      branch: '^fix/.*'\n      commits: '^fix:.*'\n\n  - label: 'release'\n    matcher:\n      baseBranch: '^release/.*'\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eIssue Triage\u003c/summary\u003e\n\n#### `.github/workflow/issue-triage.yml`\n\n```yml\non:\n  issues:\n    types: [opened, edited]\n\njobs:\n  labeler:\n    name: Labeler\n    runs-on: ubuntu-latest\n    steps:\n      - uses: fuxingloh/multi-labeler@v4\n```\n\n#### `.github/labeler.yml`\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'bug'\n    matcher:\n      body: \"(\\\\n|.)*- \\\\[x\\\\] bug(\\\\n|.)*\"\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eComment Triage\u003c/summary\u003e\n\n#### `.github/workflow/comment-slash.yml`\n\n```yml\non:\n  issue_comment:\n    types: [created, edited]\n\njobs:\n  labeler:\n    name: Labeler\n    runs-on: ubuntu-latest\n    steps:\n      - uses: fuxingloh/multi-labeler@v4\n```\n\n#### `.github/labeler.yml`\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'coverage'\n    matcher:\n      comment: \"# \\\\[Codecov\\\\] .*\"\n\n  - label: 'stale'\n    matcher:\n      comment: '/stale'\n```\n\n\u003c/details\u003e\n\n## Configuration\n\nOnce you’ve added fuxingloh/multi-labeler to your repository,\nit must be enabled by adding a `.github/labeler.yml` configuration file to the repository.\nIf you want to use a configuration file shared across multiple repositories,\nyou can set the`config-repo` input to point to a different repository.\nHowever, make sure to set a `github-token` that has permissions to access the provided repository,\nas the default `GITHUB_TOKEN` only has access to the repository the action is running in.\n\n## Matchers\n\n\u003e RegEx matcher requires backslash '\\' to be double slashed '\\\\'. Hence, to match brackets '()' you need a regex of '\\\\(\\\\)'. See https://github.com/fuxingloh/multi-labeler/issues/103\n\n### PR/Issue Title: RegEx\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'feat'\n    matcher:\n      title: '^feat:.*'\n```\n\n### PR/Issue Body: RegEx\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'bug'\n    matcher:\n      # e.g. '- [x] bug'\n      body: \"(\\\\n|.)*- \\\\[x\\\\] bug(\\\\n|.)*\"\n```\n\n### PR/Issue Comment: RegEx\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'stale'\n    matcher:\n      comment: '/stale'\n```\n\n### PR Branch: RegEx\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'feat'\n    matcher:\n      branch: '^feat/.*'\n```\n\n### PR Base Branch: RegEx\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'release'\n    matcher:\n      baseBranch: '^release/.*'\n```\n\n### PR Commits: RegEx\n\nCheck all commits and find any match, max of 250 commits only.\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'feat'\n    matcher:\n      commits: '^feat: .*'\n```\n\n### PR/Issue Author\n\nCheck for pr or issue author match.\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'single'\n    matcher:\n      author: 'fuxingloh'\n  - label: 'any'\n    matcher:\n      author:\n        - adam\n        - claire\n```\n\n### PR Files: [Glob Matcher](https://github.com/isaacs/minimatch)\n\nMaximum of 3000 files only.\nIf you use this to audit changes, take note of the 3000 files limitation.\nMatchers within files are 'and condition'; all must match.\n\n#### PR Files Basic\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'github'\n    sync: true\n    matcher:\n      # This is shorthand for any: [\".github/**\"]\n      files: '.github/**'\n\n  - label: 'security'\n    sync: true\n    matcher:\n      # This is shorthand for any: [\"web/security/**\", \"security/**\"]\n      files: ['web/security/**', 'security/**']\n```\n\n#### PR Files Count\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'size: s'\n    sync: true\n    matcher:\n      files:\n        count:\n          gte: 1\n          lte: 4\n\n  - label: 'size: m'\n    sync: true\n    matcher:\n      files:\n        count:\n          gte: 5\n          lte: 10\n\n  - label: 'size: l'\n    sync: true\n    matcher:\n      files:\n        count:\n          gte: 11\n```\n\n#### PR Files Any \u0026 All\n\n```yml\nversion: v1\n\nlabels:\n  - label: 'ci'\n    sync: true\n    matcher:\n      files:\n        any: ['.github/workflow/**', '.circleci/**']\n        all: ['!app/**']\n\n  - label: 'attention'\n    sync: true\n    matcher:\n      files:\n        any: ['app/**']\n        count:\n          neq: 1\n```\n\n### PR Status Checks\n\n#### PR Check any\n\n```yml\nversion: v1\n\nchecks:\n  - context: 'Release Drafter'\n    url: 'https://go.to/detail'\n    description:\n      success: 'Ready for review \u0026 merge.'\n      failure: 'Missing labels for release.'\n    labels:\n      any:\n        - feat\n        - fix\n        - chore\n        - docs\n```\n\n#### PR Check any + all\n\n```yml\nversion: v1\n\nchecks:\n  - context: 'Merge check'\n    description: 'Labels for merge.'\n    labels:\n      any: ['reviewed', 'size:s']\n      all: ['app']\n```\n\n#### PR Check none\n\n```yml\nversion: v1\n\nchecks:\n  - context: 'Merge check'\n    description: \"Disable merging when 'DO NOT MERGE' label is set\"\n    labels:\n      none: ['DO NOT MERGE']\n```\n\n## Why?\n\n\u003e There are so many labelers why create another? 😧\n\n1. I want a lightweight labeler written in TypeScript so that it doesn't have to build a docker image every time it runs.\n2. I want a simple match first append based multi-labeler without it being a turing complete solution.\n3. I want to write my rules with `.github/labeler.yml` for a single source of label truth.\n4. I don't want it to do anything else, labels only.\n   1. Assume you are using GitHub branch protection (labels only).\n   2. I want to run this in PR triage before everything else (labels only).\n   3. Chain this action with another action; this should just be for (labels only).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuxingloh%2Fmulti-labeler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffuxingloh%2Fmulti-labeler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuxingloh%2Fmulti-labeler/lists"}