Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Specify closed PRs to run.ts #354

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 6 additions & 11 deletions src/queries/all-open-prs-query.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { gql, TypedDocumentNode } from "@apollo/client/core";
import { client } from "../graphql-client";
import { GetAllOpenPRsAndCardIDs, GetAllOpenPRsAndCardIDsVariables } from "./schema/GetAllOpenPRsAndCardIDs";
import { GetAllOpenPRs, GetAllOpenPRsVariables } from "./schema/GetAllOpenPRs";
import { noNullish } from "../util/util";

export const getAllOpenPRsAndCardIDsQuery: TypedDocumentNode<GetAllOpenPRsAndCardIDs, GetAllOpenPRsAndCardIDsVariables> = gql`
query GetAllOpenPRsAndCardIDs($endCursor: String) {
export const getAllOpenPRsQuery: TypedDocumentNode<GetAllOpenPRs, GetAllOpenPRsVariables> = gql`
query GetAllOpenPRs($endCursor: String) {
repository(owner: "DefinitelyTyped", name: "DefinitelyTyped") {
id
pullRequests(states: OPEN, orderBy: { field: UPDATED_AT, direction: DESC }, first: 100, after: $endCursor) {
nodes {
number
projectCards(first: 100) { nodes { id } }
}
pageInfo {
hasNextPage
Expand All @@ -20,22 +19,18 @@ query GetAllOpenPRsAndCardIDs($endCursor: String) {
}
}`;

export async function getAllOpenPRsAndCardIDs() {
export async function getAllOpenPRs() {
const prNumbers: number[] = [];
const cardIDs: string[] = [];
let endCursor: string | undefined | null;
while (true) {
const result = await client.query({
query: getAllOpenPRsAndCardIDsQuery,
query: getAllOpenPRsQuery,
fetchPolicy: "no-cache",
variables: { endCursor },
});
prNumbers.push(...noNullish(result.data.repository?.pullRequests.nodes).map(pr => pr.number));
for (const pr of noNullish(result.data.repository?.pullRequests.nodes)) {
cardIDs.push(...noNullish(pr.projectCards.nodes).map(card => card.id));
}
if (!result.data.repository?.pullRequests.pageInfo.hasNextPage) {
return { prNumbers, cardIDs };
return prNumbers;
}
endCursor = result.data.repository.pullRequests.pageInfo.endCursor;
}
Expand Down
38 changes: 15 additions & 23 deletions src/queries/projectboard-cards.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { gql, TypedDocumentNode } from "@apollo/client/core";
import { client } from "../graphql-client";
import { GetProjectBoardCards } from "./schema/GetProjectBoardCards";
import { noNullish } from "../util/util";

const GetProjectBoardCardsQuery: TypedDocumentNode<GetProjectBoardCards, never> = gql`
query GetProjectBoardCards {
Expand All @@ -17,6 +18,11 @@ const GetProjectBoardCardsQuery: TypedDocumentNode<GetProjectBoardCards, never>
nodes {
id
updatedAt
content {
... on PullRequest {
number
}
}
}
}
}
Expand All @@ -25,16 +31,6 @@ const GetProjectBoardCardsQuery: TypedDocumentNode<GetProjectBoardCards, never>
}
}`;

interface CardInfo {
id: string;
updatedAt: string;
}
interface ColumnInfo {
name: string;
totalCount: number;
cards: CardInfo[];
}

export async function getProjectBoardCards() {
const results = await client.query({
query: GetProjectBoardCardsQuery,
Expand All @@ -47,17 +43,13 @@ export async function getProjectBoardCards() {
throw new Error("No project found");
}

const columns: ColumnInfo[] = [];
project.columns.nodes?.forEach(col => {
if (!col) return;
const cards: CardInfo[] = [];
col.cards.nodes?.forEach(card => card && cards.push({ id: card.id, updatedAt: card.updatedAt }));
columns.push({
name: col.name,
totalCount: col.cards.totalCount,
cards,
});
});

return columns;
return noNullish(project.columns.nodes).map(column => ({
name: column.name,
totalCount: column.cards.totalCount,
cards: noNullish(column.cards.nodes).map(card => ({
id: card.id,
updatedAt: card.updatedAt,
number: card.content && "number" in card.content ? card.content.number : undefined,
})),
}));
}
60 changes: 60 additions & 0 deletions src/queries/schema/GetAllOpenPRs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.

// ====================================================
// GraphQL query operation: GetAllOpenPRs
// ====================================================

export interface GetAllOpenPRs_repository_pullRequests_nodes {
__typename: "PullRequest";
/**
* Identifies the pull request number.
*/
number: number;
}

export interface GetAllOpenPRs_repository_pullRequests_pageInfo {
__typename: "PageInfo";
/**
* When paginating forwards, are there more items?
*/
hasNextPage: boolean;
/**
* When paginating forwards, the cursor to continue.
*/
endCursor: string | null;
}

export interface GetAllOpenPRs_repository_pullRequests {
__typename: "PullRequestConnection";
/**
* A list of nodes.
*/
nodes: (GetAllOpenPRs_repository_pullRequests_nodes | null)[] | null;
/**
* Information to aid in pagination.
*/
pageInfo: GetAllOpenPRs_repository_pullRequests_pageInfo;
}

export interface GetAllOpenPRs_repository {
__typename: "Repository";
id: string;
/**
* A list of pull requests that have been opened in the repository.
*/
pullRequests: GetAllOpenPRs_repository_pullRequests;
}

export interface GetAllOpenPRs {
/**
* Lookup a given repository by the owner and repository name.
*/
repository: GetAllOpenPRs_repository | null;
}

export interface GetAllOpenPRsVariables {
endCursor?: string | null;
}
77 changes: 0 additions & 77 deletions src/queries/schema/GetAllOpenPRsAndCardIDs.ts

This file was deleted.

18 changes: 18 additions & 0 deletions src/queries/schema/GetProjectBoardCards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,31 @@
// GraphQL query operation: GetProjectBoardCards
// ====================================================

export interface GetProjectBoardCards_repository_project_columns_nodes_cards_nodes_content_Issue {
__typename: "Issue";
}

export interface GetProjectBoardCards_repository_project_columns_nodes_cards_nodes_content_PullRequest {
__typename: "PullRequest";
/**
* Identifies the pull request number.
*/
number: number;
}

export type GetProjectBoardCards_repository_project_columns_nodes_cards_nodes_content = GetProjectBoardCards_repository_project_columns_nodes_cards_nodes_content_Issue | GetProjectBoardCards_repository_project_columns_nodes_cards_nodes_content_PullRequest;

export interface GetProjectBoardCards_repository_project_columns_nodes_cards_nodes {
__typename: "ProjectCard";
id: string;
/**
* Identifies the date and time when the object was last updated.
*/
updatedAt: any;
/**
* The card content item
*/
content: GetProjectBoardCards_repository_project_columns_nodes_cards_nodes_content | null;
}

export interface GetProjectBoardCards_repository_project_columns_nodes_cards {
Expand Down
23 changes: 10 additions & 13 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import * as schema from "@octokit/graphql-schema/schema";
import * as yargs from "yargs";
import { process as computeActions } from "./compute-pr-actions";
import { getAllOpenPRsAndCardIDs } from "./queries/all-open-prs-query";
import { getAllOpenPRs } from "./queries/all-open-prs-query";
import { queryPRInfo, deriveStateForPR } from "./pr-info";
import { executePrActions } from "./execute-pr-actions";
import { getProjectBoardCards } from "./queries/projectboard-cards";
import { runQueryToGetPRForCardId } from "./queries/card-id-to-pr-query";
import { createMutation, client } from "./graphql-client";
import { flatten } from "./util/util";
import { render } from "prettyjson";
import { inspect } from "util";

Expand All @@ -26,21 +27,18 @@ const args = yargs(process.argv.slice(2))
"show-actions": { alias: ["s4"], type: "boolean", desc: "display actions" },
"show-mutations": { alias: ["s5"], type: "boolean", desc: "display mutations" },
})
.coerce("_", (prs: (number|string)[]) => prs.map(pr => {
if (typeof pr === "number") return (n: number) => n === pr;
if (pr.match(/^\d+$/)) return (n: number) => n === +pr;
.coerce("_", (prs: (number|string)[]) => flatten(prs.map(pr => {
if (typeof pr === "number") return pr;
if (pr.match(/^\d+$/)) return +pr;
const m = pr.match(/^(\d+)-(\d+)$/);
if (!m) throw new Error(`bad PR or PR range argument: "${pr}"`);
const lo = +m[1]!, hi = +m[2]!;
return (n: number) => lo <= n && n <= hi;
}))
return new Array(hi - lo + 1).map((empty, i) => lo + i);
})))
.help("h").alias("h", "help")
.strict()
.argv;

const shouldRunOn: (n: number) => boolean =
args._.length === 0 ? _n => true : n => args._.some(p => p(n));

const xform = (x: unknown, xlate: (s: string) => string): unknown => {
if (typeof x === "string") return xlate(x);
if (typeof x !== "object" || x === null) return x;
Expand All @@ -62,10 +60,9 @@ const show = (name: string, value: unknown) => {

const start = async function () {
console.log(`Getting open PRs.`);
const { prNumbers: prs, cardIDs } = await getAllOpenPRsAndCardIDs();
const prs = args._.length ? args._ : await getAllOpenPRs();
//
for (const pr of prs) {
if (!shouldRunOn(pr)) continue;
console.log(`Processing #${pr} (${prs.indexOf(pr) + 1} of ${prs.length})...`);
// Generate the info for the PR from scratch
const info = await queryPRInfo(pr);
Expand All @@ -90,7 +87,7 @@ const start = async function () {
const mutations = await executePrActions(actions, prInfo, args.dry);
if (args["show-mutations"] ?? args.dry) show("Mutations", mutations);
}
if (args.dry || !args.cleanup) return;
if (args.dry || !args.cleanup || args._.length) return;
//
console.log("Cleaning up cards");
const columns = await getProjectBoardCards();
Expand Down Expand Up @@ -122,7 +119,7 @@ const start = async function () {
// Handle other columns
for (const column of columns) {
if (column.name === "Recently Merged") continue;
const ids = column.cards.map(c => c.id).filter(c => !cardIDs.includes(c));
const ids = column.cards.filter(c => c.number && !prs.includes(c.number)).map(c => c.id);
if (ids.length === 0) continue;
console.log(`Cleaning up closed PRs in "${column.name}"`);
// don't actually do the deletions, until I follow this and make sure that it's working fine
Expand Down
5 changes: 3 additions & 2 deletions src/util/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ export function noNullish<T>(arr: ReadonlyArray<T | null | undefined> | null | u
return arr.filter(arr => arr != null) as T[];
}

export function flatten<T extends any[]>(xs: T[]) {
return ([] as unknown as T).concat(...xs) as T;
export function flatten<T>(xs: T[]) {
type U = T extends (infer U)[] ? U : T;
return ([] as U[]).concat(...xs as U[]);
Comment on lines +8 to +10
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Types for when arguments aren't arrays, e.g. flatten([["a"], "b"]) -> ["a", "b"]

}

export function unique<T>(xs: T[]) {
Expand Down