mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-09-02 22:20:43 +02:00
all the triggers are in a different workflow and all the big jobs in separate resuable workflows
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
# 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
|
||||
|
||||
name: PR Detector Labels
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- synchronize
|
||||
workflow_call:
|
||||
inputs:
|
||||
pr_number:
|
||||
@@ -25,32 +23,30 @@ jobs:
|
||||
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
|
||||
});
|
||||
|
||||
const prNumber = ${{ inputs.pr_number }};
|
||||
|
||||
/*
|
||||
* Infrastructure PRs do not receive detector labels.
|
||||
* Get the current PR labels.
|
||||
*/
|
||||
const body = pr.body || '';
|
||||
const { data: currentLabels } =
|
||||
await github.rest.issues.listLabelsOnIssue({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber
|
||||
});
|
||||
|
||||
const infrastructureSelected =
|
||||
/-\s*\[[xX]\]\s*Infrastructure\b/.test(body);
|
||||
const currentLabelNames =
|
||||
currentLabels.map(label => label.name);
|
||||
|
||||
if (infrastructureSelected) {
|
||||
if (currentLabelNames.includes('Infrastructure')) {
|
||||
core.info(
|
||||
'Infrastructure PR detected. Skipping detector label detection.'
|
||||
'Infrastructure label found. Skipping detector label detection.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
core.info(
|
||||
`Not an infrastructure PR. Proceeding with detector label detection.`
|
||||
`Infrastructure label not found. Proceeding with detector label detection.`
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -184,6 +180,14 @@ jobs:
|
||||
* 4. Detect detector from PR title/description
|
||||
* --------------------------------------------------
|
||||
*/
|
||||
|
||||
const { data: pr } =
|
||||
await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: prNumber
|
||||
});
|
||||
|
||||
const prText = [
|
||||
pr.title || '',
|
||||
pr.body || ''
|
||||
@@ -204,25 +208,9 @@ jobs:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* --------------------------------------------------
|
||||
* 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
|
||||
* 5. Add detected detector labels
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* Existing labels are left untouched.
|
||||
@@ -250,7 +238,7 @@ jobs:
|
||||
|
||||
/*
|
||||
* --------------------------------------------------
|
||||
* 9. Summary
|
||||
* 6. Summary
|
||||
* --------------------------------------------------
|
||||
*/
|
||||
core.info(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# This workflow is triggered when opening/reopening PR or editing the Pr description or changing labels. It ignores unrelated label changes. It validates the PR type and Breaking API, then sets the labels. It also runs the PR milestone workflow to set the milestone based on the PR type label.
|
||||
# This workflow is triggered when opening/reopening PR, editing the PR description or changing labels. It ignores unrelated label changes. It runs PR type validation and if it succeeds, it runs PR milestone and detector labels workflow in parallel.
|
||||
name: PR Edit Trigger
|
||||
|
||||
on:
|
||||
@@ -15,20 +15,19 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
validate-pr:
|
||||
name: Validate PR
|
||||
check-pr-trigger:
|
||||
name: Check PR Trigger
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
validated: ${{ steps.validate.outputs.validated }}
|
||||
require_validation: ${{ steps.check.outputs.require_validation }}
|
||||
|
||||
steps:
|
||||
- name: Validate PR type and Breaking API
|
||||
id: validate
|
||||
- name: Check whether PR Validation is required
|
||||
id: check
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
core.setOutput('validated', 'true');
|
||||
|
||||
/*
|
||||
* If triggered by label change, ignore unrelated labels.
|
||||
*/
|
||||
@@ -47,166 +46,25 @@ jobs:
|
||||
core.info(
|
||||
`Ignoring unrelated label change: ${changedLabel}`
|
||||
);
|
||||
core.setOutput('validated', 'false');
|
||||
core.setOutput('require_validation', 'false');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the body contents of PR
|
||||
*/
|
||||
const prNumber = context.payload.pull_request?.number;
|
||||
core.setOutput('require_validation', 'true');
|
||||
|
||||
if (!prNumber) {
|
||||
core.setFailed('Unable to determine PR number.');
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: pr } =
|
||||
await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: prNumber
|
||||
});
|
||||
|
||||
const body = pr.body || '';
|
||||
|
||||
/*
|
||||
* Check which primary PR type is selected.
|
||||
*/
|
||||
const feature =
|
||||
/-\s*\[[xX]\]\s*Feature\b/.test(body);
|
||||
|
||||
const bugFix =
|
||||
/-\s*\[[xX]\]\s*Bug Fix\b/.test(body);
|
||||
|
||||
const infrastructure =
|
||||
/-\s*\[[xX]\]\s*Infrastructure\b/.test(body);
|
||||
|
||||
const primaryTypes = [
|
||||
feature && 'Feature',
|
||||
bugFix && 'Bug Fix',
|
||||
infrastructure && 'Infrastructure'
|
||||
].filter(Boolean);
|
||||
|
||||
/*
|
||||
* Exactly one primary PR type must be selected.
|
||||
*/
|
||||
if (primaryTypes.length !== 1) {
|
||||
core.setFailed(
|
||||
'Exactly one primary PR type must be selected. Select exactly one of: Feature, Bug Fix, Infrastructure in the description.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const primaryType = primaryTypes[0];
|
||||
|
||||
/*
|
||||
* Infrastructure PRs cannot be Breaking API.
|
||||
*/
|
||||
const breakingApi =
|
||||
/-\s*\[[xX]\]\s*This is a Breaking API change\b/.test(body);
|
||||
|
||||
if (infrastructure && breakingApi) {
|
||||
core.setFailed(
|
||||
'Infrastructure PRs cannot be Breaking API changes. Deselect Breaking API or change the PR type to Feature or Bug Fix in the description.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
core.info(`Primary PR type: ${primaryType}`);
|
||||
core.info(
|
||||
`Breaking API: ${breakingApi ? 'yes' : 'no'}`
|
||||
);
|
||||
|
||||
/*
|
||||
* Get the labels currently on the PR.
|
||||
*/
|
||||
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);
|
||||
|
||||
const primaryLabels = [
|
||||
'Feature',
|
||||
'Bug Fix',
|
||||
'Infrastructure'
|
||||
];
|
||||
|
||||
const selectedPrimary =
|
||||
primaryLabels.filter(label =>
|
||||
currentLabelNames.includes(label)
|
||||
);
|
||||
|
||||
if (selectedPrimary.length > 1) {
|
||||
core.setFailed(
|
||||
`Invalid PR label state: multiple primary labels are present: ${selectedPrimary.join(', ')}. Remove these primary type labels 'Feature, Bug Fix, Infrastructure' and let the workflow set the correct label based on the PR description.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedPrimary.length === 1 && selectedPrimary[0] !== primaryType) {
|
||||
core.setFailed(
|
||||
`Invalid PR label state: the PR body selects ${primaryType}, but the existing label is ${selectedPrimary[0]}. Remove the existing label and let the workflow set the correct label based on the PR description.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
currentLabelNames.includes('Breaking API') &&
|
||||
infrastructure
|
||||
) {
|
||||
core.setFailed(
|
||||
'Infrastructure PRs cannot have the Breaking API label.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!breakingApi &&
|
||||
currentLabelNames.includes('Breaking API')
|
||||
) {
|
||||
core.setFailed(
|
||||
'Breaking API label is present but the PR body does not mark the checkbox. Remove the label or check the checkbox in the PR body.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
breakingApi &&
|
||||
!currentLabelNames.includes('Breaking API')
|
||||
) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
labels: ['Breaking API']
|
||||
});
|
||||
|
||||
core.info('Added label: Breaking API');
|
||||
}
|
||||
|
||||
if (!currentLabelNames.includes(primaryType)) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
labels: [primaryType]
|
||||
});
|
||||
|
||||
core.info(`Added label: ${primaryType}`);
|
||||
}
|
||||
|
||||
core.info('PR validation passed.');
|
||||
validate-pr-type:
|
||||
needs: check-pr-trigger
|
||||
if: ${{ needs.check-pr-trigger.outputs.require_validation == 'true' }}
|
||||
uses: ./.github/workflows/pr_type_validation.yaml
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: read
|
||||
|
||||
milestone:
|
||||
needs: validate-pr
|
||||
if: ${{ needs.validate-pr.outputs.validated == 'true' }}
|
||||
needs: validate-pr-type
|
||||
uses: ./.github/workflows/pr_milestone.yaml
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
@@ -215,8 +73,7 @@ jobs:
|
||||
contents: read
|
||||
|
||||
detector-labels:
|
||||
needs: validate-pr
|
||||
if: ${{ needs.validate-pr.outputs.validated == 'true' }}
|
||||
needs: validate-pr-type
|
||||
uses: ./.github/workflows/pr_detector_labels.yaml
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
|
||||
@@ -1,138 +1,18 @@
|
||||
# This workflow is triggered when a PR is synchronized.
|
||||
# It checks the latest PR Validation result for the PR.
|
||||
# If PR Validation has not completed or was unsuccessful, this workflow fails.
|
||||
# If PR Validation succeeded, it calls the detector label workflow.
|
||||
# This workflow is triggered when code is pushed to a pull request. It runs the reusable detector label workflow.
|
||||
|
||||
name: PR Synchronize Trigger
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches-ignore:
|
||||
- 'dev/pr_automation*'
|
||||
- 'dev/test_pr_automation*'
|
||||
types:
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
check-validation:
|
||||
name: Check PR Validation
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check PR Validation result
|
||||
id: check
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const prNumber =
|
||||
context.payload.pull_request.number;
|
||||
|
||||
const validationWorkflowName =
|
||||
jobs:
|
||||
'PR Validation';
|
||||
|
||||
|
||||
/*
|
||||
* Get the current PR.
|
||||
*/
|
||||
const { data: pr } =
|
||||
await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: prNumber
|
||||
});
|
||||
|
||||
const headBranch = pr.head.ref;
|
||||
|
||||
core.info(
|
||||
`Looking for PR Validation runs on branch "${headBranch}".`
|
||||
);
|
||||
|
||||
/*
|
||||
* Get PR Validation workflow runs for this branch.
|
||||
*/
|
||||
const runs = await github.paginate(
|
||||
github.rest.actions.listWorkflowRunsForRepo,
|
||||
{
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
event: 'pull_request',
|
||||
branch: headBranch,
|
||||
per_page: 100
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
* Keep only PR Validation runs.
|
||||
*/
|
||||
const validationRuns = runs.filter(
|
||||
run => run.name === validationWorkflowName
|
||||
);
|
||||
|
||||
/*
|
||||
* Validation has not been performed for this PR.
|
||||
*/
|
||||
if (validationRuns.length === 0) {
|
||||
core.setFailed(
|
||||
`No PR Validation run found for PR #${prNumber}.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the most recent PR Validation run.
|
||||
*/
|
||||
const validationRun = validationRuns.sort(
|
||||
(a, b) =>
|
||||
new Date(b.created_at) -
|
||||
new Date(a.created_at)
|
||||
)[0];
|
||||
|
||||
jobs:
|
||||
core.info(
|
||||
`Latest PR Validation run: ${validationRun.id}`
|
||||
);
|
||||
|
||||
core.info(
|
||||
`Status: ${validationRun.status}`
|
||||
);
|
||||
|
||||
core.info(
|
||||
`Conclusion: ${validationRun.conclusion}`
|
||||
);
|
||||
|
||||
/*
|
||||
* PR Validation must have completed.
|
||||
*/
|
||||
if (validationRun.status !== 'completed') {
|
||||
core.setFailed(
|
||||
`PR Validation for PR #${prNumber} has not completed. Current status: ${validationRun.status}.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* PR Validation must have succeeded.
|
||||
*/
|
||||
if (validationRun.conclusion !== 'success') {
|
||||
core.setFailed(
|
||||
`PR Validation for PR #${prNumber} did not succeed. Conclusion: ${validationRun.conclusion}.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* PR Validation succeeded.
|
||||
*/
|
||||
core.info(
|
||||
`PR Validation for PR #${prNumber} succeeded. Running detector labels.`
|
||||
);
|
||||
|
||||
detector-labels:
|
||||
name: Detect detector labels on synchronize
|
||||
needs: check-validation
|
||||
uses: ./.github/workflows/pr_detector_labels.yaml
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
|
||||
Reference in New Issue
Block a user