Skip to content

redhat-plumbers-in-action/advanced-issue-labeler

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

Advanced Issue Labeler

GitHub Marketplace Lint Code Base Unit Tests CodeQL Check dist/

Demo codecov

Advanced Issue Labeler is a GitHub Action that can automatically label issues based on user input. The idea for this project came from and was first introduced in @systemd/systemd. Systemd repository has a very active community with many issues to process. Automatic labeling helps with issue triaging.

How does it work

Advanced Issue Labeler takes advantage of GitHub issue forms (special kind of issue templates) to provide a better developer experience by labeling issues based on provided input. This action works best with dropdowns and checkboxes.

Advanced Issue Labeler is expected to work in cooperation with @stefanbuck/github-issue-parser >= v3.1.1 GitHub Action. Parser action provides JSON representation of the submitted issue, where KEYs represent IDs described in the issue-form YAML configuration. Issue labeler understands it and can label issues based on selected values from dropdown. Dropdown values could directly represent labels or be mapped to policy configuration for more complex labeling requirements.

Features

  • Ability to label issues based on issue form dropdowns and checkboxes
  • Ability to specify policy for mapping specific keywords to labels
  • Ability to exclude certain words from the labeling process (block-list)
  • Ability to define multiple policies for different issue forms

Usage

1. Simple usecase

The following example shows how to automatically label issues based on the severity that the user describes in issue form. In issue form, there is a defined dropdown listing all severity levels:

# ...

- type: dropdown
  id: severity
  attributes:
    label: Severity impact
    description: Please choose the severity of the impact of this issue.
    multiple: false
    options:
      - 'None'
      - 'Low'
      - 'Medium'
      - 'High'
      - 'Urgent'
      - 'Other'
  validations:
    required: true

# ...

Important

It's essential to set the correct ID in issue-form

GitHub workflow that automatically marks issues with severity labels:

name: Issue labeler
on:
  issues:
    types: [ opened ]

permissions:
  contents: read

jobs:
  label-component:
    runs-on: ubuntu-latest

    permissions:
      # required for all workflows
      issues: write

      # only required for workflows in private repositories
      actions: read
      contents: read

    steps:
      - uses: actions/checkout@v3

      - name: Parse issue form
        uses: stefanbuck/github-issue-parser@v3
        id: issue-parser
        with:
          template-path: .github/ISSUE_TEMPLATE/bug.yml

      - name: Set labels based on severity field
        uses: redhat-plumbers-in-action/advanced-issue-labeler@v2
        with:
          issue-form: ${{ steps.issue-parser.outputs.jsonString }}
          section: severity
          block-list: |
            None
            Other
          token: ${{ secrets.GITHUB_TOKEN }}

2. More complex usecase

The following example shows how to automatically label issues based on animal types. In issue form, there is a defined dropdown listing all animals:

# ...

- type: dropdown
  id: animals
  attributes:
    label: Animals
    description: Please pick all animals you like.
    multiple: true
    options:
      - 'None'
      - '🦍 Gorilla'
      - '🐶 Dog'
      - '🐺 Wolf'
      - '🦊 Fox'
      - '🐴 Horse'
      - '🐓 Rooster'
      - '🐦 Bird'
      - '🐧 Penguin'
      - '🐸 Frog'
      - '🐬 Dolphin'
      - '🐡 Blowfish'
      - '🐟 Fish'
      - '🦈 Shark'
      - '🐛 Bug'
      - '🕷️ Spider'
      - '🐊 Crocodile'
      - 'Other'
  validations:
    required: true

# ...

Important

It's essential to set the correct ID in issue-form

Let's define a policy that will allow us to map animals to their types. Policy needs to be stored in .github/advanced-issue-labeler.yml.

policy:
  - section:
      - id: [animals]
        block-list: ['None', 'Other']
        label:
          - name: 'kind: amphibians'
            keys: ['🐸 Frog']
          - name: 'kind: birds'
            keys: ['🐓 Rooster', '🐦 Bird', '🐧 Penguin']
          - name: 'kind: fish'
            keys: ['🐡 Blowfish', '🐟 Fish', '🦈 Shark']
          - name: 'kind: mammals'
            keys: ['🦍 Gorilla', '🐶 Dog', '🐬 Dolphin', '🐺 Wolf', '🦊 Fox', '🐴 Horse']
          - name: 'kind: reptiles'
            keys: ['🐊 Crocodile']
          - name: 'invertebrates'
            keys: ['🐛 Bug', '🕷️ Spider']

GitHub workflow that automatically marks issues with animal types labels:

name: Issue labeler
on:
  issues:
    types: [ opened ]

permissions:
  contents: read

jobs:
  label-component:
    runs-on: ubuntu-latest

    permissions:
      # required for all workflows
      issues: write

      # only required for workflows in private repositories
      actions: read
      contents: read

    steps:
      - uses: actions/checkout@v3

      - name: Parse issue form
        uses: stefanbuck/github-issue-parser@v3
        id: issue-parser
        with:
          template-path: .github/ISSUE_TEMPLATE/bug.yml

      - name: Set labels based on animals field
        uses: redhat-plumbers-in-action/advanced-issue-labeler@v2
        with:
          issue-form: ${{ steps.issue-parser.outputs.jsonString }}
          token: ${{ secrets.GITHUB_TOKEN }}

Real-life examples

Feel free to try advanced-issue-labeler in template repository - @redhat-plumbers-in-action/issue-forms-automation

Configuration options

Action currently accepts the following options:

# ...

- uses: redhat-plumbers-in-action/advanced-issue-labeler@v2
  with:
    issue-form:   <issue-form.json>
    template:     <template-name.yml>
    section:      <section-id>
    block-list:   <block-list>
    config-path:  <path to config file>
    token:        <GitHub token>

# ...

issue-form

Issue-form parsed into JSON file. Supported format is generated using @stefanbuck/github-issue-parser GitHub action.

  • default value: undefined
  • requirements: required

template

Each issue form can have a defined different labeling policy, and this option is used to specify which policy should be used.

  • default value: undefined
  • requirements: optional

section

The ID of the section (dropdown or checkboxes section is recomended) from the issue form template.

  • default value: undefined
  • requirements: required

block-list

List of forbidden labels. These labels won't be set.

  • default value: undefined
  • requirements: optional

Tip

Please notice the | in the example above ☝️. That lets you effectively declare a multi-line YAML string. You can learn more about multi-line YAML syntax here. This syntax is required when block-listing multiple labels.

config-path

Path to configuration file. Configuration file format is described in: Policy section.

  • default value: .github/advanced-issue-labeler.yml
  • requirements: optional

token

Token used to set labels

  • default value: undefined
  • requirements: required
  • recomended value: secrets.GITHUB_TOKEN

Outputs

labels

List of labels that were set based on the provided policy. The output is a stringified JSON array.

Tip

Use fromJSON function to parse the output to get an array of labels.

element: ${{ fromJSON(steps.<step-id>.outputs.labels)[0] }}

policy

The representation of the policy that was used to set labels. The output is a stringified JSON object.

Example output in JSON format where:

  • template - the name of the template that was used to parse the issue form
  • section - key-value pairs where the key is the ID of the issue-form section and the value is an array of the applied labels for the given section
{
  "template": "bug.yml",
  "section": {
    "severity": [ "low" ],
    "priority": [ "high" ]
  }
}

Tip

Use fromJSON function to parse the output to get an object of policy.

severity: ${{ fromJSON(steps.<step-id>.outputs.policy).section.severity }}

Policy

It's possible to define a labeling policy to further customize the labeling process. The policy can be defined using .github/advanced-issue-labeler.yml configuration file. The structure needs to be as follows:

policy:
  - template: ['bug.yml', 'feature.yml']
    section:
      - id: ['severity', 'priority']
        block-list: []
        label:
          - name: 'Low'
            keys: ['Low', 'None']
          - name: 'Medium'
            keys: ['Medium']
          - name: 'High'
            keys: ['High']
          - name: 'Urgent'
            keys: ['Urgent']
      - id: [animals]
        block-list: ['None', 'Other']
        label:
          - name: 'amphibians'
            keys: ['🐸 Frog']
          - name: 'birds'
            keys: ['🐓 Rooster', '🐦 Bird', '🐧 Penguin']
          - name: 'fish'
            keys: ['🐡 Blowfish', '🐟 Fish', '🦈 Shark']
          - name: 'mammals'
            keys: ['🦍 Gorilla', '🐶 Dog', '🐬 Dolphin', '🐺 Wolf', '🦊 Fox', '🐴 Horse']
          - name: 'reptiles'
            keys: ['🐊 Crocodile']
          - name: 'invertebrates'
            keys: ['🐛 Bug', '🕷️ Spider']
# - template: ...

template keyword

Array of issue-forms (e.g. ['bug-report.yml']). This section is used to determine the correct labeling policy when multiple policies are defined. Works in cooperation with template option.

  • requirements: optional

section.id keyword

Equivalent of section option. An array of IDs of section from issue-form. These IDs need to point to section in the issue-form template.

  • requirements: required

section.block-list keyword

Equivalent of block-list option. An array of forbidden keywords. These keywords will be excluded when applying labeling policy.

  • requirements: required

section.label keyword

Section of policy describing labeling policy. label section of the policy is expected to have the following properties:

  • name - Name of label

  • keys - Array of keywords corresponding to values from issue-form section

  • requirements: required

Limitations

  • Currently it's not possible to use strings containing ,␣ in the dropdown menu or checkboxes value. This pattern is used in the separation process (e.g. when the dropdown option multiple is set to true).