mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
feat: github action to check if PR has requested labels before being merged (#19984)
* feat(action): check if pr includes requested labels * fix(action): add missing QA label * fix(action): check if no label prevents merging * fix(action): remove QA label check * fix(action): add missing reopened condition * fix(action): increase list of labels which prevent merges
This commit is contained in:
parent
1a218714a6
commit
0c2519397d
97
.github/scripts/check-pr-has-required-labels.ts
vendored
Normal file
97
.github/scripts/check-pr-has-required-labels.ts
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
import * as core from '@actions/core';
|
||||
import { context, getOctokit } from '@actions/github';
|
||||
import { GitHub } from '@actions/github/lib/utils';
|
||||
|
||||
main().catch((error: Error): void => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
async function main(): Promise<void> {
|
||||
// "GITHUB_TOKEN" is an automatically generated, repository-specific access token provided by GitHub Actions.
|
||||
const githubToken = process.env.GITHUB_TOKEN;
|
||||
if (!githubToken) {
|
||||
core.setFailed('GITHUB_TOKEN not found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Initialise octokit, required to call Github GraphQL API
|
||||
const octokit: InstanceType<typeof GitHub> = getOctokit(githubToken);
|
||||
|
||||
// Retrieve pull request info from context
|
||||
const prRepoOwner = context.repo.owner;
|
||||
const prRepoName = context.repo.repo;
|
||||
const prNumber = context.payload.pull_request?.number;
|
||||
if (!prNumber) {
|
||||
core.setFailed('Pull request number not found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Retrieve pull request labels
|
||||
const prLabels = await retrievePullRequestLabels(octokit, prRepoOwner, prRepoName, prNumber);
|
||||
|
||||
const preventMergeLabels = ["needs-qa", "QA'd but questions", "issues-found", "need-ux-ds-review", "blocked", "stale", "DO-NOT-MERGE"];
|
||||
|
||||
let hasTeamLabel = false;
|
||||
|
||||
// Check pull request has at least required QA label and team label
|
||||
for (const label of prLabels) {
|
||||
if (label.startsWith("team-") || label === "external-contributor") {
|
||||
console.log(`PR contains a team label as expected: ${label}`);
|
||||
hasTeamLabel = true;
|
||||
}
|
||||
if (preventMergeLabels.includes(label)) {
|
||||
throw new Error(`PR cannot be merged because it still contains this label: ${label}`);
|
||||
}
|
||||
if (hasTeamLabel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, throw an arror to prevent from merging
|
||||
let errorMessage = '';
|
||||
if (!hasTeamLabel) {
|
||||
errorMessage += 'No team labels found on the PR. ';
|
||||
}
|
||||
errorMessage += 'Please add the required label(s) before merging the PR.';
|
||||
throw new Error(errorMessage);
|
||||
|
||||
}
|
||||
|
||||
// This function retrieves the pull request on a specific repo
|
||||
async function retrievePullRequestLabels(octokit: InstanceType<typeof GitHub>, repoOwner: string, repoName: string, prNumber: number): Promise<string[]> {
|
||||
|
||||
const retrievePullRequestLabelsQuery = `
|
||||
query RetrievePullRequestLabels($repoOwner: String!, $repoName: String!, $prNumber: Int!) {
|
||||
repository(owner: $repoOwner, name: $repoName) {
|
||||
pullRequest(number: $prNumber) {
|
||||
labels(first: 100) {
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const retrievePullRequestLabelsResult: {
|
||||
repository: {
|
||||
pullRequest: {
|
||||
labels: {
|
||||
nodes: {
|
||||
name: string;
|
||||
}[];
|
||||
}
|
||||
};
|
||||
};
|
||||
} = await octokit.graphql(retrievePullRequestLabelsQuery, {
|
||||
repoOwner,
|
||||
repoName,
|
||||
prNumber,
|
||||
});
|
||||
|
||||
const pullRequestLabels = retrievePullRequestLabelsResult?.repository?.pullRequest?.labels?.nodes?.map(labelObject => labelObject?.name);
|
||||
|
||||
return pullRequestLabels || [];
|
||||
}
|
38
.github/workflows/check-pr-labels.yml
vendored
Normal file
38
.github/workflows/check-pr-labels.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: "Check PR has required labels"
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- labeled
|
||||
- unlabeled
|
||||
|
||||
jobs:
|
||||
check-pr-labels:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # This is needed to checkout all branches
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: yarn
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
|
||||
- name: Check PR has required labels
|
||||
id: check-pr-has-required-labels
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: npm run check-pr-has-required-labels
|
17
.github/workflows/do-not-merge.yml
vendored
17
.github/workflows/do-not-merge.yml
vendored
@ -1,17 +0,0 @@
|
||||
# Fails the pull request if it has the "DO-NOT-MERGE" label
|
||||
|
||||
name: Check "DO-NOT-MERGE" label
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, labeled, unlabeled, synchronize]
|
||||
|
||||
jobs:
|
||||
do-not-merge:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ contains(github.event.pull_request.labels.*.name, 'DO-NOT-MERGE') }}
|
||||
steps:
|
||||
- name: 'Check for label "DO-NOT-MERGE"'
|
||||
run: |
|
||||
echo 'This check fails PRs with the "DO-NOT-MERGE" label to block merging'
|
||||
exit 1
|
@ -96,7 +96,8 @@
|
||||
"fitness-functions": "ts-node development/fitness-functions/index.ts",
|
||||
"generate-beta-commit": "node ./development/generate-beta-commit.js",
|
||||
"validate-branch-name": "validate-branch-name",
|
||||
"add-release-label-to-pr-and-linked-issues": "ts-node ./.github/scripts/add-release-label-to-pr-and-linked-issues.ts"
|
||||
"add-release-label-to-pr-and-linked-issues": "ts-node ./.github/scripts/add-release-label-to-pr-and-linked-issues.ts",
|
||||
"check-pr-has-required-labels": "ts-node ./.github/scripts/check-pr-has-required-labels.ts"
|
||||
},
|
||||
"resolutions": {
|
||||
"simple-update-notifier@^1.0.0": "^2.0.0",
|
||||
|
Loading…
Reference in New Issue
Block a user