Skip to content

Commit

Permalink
Update probot (#51)
Browse files Browse the repository at this point in the history
* update probot version

* logger for the PRlabeledHandler

* go through all PRs, not first 100
  • Loading branch information
seymourisdead authored Jun 10, 2024
1 parent f7593d2 commit 1d959b0
Show file tree
Hide file tree
Showing 4 changed files with 699 additions and 644 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@slack/web-api": "^6.7.1",
"async-await-queue": "^1.2.0",
"axios": "^0.26.0",
"probot": "^12.3.0"
"probot": "^13.3.0"
},
"devDependencies": {
"@types/jest": "^26.0.19",
Expand Down
185 changes: 139 additions & 46 deletions src/modules/deploy_preview_label_handler/deploy_preview_label_handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {EmitterWebhookEvent, EmitterWebhookEventName} from "@octokit/webhooks"
import { Context } from "probot/lib/context";
import {logger} from "../../shared/logger";
import {isDryRun} from "../../shared/utils";

const FREE = "BFBFBF";
const OCCUPIED = "2fad40";
Expand All @@ -21,82 +23,128 @@ const COLORS: Record<string, string> = {
export const PRLabeledHandler = async (context: EmitterWebhookEvent<"pull_request.labeled"> & Omit<Context<EmitterWebhookEventName>, "id" | "name" | "payload">) => {
if (context.payload.repository.full_name !== "neondatabase/cloud" ||
context.payload.sender.type === 'Bot') {
logger('info', "Skip PRLabeledHandler because the sender is Bot")
return;
}

const label = context.payload.label;
if (!label) {
logger('info', "Skip PRLabeledHandler because no label")
return;
}
const labelName = label.name;
if (!labelName.match(/preview\/\w/)) {
logger('info', "Skip PRLabeledHandler because changed label is not preview related")
return;
}

const previewName: string = label.name.split('/')[1] || '';

if (!previewName) {
logger('info', "Skip PRLabeledHandler because preview name not found")
return;
}

// find other PRs with this label and remove the label from it
const prevPRs = await context.octokit.request('GET /repos/{owner}/{repo}/pulls', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
per_page: 100,
});
try {
const prevPRs = await context.octokit.paginate('GET /repos/{owner}/{repo}/pulls', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
});

prevPRs.data.forEach((pr) => {
if (pr.number !== context.payload.pull_request.number
&& pr.labels.find((prLabel) => prLabel.name === labelName)) {
context.octokit.request('DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}', {
prevPRs.forEach((pr) => {
if (pr.number !== context.payload.pull_request.number
&& pr.labels.find((prLabel) => prLabel.name === labelName)) {
logger('info', `Removing label ${labelName} from pr ${context.payload.pull_request.url}`)
try {
if (!isDryRun()) {
context.octokit.request('DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: pr.number,
name: labelName,
});
}
} catch (error) {
logger('error', `Removing label from previously marked PRs failed`, {error, context, label: labelName})
}
}
});
} catch (err) {
logger('error', `Failed to fetch PRs`, err)
}

try {
logger('info', `Marking the preview label as occupied`, {
labelName,
})

if (!isDryRun()) {
await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: pr.number,
name: labelName,
color: COLORS[previewName] || OCCUPIED,
description: `Preview is occupied by #${context.payload.pull_request.number}`,
});
}
});

await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
name: labelName,
color: COLORS[previewName] || OCCUPIED,
description: `Preview is occupied by #${context.payload.pull_request.number}`,
});
} catch (error) {
logger('error', `Failed to mark preview as occupied`, {
error,
context,
label: labelName,
})
}
}

export const PRUnLabeledHandler = async (context: EmitterWebhookEvent<"pull_request.unlabeled"> & Omit<Context<EmitterWebhookEventName>, "id" | "name" | "payload">) => {
if (context.payload.repository.full_name !== "neondatabase/cloud" ||
context.payload.sender.type === 'Bot') {
logger('info', "Skip PRUnLabeledHandler because the sender is Bot")
return;
}

const label = context.payload.label;
if (!label || !label.name.match(/preview\/\w/)) {
logger('info', "Skip PRUnLabeledHandler because changed label is not preview related")
return;
}

const labelName = label.name;
const previewName: string = label.name.split('/')[1] || '';

if (!previewName) {
logger('info', "Skip PRUnLabeledHandler because preview name not found")
return;
}

await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
name: labelName,
color: FREE,
description: 'Free preview environment',
});
try {
logger('info', "Marking preview as free", {
label: labelName,
context,
})
if (!isDryRun()) {
await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
name: labelName,
color: FREE,
description: 'Free preview environment',
});
}
} catch (error) {
logger('error', `Failed to mark preview as free`, {
label: labelName,
context,
error
})
}
}

export const PRMergedOrClosedHandler = async (context: EmitterWebhookEvent<"pull_request.closed"> & Omit<Context<EmitterWebhookEventName>, "id" | "name" | "payload">) => {
if (context.payload.repository.full_name !== "neondatabase/cloud" ||
context.payload.sender.type === 'Bot') {
logger('info', "Skip PRMergedOrClosedHandler because the sender is Bot")
return;
}

Expand All @@ -113,33 +161,63 @@ export const PRMergedOrClosedHandler = async (context: EmitterWebhookEvent<"pull
return;
}

await context.octokit.request('DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.pull_request.number,
name: labelName,
});
try {
logger('info', "deleting label from the PR", {
context,
label: labelName
})
if (!isDryRun()) {
await context.octokit.request('DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.pull_request.number,
name: labelName,
});
}
} catch (error) {
logger('error', "Failed to delete label from PR", {
error,
context,
label: labelName
})
}

await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
name: labelName,
color: FREE,
description: 'Free preview environment',
});
try {
logger('info', "marking preview as free", {
context,
label: labelName
})
if (!isDryRun()) {
await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
name: labelName,
color: FREE,
description: 'Free preview environment',
});
}
} catch (error) {
logger('error', "Failed to mark preview as free", {
error,
context,
label: labelName
})
}
});
}

export const PROpenedHandler = async (context: EmitterWebhookEvent<"pull_request.opened"> & Omit<Context<EmitterWebhookEventName>, "id" | "name" | "payload">) => {
if (context.payload.repository.full_name !== "neondatabase/cloud" ||
context.payload.sender.type === 'Bot') {
logger('info', "Skip PROpenedHandler because the sender is Bot")
return;
}

const label = context.payload.pull_request.labels.find((prLabel) => {
return prLabel.name.match(/preview\/\w/)
});
if (!label) {
logger('info', "Skip PROpenedHandler because PR has no labels")
return;
}

Expand All @@ -148,14 +226,29 @@ export const PROpenedHandler = async (context: EmitterWebhookEvent<"pull_request
const previewName: string = label.name.split('/')[1] || '';

if (!previewName) {
logger('info', "Skip PROpenedHandler because PR has no preview labels")
return;
}

await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
name: labelName,
color: COLORS[previewName] || OCCUPIED,
description: `Preview is occupied by #${context.payload.pull_request.number}`,
});
try {
logger('info', `Marking the preview label as occupied`, {
labelName,
})

if (!isDryRun()) {
await context.octokit.request('PATCH /repos/{owner}/{repo}/labels/{name}', {
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
name: labelName,
color: COLORS[previewName] || OCCUPIED,
description: `Preview is occupied by #${context.payload.pull_request.number}`,
});
}
} catch (error) {
logger('error', `Failed to mark preview as occupied`, {
error,
context,
label: labelName,
})
}
}
4 changes: 2 additions & 2 deletions src/modules/status_last_updated_handler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export const status_last_updated_handler = (app: Probot) => {
return;
}

// @ts-ignore
if (context.payload.changes && context.payload.changes.fieldId !== statusFieldId) {
if (context.payload.action === "edited"
&& context.payload.changes.field_value.field_node_id !== statusFieldId) {
logger("info", 'status_last_updated_handler skipped because changes are not in status field')
return;
}
Expand Down
Loading

0 comments on commit 1d959b0

Please sign in to comment.