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: disable permit gen for users in non collaborative issues #182

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
7ee3654
feat: disable permit gen for users in non collaborative issues
ishowvel Nov 7, 2024
ac5a724
feat: disable permit gen for users in non collaborative issues
ishowvel Nov 7, 2024
7649094
Merge branch 'ubiquity-os-marketplace:development' into admin-gen
ishowvel Nov 10, 2024
b446e97
fix: octokit
ishowvel Nov 10, 2024
7a2a25b
chore: updated manifest.json and dist build
github-actions[bot] Nov 10, 2024
a38df6f
fix: repo name and owner id
ishowvel Nov 10, 2024
9d0bb10
chore: updated manifest.json and dist build
github-actions[bot] Nov 10, 2024
dc2771e
chore: sync
ishowvel Nov 11, 2024
d2f32fb
chore: sync
ishowvel Nov 11, 2024
2533df1
fix: add permission handler
ishowvel Nov 11, 2024
233a4d4
fix: logging and comments
ishowvel Nov 12, 2024
4733d91
fix: use built in rest method
ishowvel Nov 13, 2024
431390d
chore: add old polyfill
ishowvel Nov 14, 2024
03addcc
chore: add old polyfill
ishowvel Nov 14, 2024
63d80b1
Merge remote-tracking branch 'upstream/development' into admin-gen
ishowvel Nov 18, 2024
e2285b8
fix: add a check for reviews
ishowvel Nov 19, 2024
6df4af0
chore: updated manifest.json and dist build
github-actions[bot] Nov 19, 2024
0255a1e
feat: add all test cases
ishowvel Nov 19, 2024
7e22024
chore: updated manifest.json and dist build
github-actions[bot] Nov 19, 2024
46a2691
Merge remote-tracking branch 'upstream/development' into admin-gen
ishowvel Nov 20, 2024
0d38af0
Merge branch 'admin-gen' of https://github.com/ishowvel/text-conversa…
ishowvel Nov 20, 2024
6ae7448
chore: updated manifest.json and dist build
github-actions[bot] Nov 20, 2024
086af49
fix: correctly label issue to be collaborative and fix tests
ishowvel Nov 20, 2024
245b4db
chore: updated manifest.json and dist build
github-actions[bot] Nov 20, 2024
6876a4e
chore: simplify
ishowvel Nov 21, 2024
0370794
chore: updated manifest.json and dist build
github-actions[bot] Nov 21, 2024
5eb2981
chore: simplify
ishowvel Nov 21, 2024
80f51db
chore: updated manifest.json and dist build
github-actions[bot] Nov 21, 2024
805a1a6
fix: correctly generate permit comments
ishowvel Nov 23, 2024
4dde5d1
chore: updated manifest.json and dist build
github-actions[bot] Nov 23, 2024
1dab9b8
chore: refactor and apply suggestion
ishowvel Nov 25, 2024
2d31d97
chore: add old polyfill
ishowvel Nov 25, 2024
352cebc
fix: remove unnecessary Promise.resolve
ishowvel Nov 26, 2024
2d963ec
chore: updated manifest.json and dist build
github-actions[bot] Nov 26, 2024
25ada43
chore: add old polyfill
ishowvel Nov 26, 2024
a741cdc
chore: updated manifest.json and dist build
github-actions[bot] Nov 26, 2024
6d02d51
chore: add old polyfill
ishowvel Nov 26, 2024
4e3305c
fix: correctly fetch user perm
ishowvel Nov 26, 2024
688596f
chore update mock
ishowvel Nov 26, 2024
2ee7e83
chore: add polyfill
ishowvel Nov 26, 2024
f0b0bc3
fix: if no pull req return false for reviews
ishowvel Nov 27, 2024
322d6a2
fix: comapare issue creator and not assignee
ishowvel Nov 29, 2024
c3780bd
chore: add old polyfill
ishowvel Nov 30, 2024
45d739f
chore: remove duplicacy
ishowvel Dec 3, 2024
e2abfd0
chore: add old polyfill
ishowvel Dec 3, 2024
a5d16a2
fix: remove unnecessary mock in favour of mocked api endpoint
ishowvel Dec 3, 2024
e41ebbe
chore: add old polyfill
ishowvel Dec 5, 2024
21e78c9
chore: updated manifest.json and dist build
github-actions[bot] Dec 5, 2024
e7ef2ce
chore: add old polyfill
ishowvel Dec 5, 2024
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
6 changes: 3 additions & 3 deletions dist/index.js

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions src/helpers/checkers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { GitHubPullRequestReviewState } from "../github-types";
import { IssueActivity } from "../issue-activity";
import { ContextPlugin } from "../types/plugin-input";

export function isCollaborative(data: Readonly<IssueActivity>) {
if (!data.self?.closed_by || !data.self.user) return false;
const issueCreator = data.self.user;

if (data.self.closed_by.id === issueCreator.id) {
const pricingEventsByNonAssignee = data.events.find(
(event) =>
event.event === "labeled" &&
"label" in event &&
(event.label.name.startsWith("Time: ") || event.label.name.startsWith("Priority: ")) &&
event.actor.id !== issueCreator.id
);
return !!pricingEventsByNonAssignee || !!nonAssigneeApprovedReviews(data);
}
return true;
}

export function nonAssigneeApprovedReviews(data: Readonly<IssueActivity>) {
if (data.linkedReviews[0] && data.self?.assignee) {
const pullRequest = data.linkedReviews[0].self;
const pullReview = data.linkedReviews[0];
const reviewsByNonAssignee: GitHubPullRequestReviewState[] = [];
const assignee = data.self.assignee;

if (pullReview.reviews && pullRequest) {
for (const review of pullReview.reviews) {
const isReviewRequestedForUser =
"requested_reviewers" in pullRequest &&
pullRequest.requested_reviewers?.some((o) => o.id === review.user?.id);
if (!isReviewRequestedForUser && review.user?.id) {
reviewsByNonAssignee.push(review);
}
}
}
return reviewsByNonAssignee.filter((v) => v.user?.id !== assignee.id && v.state === "APPROVED");
}
return false;
}

export async function isAdmin(username: string, context: ContextPlugin): Promise<boolean> {
const octokit = context.octokit;
try {
const userPerms = await octokit.rest.orgs.getMembershipForUser({
org: context.payload.repository.owner.login,
username: username,
});
return userPerms.data.role === "admin" || userPerms.data.role === "billing_manager";
} catch (e) {
context.logger.debug(`${username} is not a member of ${context.payload.repository.owner.login}`, { e });
return false;
}
}
11 changes: 10 additions & 1 deletion src/parser/github-comment-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { getErc20TokenSymbol } from "../helpers/web3";
import { IssueActivity } from "../issue-activity";
import { BaseModule } from "../types/module";
import { GithubCommentScore, Result } from "../types/results";
import { postComment } from "@ubiquity-os/plugin-sdk";
import { isAdmin, isCollaborative } from "../helpers/checkers";

interface SortedTasks {
issues: { specification: GithubCommentScore | null; comments: GithubCommentScore[] };
Expand Down Expand Up @@ -104,13 +106,20 @@ export class GithubCommentModule extends BaseModule {
}

async transform(data: Readonly<IssueActivity>, result: Result): Promise<Result> {
const isIssueCollaborative = isCollaborative(data);
const isUserAdmin = data.self?.user ? await isAdmin(data.self.user.login, this.context) : false;
const body = await this.getBodyContent(result);
if (this._configuration?.debug) {
fs.writeFileSync(this._debugFilePath, body);
}
if (this._configuration?.post) {
try {
await this.postComment(body);
if (Object.values(result).some((v) => v.permitUrl) || isIssueCollaborative || isUserAdmin) {
await this.postComment(body);
} else {
const errorLog = this.context.logger.error("Issue is non-collaborative. Skipping permit generation.");
await postComment(this.context, errorLog);
}
} catch (e) {
this.context.logger.error(`Could not post GitHub comment: ${e}`);
}
Expand Down
15 changes: 15 additions & 0 deletions src/parser/permit-generation-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { getRepo, parseGitHubUrl } from "../start";
import { EnvConfig } from "../types/env-type";
import { BaseModule } from "../types/module";
import { Result } from "../types/results";
import { isAdmin, isCollaborative } from "../helpers/checkers";

interface Payload {
evmNetworkId: number;
Expand All @@ -38,6 +39,12 @@ export class PermitGenerationModule extends BaseModule {
readonly _supabase = createClient<Database>(this.context.env.SUPABASE_URL, this.context.env.SUPABASE_KEY);

async transform(data: Readonly<IssueActivity>, result: Result): Promise<Result> {
const canGeneratePermits = await this._canGeneratePermit(data);

if (!canGeneratePermits) {
this.context.logger.error("[PermitGenerationModule] Non collaborative issue detected, skipping.");
return Promise.resolve(result);
}
const payload: Context["payload"] & Payload = {
...context.payload.inputs,
issueUrl: this.context.payload.issue.html_url,
Expand Down Expand Up @@ -192,6 +199,14 @@ export class PermitGenerationModule extends BaseModule {
return this._deductFeeFromReward(result, treasuryGithubData);
}

async _canGeneratePermit(data: Readonly<IssueActivity>) {
if (!data.self?.closed_by || !data.self.user) return false;

if (await isAdmin(data.self.user.login, this.context)) return true;

return isCollaborative(data);
}

_deductFeeFromReward(
result: Result,
treasuryGithubData: RestEndpointMethodTypes["users"]["getByUsername"]["response"]["data"]
Expand Down
16 changes: 16 additions & 0 deletions tests/__mocks__/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ export const handlers = [
}
return HttpResponse.json(user);
}),
http.get("https://api.github.com/orgs/:org/memberships/:username", ({ params }) => {
const { username } = params;

if (username === "0x4007") {
return HttpResponse.json({
data: {
role: "admin"
}
});
}
return HttpResponse.json({
data: {
role: "member"
}
});
}),
http.post("https://api.github.com/app/installations/48381972/access_tokens", () => {
return HttpResponse.json({});
}),
Expand Down
Loading
Loading