Skip to content

Commit

Permalink
Use /search API to check if first PR
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Cabé <[email protected]>
  • Loading branch information
kartben authored and stephanosio committed Apr 21, 2023
1 parent 2506eca commit 4920091
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 85 deletions.
54 changes: 20 additions & 34 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function run() {
firstContribution = yield isFirstIssue(client, sender, issue.number);
}
else {
firstContribution = yield isFirstPull(client, sender, issue.number, context.payload.action === 'closed');
firstContribution = yield isFirstOpenedOrMergedPR(client, sender, issue.number, context.payload.action === 'closed');
}
if (!firstContribution) {
console.log('Not the user\'s first contribution');
Expand All @@ -86,13 +86,7 @@ function run() {
yield client.rest.issues.createComment(Object.assign(Object.assign({}, context.repo), { issue_number: issue.number, body: issueMessage }));
}
else {
// Get the pull request details
const { data: pr } = yield client.rest.pulls.get(Object.assign(Object.assign({}, context.repo), { pull_number: issue.number }));
if (context.payload.action === 'closed' && !pr.merged) {
console.log('PR was closed without merging, skipping');
return;
}
const message = pr.merged ? prMergedMessage : prOpenedMessage;
const message = (context.payload.action === 'closed') ? prMergedMessage : prOpenedMessage;
console.log(`Adding message: ${message} to ${issueType} ${issue.number}`);
yield client.rest.pulls.createReview(Object.assign(Object.assign({}, context.repo), { pull_number: issue.number, body: message, event: 'COMMENT' }));
}
Expand Down Expand Up @@ -120,37 +114,29 @@ function isFirstIssue(client, sender, curIssueNumber) {
return true;
});
}
// It's someone's "first" PR if it's the first PR they've opened,
// or if it's their first closed PR that's been merged.
function isFirstPull(client, sender, curPullNumber, closed, page = 1) {
var _a;
function isFirstOpenedOrMergedPR(client, sender, curPullNumber, closed) {
return __awaiter(this, void 0, void 0, function* () {
// Provide console output if we loop for a while.
console.log('Checking...');
const { status, data: pulls } = yield client.rest.pulls.list(Object.assign(Object.assign({}, github.context.repo), { per_page: 100, page: page, state: 'all' }));
if (status !== 200) {
// get the PR's details
const { status: getPRStatus, data: pr } = yield client.rest.pulls.get(Object.assign(Object.assign({}, github.context.repo), { pull_number: curPullNumber }));
if (getPRStatus !== 200) {
throw new Error(`Received unexpected API status code ${status}`);
}
if (pulls.length === 0) {
return true;
let query = `repo:${github.context.repo.owner}/${github.context.repo.repo} type:pr author:${sender}`;
if (closed) {
let query = `repo:${github.context.repo.owner}/${github.context.repo.repo} type:pr author:${sender}`;
if (!pr.merged)
return false;
query += ` closed:<=${pr.closed_at} is:merged`;
}
for (const pull of pulls) {
const login = (_a = pull.user) === null || _a === void 0 ? void 0 : _a.login;
if (!closed) {
// If the PR is open, we only care if it's the first PR they've opened.
if (login === sender && pull.number < curPullNumber) {
return false;
}
}
else {
// If the PR is closed, we need to check if it's the first PR of theirs that's been merged.
// In other words, are there PRs from them other than "currPullNumber" that are merged.
if (login === sender && pull.merged_at !== null && pull.number != curPullNumber) {
return false;
}
}
else {
query += ` created:<=${pr.created_at}`;
}
const { status: searchStatus, data: searchResults } = yield client.rest.search.issuesAndPullRequests({ q: query });
if (searchStatus !== 200) {
throw new Error(`Received unexpected API status code ${status}`);
}
return yield isFirstPull(client, sender, curPullNumber, closed, page + 1);
// If current PR is the user's first to be created or merged, there should be exactly one result
return searchResults.total_count === 1;
});
}
run();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "first-interaction-action",
"version": "1.1.3-zephyr",
"version": "1.1.1-zephyr-1",
"description": "An action for greeting first time contributors.",
"main": "lib/main.js",
"scripts": {
Expand Down
71 changes: 21 additions & 50 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function run() {
issue.number
);
} else {
firstContribution = await isFirstPull(
firstContribution = await isFirstOpenedOrMergedPR(
client,
sender,
issue.number,
Expand All @@ -75,18 +75,7 @@ async function run() {
body: issueMessage
});
} else {
// Get the pull request details
const { data: pr } = await client.rest.pulls.get({
...context.repo,
pull_number: issue.number
});

if(context.payload.action === 'closed' && !pr.merged) {
console.log('PR was closed without merging, skipping');
return;
}

const message = pr.merged ? prMergedMessage : prOpenedMessage;
const message = (context.payload.action === 'closed') ? prMergedMessage : prOpenedMessage;

console.log(`Adding message: ${message} to ${issueType} ${issue.number}`);
await client.rest.pulls.createReview({
Expand Down Expand Up @@ -130,56 +119,38 @@ async function isFirstIssue(
return true;
}

// It's someone's "first" PR if it's the first PR they've opened,
// or if it's their first closed PR that's been merged.
async function isFirstPull(
async function isFirstOpenedOrMergedPR(
client: ReturnType<typeof github.getOctokit>,
sender: string,
curPullNumber: number,
closed: boolean,
page: number = 1
closed: boolean
): Promise<boolean> {
// Provide console output if we loop for a while.
console.log('Checking...');
const {status, data: pulls} = await client.rest.pulls.list({
// get the PR's details
const {status: getPRStatus, data: pr} = await client.rest.pulls.get({
...github.context.repo,
per_page: 100,
page: page,
state: 'all'
pull_number: curPullNumber
});

if (status !== 200) {
if (getPRStatus !== 200) {
throw new Error(`Received unexpected API status code ${status}`);
}

if (pulls.length === 0) {
return true;
let query = `repo:${github.context.repo.owner}/${github.context.repo.repo} type:pr author:${sender}`;
if (closed) {
let query = `repo:${github.context.repo.owner}/${github.context.repo.repo} type:pr author:${sender}`;
if(!pr.merged) return false;
query += ` closed:<=${pr.closed_at} is:merged`;
} else {
query += ` created:<=${pr.created_at}`;
}

for (const pull of pulls) {
const login = pull.user?.login;

if(!closed) {
// If the PR is open, we only care if it's the first PR they've opened.
if (login === sender && pull.number < curPullNumber) {
return false;
}
} else {
// If the PR is closed, we need to check if it's the first PR of theirs that's been merged.
// In other words, are there PRs from them other than "currPullNumber" that are merged.
if (login === sender && pull.merged_at!==null && pull.number != curPullNumber) {
return false;
}
}
const {status: searchStatus, data: searchResults} = await client.rest.search.issuesAndPullRequests({ q: query });

if (searchStatus !== 200) {
throw new Error(`Received unexpected API status code ${status}`);
}

return await isFirstPull(
client,
sender,
curPullNumber,
closed,
page + 1
);
// If current PR is the user's first to be created or merged, there should be exactly one result
return searchResults.total_count === 1;
}

run();

0 comments on commit 4920091

Please sign in to comment.