GitHubでrepositoryごとに権限が割り当ててある人間を探す

abst

GitHubの権限を真面目に管理することを考えると、やはりrepositoryに対してUserを紐付けることをやめたい。 つまりRepositoryに対してTeamを紐づける権限管理をやりたい。

しかし、Repositoryを作ったUserがadminとして設定されてしまう仕様や過去に適当に割り当ててしまっていた経緯から、いまだにRepositoryに対して割り当てられているUserを探して削除する必要がある。

今回はGitHubのGraphQL APIを用いて上記のようなRepositoryを探す

実装手法

以下のようなQueryにした。ORG_NAMEを書き換えること

query FindRepo($node_id: String) {
  organization(login: "ORG_NAME") {
      repositories(first: 20, after: $node_id) {
          totalCount
          pageInfo {
              endCursor
              hasNextPage
          }
          nodes {
              id
              name
              nameWithOwner
              collaborators(affiliation: DIRECT) {
                  edges {
                      node {
                          login
                      }
                      permission
                      permissionSources {
                          source {
                              __typename
                              ... on Organization {
                                  login
                              }
                              ... on Repository {
                                  nameWithOwner
                              }
                              ... on Team {
                                  slug
                              }
                          }
                      }
                  }
              }
          }
      }
  }
}

依存関係として、jq,ghが必要

TMP_FILE="$PWD/tmp.json"
DEST="$PWD/repo_list"
QUERY="$PWD/repo.graphql"

set -ex

gh api graphql -f query="$(cat $QUERY)" > $TMP_FILE
jq -r '.data.organization.repositories.nodes[]|select(.collaborators.edges|length > 0)|.nameWithOwner' < $TMP_FILE > $DEST
cat $TMP_FILE
while [ "$(jq -r '.data.organization.repositories.pageInfo.hasNextPage' < $TMP_FILE )" == "true" ]; do
  sleep 1

  cursor=$(jq -r '.data.organization.repositories.pageInfo.endCursor' < $TMP_FILE )
  gh api graphql -F node_id="$cursor" -f query="$(cat $QUERY)" > $TMP_FILE
  jq -r '.data.organization.repositories.nodes[]|select(.collaborators.edges|length > 0)|.nameWithOwner' < $TMP_FILE >> $DEST
  cat  $TMP_FILE
done

解説

Repository の affiliation: DIRECT にするとRepositoryに対してUserが紐づいた人が出てくる.

All collaborators with permissions to an organization-owned subject, regardless of organization membership status.

らしい

bashで雑にloopを回していく。

権限を取り除く

API経由でできなくもなさそうだが手で取り除いた。

正直、このコードはひどいな、と思いつつ...

for i in $(cat $DEST);do echo $i; sleep 2;done|xargs -n 1 -I @ open https://github.com/@/settings/access

ブログなどのコードはメンテされないので別のとこで面倒を見るためのリンク

scrapbox.io