Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 70 additions & 11 deletions .github/workflows/enforce-label.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,90 @@
name: Enforce PR label

on:
pull_request:
pull_request_target:
types: [labeled, unlabeled, opened, edited, synchronize]

permissions:
issues: write
pull-requests: write

jobs:
pr-title:
name: Check conventional commit PR title
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# WARN: With `pull_request_target` it is unsafe to execute user code, we execute
# pixi/commitlint from target branch.
ref: ${{ github.event.pull_request.base.sha }}
- name: Setup Pixi
uses: prefix-dev/setup-pixi@v0.9.3
with:
pixi-version: v0.60.0
cache: true
manifest-path: pyproject.toml
- name: Verify conventional commit conventions on PR title
id: commitlint
run: echo "${{ github.event.pull_request.title }}" | pixi run commitlint
# TODO: we have not added the labels but we can add them automatically
# from conventional commit titles
# pr-label:
# name: Check PR label
# runs-on: ubuntu-latest
# permissions:
# pull-requests: write
# steps:
# - name: enforce-triage-label
# uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1
- name: Apply PR label
if: success()
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |-
const title = context.payload.pull_request.title;

// Extract conventional commit type and optional scope
const match = title.match(/^([a-z]+)(?:\(([a-z]+)\))?:/);
if (!match) {
console.log("No conventional commit type found in PR title");
return;
}

const commitType = match[1];
const commitScope = match[2]; // optional
console.log(`Detected commit type: ${commitType}`);
if (commitScope) {
console.log(`Detected commit scope: ${commitScope}`);
}

// Map commit types to PR labels
const typeToLabel = {
"fix": "bug",
"feat": "feature",
"doc": "documentation",
"chore": "maintenance",
"ci": "maintenance",
"dev": "maintenance",
"test": "maintenance",
"perf": "enhancement",
"release": "maintenance",
"revert": "maintenance"
};

const label = typeToLabel[commitType];
if (!label) {
console.log(`No label mapping found for commit type: ${commitType}`);
return;
}

console.log(`Applying type label: ${label}`);

// Collect labels to add
const labelsToAdd = [label];

// Add scope label if applicable (client or server)
if (commitScope && ["client", "server"].includes(commitScope)) {
console.log(`Applying scope label: ${commitScope}`);
labelsToAdd.push(commitScope);
}

// Apply labels (GitHub API is idempotent - ignores already present labels)
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: labelsToAdd
});
Loading