Skip to content

Instantly share code, notes, and snippets.

@mryhryki
Last active March 26, 2022 08:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mryhryki/47d83f9ecd8e75a4f034aab8d649d1b2 to your computer and use it in GitHub Desktop.
Save mryhryki/47d83f9ecd8e75a4f034aab8d649d1b2 to your computer and use it in GitHub Desktop.
特定のユーザーがアサインされてクローズされた Issue を取得するスクリプト for Deno
#!/usr/bin/env -S deno run --allow-env --allow-net
/**
* # 特定のユーザーがアサインされてクローズされた Issue を取得するスクリプト for Deno
*
* ## Deno のインストール方法はこちら (macOS / Linux)
*
* ```shell
* # https://deno.land/manual/getting_started/installation
* curl -fsSL https://deno.land/x/install/install.sh | sh
* ```
*
* ## 使い方
*
* 1. アクセストークンを環境変数 `GITHUB_ACCESS_TOKEN` にセットする
* 2. 以下のコマンドを実行する
*
* ```shell
* $ chmod +x ./index.js
* $ ./index.js
*
* # または
*
* $ deno run --allow-env --allow-net index.js
* ```
*
* @author mryhryki
* @license MIT
*/
/**
* 検索したいユーザーの GitHub ID
*/
const GitHubLogin = "mryhryki"
/**
* Issue をフィルタリングする関数
*
* @param {string} url Issue の URL
* @param {string} title タイトル
* @param {string} closedAt クローズした日時 (e.g. "2021-04-23T08:46:37Z")
* @param {string} repository リポジトリ名 (e.g. "Connehito/mamari-spec")
* @param {string[]} labels ラベルの配列 (e.g. ["label1", "label2"]
* @return {boolean} フィルタ結果 (true: 残す, false: 除く)
*/
const filterIssue = ({ url, title, closedAt, repository, labels }) => {
// Connehito 以外のリポジトリの Issue は除く
if (!repository.startsWith("Connehito/")) {
return false;
}
// 2021-04-01 以前にクローズされた Issue は除く
const closedDate = closedAt.substr(0, 10);
if (closedDate < "2021-04-01") {
return false;
}
// "Yellowチーム" ラベルが付いていない Issue は除く
if (!labels.includes("Yellowチーム")) {
return false;
}
return true;
}
const GitHubURL = "https://api.github.com/graphql";
const GitHubAccessToken = Deno.env.get("GITHUB_ACCESS_TOKEN");
const fetchGitHubGraphQL = async (query) => {
const response = await fetch(GitHubURL, {
method: "POST",
headers: {
Authorization: `token ${GitHubAccessToken}`
},
body: JSON.stringify({ query })
});
if (response.status !== 200) {
throw new Error(`Invalid status code: ${response.status}`);
}
return response.json();
};
// https://docs.github.com/en/free-pro-team@latest/graphql/overview/explorer で試せる
const getQuery = (nextToken) => {
const after = nextToken == null ? "null" : `"${nextToken}"`;
return `
{
user(login: "${GitHubLogin}") {
issues(
first: 100,
states: [CLOSED],
filterBy: { assignee: "${GitHubLogin}" },
orderBy: { field: UPDATED_AT, direction: DESC },
after: ${after}
) {
nodes {
url
title
closedAt
labels(first: 10) {
nodes {
name
}
}
repository {
owner {
login
}
name
}
}
pageInfo {
endCursor
}
}
}
}
`;
};
const issues = [];
let nextToken = null;
do {
const query = getQuery(nextToken);
const json = await fetchGitHubGraphQL(query);
const { nodes, pageInfo } = json.data.user.issues;
// ページングを有効にする場合は、下の行を有効にする
// nextToken = pageInfo.endCursor;
nodes
.map((issue) => ({
...issue,
repository: `${issue.repository.owner.login}/${issue.repository.name}`, // "(OWNER)/(REPO)" 形式にする
labels: issue.labels.nodes.map(({ name }) => name), // ラベル名の配列にする
}))
.filter(filterIssue)
.forEach((issue) => issues.push(issue));
} while (nextToken != null);
issues.sort((i1, i2) => {
return i1.closedAt < i2.closedAt ? -1 : 1;
});
issues.forEach(({ url, title, closedAt, repository, labels }) => {
console.log(`${closedAt}\t${title}\t[${labels.join(", ")}]\t${url}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment