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

Implement handling RFCs #1212

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3cae67f
Update github.ts
xno-miner Jun 17, 2024
60498ef
Update index.ts
xno-miner Jun 17, 2024
c22b1c8
Minor fix
xno-miner Jun 17, 2024
f0e9c3d
Update helpers/github.ts
xno-miner Jun 17, 2024
9258750
Update devpool-issue-handler.test.ts
xno-miner Jun 17, 2024
a6c3c1e
Update devpool-issue-handler.test.ts
xno-miner Jun 17, 2024
d96e69e
Update index.ts
xno-miner Jun 17, 2024
22ebb9c
Update github.ts
xno-miner Jun 17, 2024
fe8c4c6
Minor fix
xno-miner Jun 17, 2024
80ce59b
Minor clean
xno-miner Jun 17, 2024
20d74be
Fix getting repo name
xno-miner Jun 17, 2024
b77c0c0
Moved DEVPOOL_OWNER_NAME, DEVPOOL_REPO_NAME, DEVPOOL_RFC_OWNER_NAME a…
xno-miner Jun 28, 2024
4f3c962
Moved the DEVPOOL_ variables to .env (copy the values from .env.example)
xno-miner Jun 28, 2024
128c5d8
don't tweet rfcs
xno-miner Jun 28, 2024
212502f
don't tweet rfcs
xno-miner Jun 28, 2024
ea31d8a
Moved the DEVPOOL_ variables back from env
xno-miner Jun 29, 2024
a08862c
Improved code readability
xno-miner Jun 29, 2024
4cafbe3
Minor fix
xno-miner Jun 29, 2024
179586e
Further improved readability
xno-miner Jun 29, 2024
5263f17
Minor fix
xno-miner Jun 29, 2024
1a65d43
Create env variables for devpool/RFC
xno-miner Jul 2, 2024
133d263
Merge branch 'development' into development
xno-miner Jul 25, 2024
66f7d63
Create tests for RFCs
xno-miner Jul 26, 2024
7a583ab
Add missing files
xno-miner Jul 26, 2024
ed3bbf0
JSON.parse RFC env
xno-miner Jul 29, 2024
ea374eb
quotes in ymls
xno-miner Aug 1, 2024
5a7f812
Fix env and enable rfc test
xno-miner Aug 1, 2024
6318d84
minor cleanup
xno-miner Aug 1, 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
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ TWITTER_API_KEY=
TWITTER_API_KEY_SECRET=
TWITTER_ACCESS_TOKEN=
TWITTER_ACCESS_TOKEN_SECRET=

DEVPOOL_OWNER_NAME=ubiquity
DEVPOOL_REPO_NAME=devpool-directory
RFC=0
3 changes: 3 additions & 0 deletions .github/workflows/sync-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ jobs:
TWITTER_API_KEY_SECRET: ${{ secrets.TWITTER_API_KEY_SECRET }}
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
DEVPOOL_OWNER_NAME: ubiquity
DEVPOOL_REPO_NAME: devpool-directory
RFC: 0
run: npx tsx index.ts

- uses: actions/upload-artifact@v4
Expand Down
80 changes: 45 additions & 35 deletions helpers/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export const projects = _projects as {
category?: Record<string, string>;
};

export const DEVPOOL_OWNER_NAME = "ubiquity";
export const DEVPOOL_REPO_NAME = "devpool-directory";
export enum LABELS {
PRICE = "Price",
UNAVAILABLE = "Unavailable",
Expand Down Expand Up @@ -285,8 +283,8 @@ export async function calculateStatistics(issues: GitHubIssue[]) {

issues.forEach((issue) => {
if (!issue.repository_url || !issue.html_url) return;
if (!issue.repository_url.includes(DEVPOOL_REPO_NAME) || !issue.html_url.includes(DEVPOOL_REPO_NAME)) return;
if ("repo" in issue && issue.repo != DEVPOOL_REPO_NAME) return;
if (!issue.repository_url.includes(process.env.DEVPOOL_REPO_NAME) || !issue.html_url.includes(process.env.DEVPOOL_REPO_NAME)) return;
if ("repo" in issue && issue.repo != process.env.DEVPOOL_REPO_NAME) return;

const labels = issue.labels as GitHubLabel[];
// devpool issue has unavailable label because it's assigned and so it's closed
Expand Down Expand Up @@ -337,8 +335,8 @@ export async function calculateStatistics(issues: GitHubIssue[]) {

export async function writeTotalRewardsToGithub(statistics: Statistics) {
try {
const owner = DEVPOOL_OWNER_NAME;
const repo = DEVPOOL_REPO_NAME;
const owner = process.env.DEVPOOL_OWNER_NAME;
const repo = process.env.DEVPOOL_REPO_NAME;
const filePath = "total-rewards.json";
const content = JSON.stringify(statistics, null, 2);

Expand Down Expand Up @@ -389,14 +387,16 @@ export async function createDevPoolIssue(projectIssue: GitHubIssue, projectUrl:
// if the project issue is assigned to someone, then skip it
if (projectIssue.assignee) return;

// if issue doesn't have the "Price" label then skip it, no need to pollute repo with draft issues
if (!(projectIssue.labels as GitHubLabel[]).some((label) => label.name.includes(LABELS.PRICE))) return;
// check if the issue is the same type as it should be
const hasPriceLabel = (projectIssue.labels as GitHubLabel[]).some((label) => label.name.includes(LABELS.PRICE));
const hasCorrectPriceLabel = (process.env.RFC && !hasPriceLabel) || (!process.env.RFC && hasPriceLabel)
if (!hasCorrectPriceLabel) return;

// create a new issue
try {
const createdIssue = await octokit.rest.issues.create({
owner: DEVPOOL_OWNER_NAME,
repo: DEVPOOL_REPO_NAME,
owner: process.env.DEVPOOL_OWNER_NAME,
repo: process.env.DEVPOOL_REPO_NAME,
title: projectIssue.title,
body,
labels: getDevpoolIssueLabels(projectIssue, projectUrl),
Expand All @@ -408,15 +408,17 @@ export async function createDevPoolIssue(projectIssue: GitHubIssue, projectUrl:
return;
}

// post to social media
try {
const socialMediaText = getSocialMediaText(createdIssue.data);
const tweetId = await twitter.postTweet(socialMediaText);

twitterMap[createdIssue.data.node_id] = tweetId?.id ?? "";
await writeFile("./twitterMap.json", JSON.stringify(twitterMap));
} catch (err) {
console.error("Failed to post tweet: ", err);
// post to social media (only if it's not an RFC)
if (!process.env.RFC) {
try {
const socialMediaText = getSocialMediaText(createdIssue.data);
const tweetId = await twitter.postTweet(socialMediaText);

twitterMap[createdIssue.data.node_id] = tweetId?.id ?? "";
await writeFile("./twitterMap.json", JSON.stringify(twitterMap));
} catch (err) {
console.error("Failed to post tweet: ", err);
}
}
} catch (err) {
console.error("Failed to create new issue: ", err);
Expand All @@ -435,7 +437,7 @@ export async function handleDevPoolIssue(
const labelRemoved = getDevpoolIssueLabels(projectIssue, projectUrl).filter((label) => label != LABELS.UNAVAILABLE);
const originals = devpoolIssue.labels.map((label) => (label as GitHubLabel).name);
const hasChanges = !areEqual(originals, labelRemoved);
const hasNoPriceLabels = !(projectIssue.labels as GitHubLabel[]).some((label) => label.name.includes(LABELS.PRICE));
const hasPriceLabel = (projectIssue.labels as GitHubLabel[]).some((label) => label.name.includes(LABELS.PRICE));

const metaChanges = {
// the title of the issue has changed
Expand All @@ -448,7 +450,7 @@ export async function handleDevPoolIssue(

await applyMetaChanges(metaChanges, devpoolIssue, projectIssue, isFork, labelRemoved, originals);

const newState = await applyStateChanges(projectIssues, projectIssue, devpoolIssue, hasNoPriceLabels);
const newState = await applyStateChanges(projectIssues, projectIssue, devpoolIssue, hasPriceLabel);

await applyUnavailableLabelToDevpoolIssue(
projectIssue,
Expand All @@ -473,8 +475,8 @@ async function applyMetaChanges(
if (shouldUpdate) {
try {
await octokit.rest.issues.update({
owner: DEVPOOL_OWNER_NAME,
repo: DEVPOOL_REPO_NAME,
owner: process.env.DEVPOOL_OWNER_NAME,
repo: process.env.DEVPOOL_REPO_NAME,
issue_number: devpoolIssue.number,
title: metaChanges.title ? projectIssue.title : devpoolIssue.title,
body: metaChanges.body && !isFork ? projectIssue.html_url : projectIssue.html_url.replace("https://", "https://www."),
Expand All @@ -490,7 +492,9 @@ async function applyMetaChanges(
}
}

async function applyStateChanges(projectIssues: GitHubIssue[], projectIssue: GitHubIssue, devpoolIssue: GitHubIssue, hasNoPriceLabels: boolean) {
async function applyStateChanges(projectIssues: GitHubIssue[], projectIssue: GitHubIssue, devpoolIssue: GitHubIssue, hasPriceLabel: boolean) {
const hasCorrectPriceLabel = (process.env.RFC && !hasPriceLabel) || (!process.env.RFC && hasPriceLabel)

const stateChanges: StateChanges = {
// missing in the partners
forceMissing_Close: {
Expand All @@ -500,10 +504,16 @@ async function applyStateChanges(projectIssues: GitHubIssue[], projectIssue: Git
},
// no price labels set and open in the devpool
noPriceLabels_Close: {
cause: hasNoPriceLabels && devpoolIssue.state === "open",
cause: (!process.env.RFC) && (!hasCorrectPriceLabel) && devpoolIssue.state === "open",
effect: "closed",
comment: "Closed (no price labels)",
},
// HAS price labels set and open in the RFC devpool
rfcPriceLabels_Close: {
cause: process.env.RFC && (!hasCorrectPriceLabel) && devpoolIssue.state === "open",
effect: "closed",
comment: "Closed (has price labels)",
},
// it's closed, been merged and still open in the devpool
issueComplete_Close: {
cause: projectIssue.state === "closed" && devpoolIssue.state === "open" && !!projectIssue.pull_request?.merged_at,
Expand All @@ -528,20 +538,20 @@ async function applyStateChanges(projectIssues: GitHubIssue[], projectIssue: Git
effect: "closed",
comment: "Closed (assigned-open)",
},
// it's open, merged, unassigned, has price labels and is closed in the devpool
// it's open, merged, unassigned, has CORRECT price labels and is closed in the devpool
issueReopenedMerged_Open: {
cause:
projectIssue.state === "open" &&
devpoolIssue.state === "closed" &&
!!projectIssue.pull_request?.merged_at &&
!hasNoPriceLabels &&
hasCorrectPriceLabel &&
!projectIssue.assignee?.login,
effect: "open",
comment: "Reopened (merged)",
},
// it's open, unassigned, has price labels and is closed in the devpool
// it's open, unassigned, has CORRECT price labels and is closed in the devpool
issueUnassigned_Open: {
cause: projectIssue.state === "open" && devpoolIssue.state === "closed" && !projectIssue.assignee?.login && !hasNoPriceLabels,
cause: projectIssue.state === "open" && devpoolIssue.state === "closed" && !projectIssue.assignee?.login && hasCorrectPriceLabel,
effect: "open",
comment: "Reopened (unassigned)",
},
Expand All @@ -559,8 +569,8 @@ async function applyStateChanges(projectIssues: GitHubIssue[], projectIssue: Git

try {
await octokit.rest.issues.update({
owner: DEVPOOL_OWNER_NAME,
repo: DEVPOOL_REPO_NAME,
owner: process.env.DEVPOOL_OWNER_NAME,
repo: process.env.DEVPOOL_REPO_NAME,
issue_number: devpoolIssue.number,
state: value.effect,
});
Expand Down Expand Up @@ -596,8 +606,8 @@ async function applyUnavailableLabelToDevpoolIssue(
) {
try {
await octokit.rest.issues.addLabels({
owner: DEVPOOL_OWNER_NAME,
repo: DEVPOOL_REPO_NAME,
owner: process.env.DEVPOOL_OWNER_NAME,
repo: process.env.DEVPOOL_REPO_NAME,
issue_number: devpoolIssue.number,
labels: metaChanges.labels ? labelRemoved.concat(LABELS.UNAVAILABLE) : originals.concat(LABELS.UNAVAILABLE),
});
Expand All @@ -607,8 +617,8 @@ async function applyUnavailableLabelToDevpoolIssue(
} else if (projectIssue.state === "closed" && devpoolIssue.labels.some((label) => (label as GitHubLabel).name === LABELS.UNAVAILABLE)) {
try {
await octokit.rest.issues.removeLabel({
owner: DEVPOOL_OWNER_NAME,
repo: DEVPOOL_REPO_NAME,
owner: process.env.DEVPOOL_OWNER_NAME,
repo: process.env.DEVPOOL_REPO_NAME,
issue_number: devpoolIssue.number,
name: LABELS.UNAVAILABLE,
});
Expand Down
14 changes: 7 additions & 7 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import dotenv from "dotenv";
import {
DEVPOOL_OWNER_NAME,
DEVPOOL_REPO_NAME,
getAllIssues,
getIssueByLabel,
getProjectUrls,
Expand Down Expand Up @@ -35,21 +33,23 @@ async function main() {
}

// get devpool issues
const devpoolIssues: GitHubIssue[] = await getAllIssues(DEVPOOL_OWNER_NAME, DEVPOOL_REPO_NAME);
const devpoolIssues: GitHubIssue[] = (await getAllIssues(process.env.DEVPOOL_OWNER_NAME, process.env.DEVPOOL_REPO_NAME))

// Calculate total rewards from open issues
const { rewards, tasks } = await calculateStatistics(devpoolIssues);
const statistics: Statistics = { rewards, tasks };
if (!process.env.RFC) {
const { rewards, tasks } = await calculateStatistics(devpoolIssues);
const statistics: Statistics = { rewards, tasks };

await writeTotalRewardsToGithub(statistics);
await writeTotalRewardsToGithub(statistics);
}

// aggregate projects.urls and opt settings
const projectUrls = await getProjectUrls();

// aggregate all project issues
const allProjectIssues: GitHubIssue[] = [];

const isFork = await checkIfForked(DEVPOOL_OWNER_NAME);
const isFork = await checkIfForked(process.env.DEVPOOL_OWNER_NAME);

// for each project URL
for (const projectUrl of projectUrls) {
Expand Down