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

Open
wants to merge 14 commits into
base: development
Choose a base branch
from
8 changes: 7 additions & 1 deletion src/parser/github-comment-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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";

interface SortedTasks {
issues: { specification: GithubCommentScore | null; comments: GithubCommentScore[] };
Expand Down Expand Up @@ -110,7 +111,12 @@ export class GithubCommentModule extends BaseModule {
}
if (this._configuration?.post) {
try {
await this.postComment(body);
if (Object.values(result).some((v) => v.permitUrl)) {
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
36 changes: 36 additions & 0 deletions src/parser/permit-generation-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ 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,
this.context.payload.repository.owner.login,
this.context.payload.repository.name
);

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 +202,32 @@ export class PermitGenerationModule extends BaseModule {
return this._deductFeeFromReward(result, treasuryGithubData);
}

async _canGeneratePermit(data: Readonly<IssueActivity>, repoOwner: string, repoName: string) {
if (!data.self?.closed_by || !data.self.assignee) return false;

const octokit = this.context.octokit as unknown as Context["octokit"];
const assignee = data.self?.assignee;

const assigneePerms = await octokit.rest.repos.getCollaboratorPermissionLevel({
owner: repoOwner,
repo: repoName,
username: assignee.login,
});
const isAdmin = assigneePerms.data.role_name === "admin" || assigneePerms.data.role_name === "billing_manager";

if (data.self.closed_by.id === assignee.id && !isAdmin) {
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 !== assignee.id
);
return !!pricingEventsByNonAssignee;
} else {
return true;
}
}
_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/repos/:owner/:repo/collaborators/:username/permission", ({ params }) => {
const { username } = params;

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