Files
slsDetectorPackage/.github/workflows/pr_detector_labels.yaml
T
maliakal_d ddb65092f2
Build on RHEL9 docker image / build (push) Successful in 4m13s
Build on RHEL8 docker image / build (push) Successful in 5m11s
Run Simulator Tests on local RHEL9 / build (push) Successful in 20m6s
Run Simulator Tests on local RHEL8 / build (push) Successful in 23m26s
naming
2026-08-28 13:48:47 +02:00

262 lines
7.9 KiB
YAML

# This reusable workflow detects detector labels for pull requests. This workflow is ignored for Infrastructure Prs. It checks whole word matching of detector names in server folders, changed code and PR title/description. If a detector is detected, the corresponding label is added to the PR. Existing labels are left untouched. Detector labels are never removed automatically.
name: PR Synchronize Trigger
on:
pull_request:
types:
- synchronize
workflow_call:
inputs:
pr_number:
required: true
type: number
permissions:
pull-requests: write
issues: read
jobs:
detector-labels:
name: Detect detector labels
runs-on: ubuntu-latest
steps:
- name: Detect detector labels
uses: actions/github-script@v8
with:
script: |
const prNumber = ${{ inputs.pr_number || github.event.pull_request.number }};
const { data: pr } =
await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
/*
* Infrastructure PRs do not receive detector labels.
*/
const body = pr.body || '';
const infrastructureSelected =
/-\s*\[[xX]\]\s*Infrastructure\b/.test(body);
if (infrastructureSelected) {
core.info(
'Infrastructure PR detected. Skipping detector label detection.'
);
return;
}
core.info(
`Not an infrastructure PR. Proceeding with detector label detection.`
);
/*
* Known detector labels.
*/
const detectorLabels = [
'Ctb',
'Eiger',
'Moench',
'Mythen3',
'Jungfrau',
'Gotthard2',
'Matterhorn',
'Xilinx_ctb'
];
/*
* Check whether a detector name appears as a
* complete word, case-insensitively.
*/
function containsDetector(text, detector) {
const regex = new RegExp(
`\\b${detector}\\b`,
'i'
);
return regex.test(text);
}
/*
* Detectors detected by any detection method.
*/
const detectedDetectors = new Set();
/*
* --------------------------------------------------
* 1. Get all files changed by the PR
* --------------------------------------------------
*/
const files = await github.paginate(
github.rest.pulls.listFiles,
{
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
per_page: 100
}
);
core.info(
`Found ${files.length} changed files.`
);
/*
* --------------------------------------------------
* 2. Detect detector from detector-server folders
* --------------------------------------------------
*
* Examples:
*
* slsDetectorServers/eigerDetectorServer/...
* ↓
* Eiger
*
* slsDetectorServers/xilinx_ctbDetectorServer/...
* ↓
* Xilinx_ctb
*/
for (const file of files) {
const match = file.filename.match(
/^slsDetectorServers\/([^/]+)DetectorServer\//
);
if (!match) {
continue;
}
const detectorName = match[1];
/*
* Remove "DetectorServer" and capitalize
* the first character.
*/
const detector =
detectorName.charAt(0).toUpperCase() +
detectorName.slice(1);
if (detectorLabels.includes(detector)) {
detectedDetectors.add(detector);
core.info(
`Detected ${detector} from detector-server path: ${file.filename}`
);
}
}
/*
* --------------------------------------------------
* 3. Detect detector from changed code
* --------------------------------------------------
*
* Only the PR patch is searched.
*
* Therefore, text that already existed elsewhere
* in an unchanged file does not trigger a label.
*/
for (const file of files) {
if (!file.patch) {
continue;
}
for (const detector of detectorLabels) {
if (
containsDetector(
file.patch,
detector
)
) {
detectedDetectors.add(detector);
core.info(
`Detected ${detector} in changed code: ${file.filename}`
);
}
}
}
/*
* --------------------------------------------------
* 4. Detect detector from PR title/description
* --------------------------------------------------
*/
const prText = [
pr.title || '',
pr.body || ''
].join('\n');
for (const detector of detectorLabels) {
if (
containsDetector(
prText,
detector
)
) {
detectedDetectors.add(detector);
core.info(
`Detected ${detector} in PR title or description.`
);
}
}
/*
* --------------------------------------------------
* 5. Get current PR labels
* --------------------------------------------------
*/
const { data: currentLabels } =
await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
const currentLabelNames =
currentLabels.map(label => label.name);
/*
* --------------------------------------------------
* 6. Add detected detector labels
* --------------------------------------------------
*
* Existing labels are left untouched.
*
* Detector labels are NEVER removed automatically.
*/
for (const detector of detectedDetectors) {
if (!currentLabelNames.includes(detector)) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [detector]
});
core.info(
`Added detector label: ${detector}`
);
} else {
core.info(
`Detector label already exists: ${detector}`
);
}
}
/*
* --------------------------------------------------
* 9. Summary
* --------------------------------------------------
*/
core.info(
`Detected detectors: ${
detectedDetectors.size > 0
? [...detectedDetectors].join(', ')
: 'none'
}`
);