-
-
Save mryhryki/47d83f9ecd8e75a4f034aab8d649d1b2 to your computer and use it in GitHub Desktop.
特定のユーザーがアサインされてクローズされた Issue を取得するスクリプト for Deno
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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