From 606c439d146db9102811e103b1d42583cf8d58ff Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Thu, 26 Feb 2026 16:43:33 -0600 Subject: [PATCH] feat: add script to retrieve repositories created from a specific template using GraphQL --- gh-cli/README.md | 11 +++ .../get-repositories-created-from-template.sh | 70 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100755 gh-cli/get-repositories-created-from-template.sh diff --git a/gh-cli/README.md b/gh-cli/README.md index ac71ef6..83e0476 100644 --- a/gh-cli/README.md +++ b/gh-cli/README.md @@ -1234,6 +1234,17 @@ Generates a CSV with 4 columns: - url template - The autolink url template - autonumeric - If the autolink is autonumeric or not (true/false) +### get-repositories-created-from-template.sh + +Gets all repositories in an organization or user account that were created from a specific repository template using GraphQL. Tries the organization endpoint first, then falls back to the user endpoint. + +```shell +./get-repositories-created-from-template.sh joshjohanning-org joshjohanning/nodejs-actions-starter-template +``` + +> [!NOTE] +> The `templateRepository` field is only populated if the template repository still exists and is accessible + ### get-repositories-not-using-actions.sh Get repositories not using actions, by files committed in the `.github/workflows` directory diff --git a/gh-cli/get-repositories-created-from-template.sh b/gh-cli/get-repositories-created-from-template.sh new file mode 100755 index 0000000..b47eabf --- /dev/null +++ b/gh-cli/get-repositories-created-from-template.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Gets all repositories in an organization or user account that were created from a specific +# repository template +# +# Note: Uses the GraphQL API to query all repositories in a single paginated call. Tries the +# organization endpoint first, then falls back to the user endpoint. The templateRepository +# field is only populated if the template repository still exists and is accessible. +# +# Usage: +# ./get-repositories-created-from-template.sh [hostname] +# +# Example: +# ./get-repositories-created-from-template.sh joshjohanning-org joshjohanning/nodejs-actions-starter-template +# ./get-repositories-created-from-template.sh joshjohanning joshjohanning/nodejs-actions-starter-template +# ./get-repositories-created-from-template.sh joshjohanning-org joshjohanning/nodejs-actions-starter-template ghes.example.com + +if [ -z "$2" ]; then + echo "Usage: $0 [hostname]" + echo "Example: $0 joshjohanning-org joshjohanning/nodejs-actions-starter-template" + exit 1 +fi + +org="$1" +template_repo="$2" +hostname="${3:-github.com}" + +echo "Finding repositories in '$org' created from template '$template_repo'..." +echo "" + +# try organization first, fall back to user +results=$(gh api graphql --hostname "$hostname" --paginate -F owner="$org" -f query=' +query ($owner: String!, $endCursor: String) { + organization(login: $owner) { + repositories(first: 100, after: $endCursor) { + nodes { + nameWithOwner + templateRepository { + nameWithOwner + } + } + pageInfo { + endCursor + hasNextPage + } + } + } +}' --jq "[.data.organization.repositories.nodes[] | select(.templateRepository.nameWithOwner == \"$template_repo\") | .nameWithOwner] | .[]" 2>/dev/null) + +if [ $? -ne 0 ] || [ -z "$results" ]; then + results=$(gh api graphql --hostname "$hostname" --paginate -F owner="$org" -f query=' +query ($owner: String!, $endCursor: String) { + user(login: $owner) { + repositories(first: 100, after: $endCursor, ownerAffiliations: OWNER) { + nodes { + nameWithOwner + templateRepository { + nameWithOwner + } + } + pageInfo { + endCursor + hasNextPage + } + } + } +}' --jq "[.data.user.repositories.nodes[] | select(.templateRepository.nameWithOwner == \"$template_repo\") | .nameWithOwner] | .[]") +fi + +echo "$results"