Skip to content

Apply PR Labels

Apply PR Labels #2259

Workflow file for this run

name: Apply PR Labels
# workflow_run is used intentionally here: the elevated-permission step runs
# in the base-repo context but never checks out PR code, so it is safe.
on:
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: ["Labels Trigger"]
types:
- completed
permissions: {}
concurrency:
group: labels-apply-${{ github.event.workflow_run.id }}
cancel-in-progress: true
jobs:
labels-by-language:
name: labels-by-language
runs-on: ubuntu-slim
if: github.event.workflow_run.conclusion == 'success'
permissions:
pull-requests: write # So we can add labels to the pull request
steps:
- uses: actions/github-script@v9
with:
script: |
// For same-repo PRs the pull_requests array is populated directly.
// For fork PRs it is empty, so fall back to a commit-SHA lookup.
let prNumber;
const prs = context.payload.workflow_run.pull_requests;
if (prs && prs.length > 0) {
prNumber = prs[0].number;
} else {
// For fork PRs, commits don't exist in the base repo history so
// listPullRequestsAssociatedWithCommit returns empty. Use the
// head owner + branch from the workflow_run payload instead.
const headOwner = context.payload.workflow_run.head_repository.owner.login;
const headBranch = context.payload.workflow_run.head_branch;
const result = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: `${headOwner}:${headBranch}`,
state: 'open',
});
if (result.data.length === 0) {
core.warning(`No open PR found for ${headOwner}:${headBranch}`);
return;
}
prNumber = result.data[0].number;
}
const filenames = (await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
per_page: 100,
})).map(file => file.filename);
console.log(filenames);
const vehicle_labels = {
AntennaTracker: 'AntennaTracker',
ArduCopter: 'Copter',
ArduPlane: 'Plane',
ArduSub: 'Sub',
Blimp: 'Blimp',
Rover: 'Rover',
};
const vehicle_sim_labels = {
Helicopter: 'TradHeli',
QuadPlane: 'VTOL-Plane',
Sailboat: 'Sailboat',
Blimp: 'Blimp',
Plane: 'Plane',
Rover: 'Rover',
Submarine: 'Sub',
};
const generic_suffix_labels = {
'.lua': 'Scripting',
'.py': 'Python',
};
const generic_prefix_labels = {
'libraries/AP_ExternalAHRS': 'ExternalAHRS',
'libraries/AP_Compass': 'Compass',
'libraries/AP_NavEKF': 'EKF',
'libraries/AP_HAL_Linux': 'Linux',
'libraries/GCS_MAVLink': 'MAVLink',
'libraries/SITL': 'SITL',
'Tools/AP_Periph': 'AP_Periph',
'Tools/autotest': 'CI',
'.github/workflows': 'github_actions',
};
const specific_vehicle_checks = {
'VTOL-Plane': ['ArduPlane/quadplane'],
'TradHeli': [
'ArduCopter/heli.cpp',
'Tools/autotest/default_params/copter-heli',
'libraries/AP_Motors/AP_MotorsHeli',
],
'Sailboat': ['Rover/sailboat'],
'Sub': ['libraries/AP_Motors/AP_Motors6DOF'],
};
const labels = new Set();
for (const filename of filenames) {
// Generic checks
for (const [suffix, label] of Object.entries(generic_suffix_labels)) {
if (filename.endsWith(suffix)) {
labels.add(label);
break;
}
}
for (const [prefix, label] of Object.entries(generic_prefix_labels)) {
if (filename.startsWith(prefix)) {
labels.add(label);
break;
}
}
// Specific/niche vehicle checks
var specific = false; // There can only be one specific label per file.
for (const [vehicle, prefixes] of Object.entries(specific_vehicle_checks)) {
for (const prefix of prefixes) {
if (filename.startsWith(prefix)) {
labels.add(vehicle);
specific = true;
break;
}
}
if (specific) break;
}
if (specific) continue;
for (const [vehicle, label] of Object.entries(vehicle_sim_labels)) {
if (
filename === `Tools/autotest/${vehicle.toLowerCase()}.py` ||
filename.startsWith(`Tools/autotest/default_params/${vehicle.toLowerCase()}`) ||
filename.startsWith(`libraries/SITL/SIM_${vehicle}`)
) {
labels.add(label);
specific = true;
break;
}
}
if (specific) continue;
// General vehicle checks
for (const [vehicle, label] of Object.entries(vehicle_labels)) {
if (
filename.startsWith(vehicle) ||
filename.startsWith(`Tools/autotest/${vehicle}_Test`) ||
filename === `Tools/autotest/${vehicle.toLowerCase()}.py`
) {
labels.add(label);
break;
}
}
}
console.log(labels);
if (labels.size > 0) {
github.rest.issues.addLabels({
issue_number: prNumber,
owner: context.repo.owner,
repo: context.repo.repo,
labels: Array.from(labels),
});
}