Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cicd e2e label requirements + pr automation #12243

Merged
merged 22 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from 19 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: 75 additions & 6 deletions .github/scripts/bitrise/run-bitrise-e2e-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,33 @@ main().catch((error: Error): void => {
process.exit(1);
});

// Determine whether E2E should run and provide the associated reason
function shouldRunBitriseE2E(antiLabel: boolean, hasSmokeTestLabel: boolean, isDocs: boolean, isFork: boolean, isMergeQueue: boolean): [boolean, string] {

const conditions = [
{condition: hasSmokeTestLabel, message: "The smoke test label is present.", shouldRun: true},
{condition: isFork, message: "The pull request is from a fork.", shouldRun: false},
{condition: isDocs, message: "The pull request is documentation related.", shouldRun: false},
{condition: isMergeQueue, message: "The pull request is part of a merge queue.", shouldRun: false},
{condition: antiLabel, message: "The pull request has the anti-label.", shouldRun: false}
];

// Iterate through conditions to determine action
for (const {condition, message, shouldRun} of conditions) {
if (condition) {
return [shouldRun, message];
}
}

// Default case if no conditions met
return [false, "Unexpected scenario or no relevant labels found."];
}


async function main(): Promise<void> {
const githubToken = process.env.GITHUB_TOKEN;
const e2eLabel = process.env.E2E_LABEL;
const antiLabel = process.env.NO_E2E_LABEL;
const e2ePipeline = process.env.E2E_PIPELINE;
const workflowName = process.env.WORKFLOW_NAME;
const triggerAction = context.payload.action as PullRequestTriggerType;
Expand All @@ -42,6 +66,17 @@ async function main(): Promise<void> {
process.exit(1);
}

if (!antiLabel) {
core.setFailed('NO_E2E_LABEL not found');
process.exit(1);
}

// Logging for Pipeline debugging
console.log(`Trigger action: ${triggerAction}`);
console.log(`event: ${context.eventName}`);
console.log(`pullRequestNumber: ${pullRequestNumber}`);


const octokit: InstanceType<typeof GitHub> = getOctokit(githubToken);

const { data: prData } = await octokit.rest.pulls.get({
Expand All @@ -50,30 +85,55 @@ async function main(): Promise<void> {
pull_number: pullRequestNumber,
});

const docs = prData.title.startsWith("docs:");

// Get the latest commit hash
const latestCommitHash = prData.head.sha;

// Check if the e2e smoke label is applied
// Grab flags and labels
const labels = prData.labels;
const hasSmokeTestLabel = labels.some((label) => label.name === e2eLabel);
const hasAntiLabel = labels.some((label) => label.name === antiLabel);
const fork = context.payload.pull_request?.head.repo.fork || false;
const mergeQueue = (context.eventName === 'merge_group')


// Pass check since e2e smoke label is not applied
if (!hasSmokeTestLabel) {
console.log(`Docs: ${docs}`);
console.log(`Fork: ${fork}`);
console.log(`Merge Queue: ${mergeQueue}`);
console.log(`Has smoke test label: ${hasSmokeTestLabel}`);
console.log(`Anti label: ${hasAntiLabel}`);


// One of these two labels must exist if not we bomb out
if (!hasSmokeTestLabel && !hasAntiLabel) {
core.setFailed(
`At least 1 E2E Label must be Applied either ${e2eLabel} or ${antiLabel}`,
);
process.exit(1);
}

const [shouldRun, reason] = shouldRunBitriseE2E(hasAntiLabel, hasSmokeTestLabel, docs, fork, mergeQueue);
console.log(`Should run: ${shouldRun}, Reason: ${reason}`);

//
jake-perkins marked this conversation as resolved.
Show resolved Hide resolved
if (!shouldRun) {
console.log(
`"${e2eLabel}" label not applied. Skipping Bitrise status check.`,
`Skipping Bitrise status check. due to the following reason: ${reason}`,
);

// Post success status (skipped)
const createStatusCheckResponse = await octokit.rest.checks.create({
owner,
repo,
name: statusCheckName,
head_sha: latestCommitHash,
status: StatusCheckStatusType.Completed,
conclusion: CompletedConclusionType.Success,
conclusion: CompletedConclusionType.Success,
started_at: new Date().toISOString(),
output: {
title: statusCheckTitle,
summary: 'Skip run since no E2E smoke label is applied',
summary: `Skip run since ${reason}`,
},
});

Expand All @@ -95,6 +155,8 @@ async function main(): Promise<void> {
triggerAction === PullRequestTriggerType.Labeled &&
context.payload?.label?.name === e2eLabel
) {

console.log(`Starting Bitrise build for commit ${latestCommitHash}`);
// Configure Bitrise configuration for API call
const data = {
build_params: {
Expand Down Expand Up @@ -222,6 +284,8 @@ async function main(): Promise<void> {
}

// Post pending status
console.log(`Posting pending status for commit ${latestCommitHash}`);

const createStatusCheckResponse = await octokit.rest.checks.create({
owner,
repo,
Expand Down Expand Up @@ -256,6 +320,9 @@ async function main(): Promise<void> {
const lastCommentPage = Math.ceil(
numberOfTotalComments / numberOfCommentsToCheck,
);

console.log("Listing Comments..")
Cal-L marked this conversation as resolved.
Show resolved Hide resolved

const { data: latestCommentBatch } = await octokit.rest.issues.listComments({
owner,
repo,
Expand Down Expand Up @@ -287,6 +354,8 @@ async function main(): Promise<void> {

// Bitrise comment doesn't exist, post fail status
if (!bitriseComment) {

console.log(`Btrise comment not detected for commit ${latestCommitHash}`);
jake-perkins marked this conversation as resolved.
Show resolved Hide resolved
// Post fail status
const createStatusCheckResponse = await octokit.rest.checks.create({
owner,
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/auto-draft-prs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Auto Draft

on:
pull_request:
types: [opened]
branches:
- main

permissions:
pull-requests: write
contents: read
issues: write

jobs:
process_pr:
runs-on: ubuntu-latest
steps:
- name: Convert PR to Draft and Add Label
uses: actions/github-script@v6
with:
script: |
// Convert PR to draft
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
draft: true
});

// Check if the PR title includes "docs:" or if it's from a fork
if (context.payload.pull_request.title.includes('docs:') || context.payload.pull_request.head.repo.fork) {
// Add label "No E2E Smoke Needed"
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: ['No E2E Smoke Needed']
});
}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -323,4 +323,4 @@ jobs:
else
echo "All jobs passed step skipped. Block PR."
exit 1
fi
fi
20 changes: 3 additions & 17 deletions .github/workflows/run-bitrise-e2e-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,18 @@ on:
types: [edited, deleted]
pull_request:
types: [opened, reopened, labeled, unlabeled, synchronize]
merge_group: # Trigger on merge queue events to satisfy the branch protection rules
types: [checks_requested]

env:
E2E_LABEL: 'Run Smoke E2E'
NO_E2E_LABEL: 'No E2E Smoke Needed'
E2E_PIPELINE: 'pr_smoke_e2e_pipeline'
WORKFLOW_NAME: 'run-bitrise-e2e-check'

jobs:
is-fork-pull-request:
name: Determine pull request source
if: ${{ github.event.issue.pull_request || github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
outputs:
IS_FORK: ${{ steps.is-fork.outputs.IS_FORK }}
steps:
- uses: actions/checkout@v3
- name: Determine whether this PR is from a fork
id: is-fork
run: echo "IS_FORK=$(gh pr view --json isCrossRepository --jq '.isCrossRepository' "${PR_NUMBER}" )" >> "$GITHUB_OUTPUT"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number || github.event.issue.number }}

run-bitrise-e2e-check:
needs: is-fork-pull-request
runs-on: ubuntu-latest
if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
permissions:
pull-requests: write
contents: write
Expand Down
Loading