Last active
June 10, 2026 06:30
-
-
Save xbalaji/8c8e9cfe1b8f1af12bda082234a1193e to your computer and use it in GitHub Desktop.
create_github_repo.sh
This file contains hidden or 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
| #!/bin/bash | |
| # ============================ | |
| # Script: create_github_repo.sh | |
| # Purpose: Create a GitHub repo under an org by mirroring all branches | |
| # from a template repo, clone via SSH, update README, | |
| # push changes, assign team permissions, and list collaborators. | |
| # ============================ | |
| # Defaults | |
| ORG="xlabsinc" | |
| VISIBILITY="private" | |
| TEAM_TO_ADD="xbalaji-accounts" # default team slug | |
| TEAM_PERMISSION="admin" # default permission for team | |
| # --------------------------- | |
| # Functions | |
| # --------------------------- | |
| usage() { | |
| cat <<EOF | |
| Usage: $0 -r <reponame> [-o <orgname>] [-v <visibility>] [-t <team_slug>] [-p <team_permission>] [-h] | |
| Options: | |
| -r, --repo Repository name (required) | |
| -o, --org GitHub organization (optional, default: $ORG) | |
| -v, --visibility private or public (optional, default: private) | |
| -t, --team GitHub team slug to grant permission (optional, default: $TEAM_TO_ADD) | |
| -p, --permission Team permission: pull, push, admin, maintain, triage (optional, default: $TEAM_PERMISSION) | |
| -h, --help Display this help message | |
| Examples: | |
| $0 -r myrepo | |
| $0 -r myrepo -v public | |
| $0 -r myrepo -o myorg -t dev-team -p maintain | |
| EOF | |
| exit 1 | |
| } | |
| check_command() { | |
| command -v "$1" >/dev/null 2>&1 | |
| if [[ $? -eq 0 ]]; then | |
| echo "Command '$1' is available." | |
| else | |
| echo "Error: '$1' is not installed. Please install it first." | |
| exit 1 | |
| fi | |
| } | |
| # --------------------------- | |
| # Parse arguments | |
| # --------------------------- | |
| ARGS=$(getopt -o r:o:v:t:p:h --long repo:,org:,visibility:,team:,permission:,help -n "$0" -- "$@") | |
| if [[ $? -ne 0 ]]; then usage; fi | |
| eval set -- "$ARGS" | |
| while true; do | |
| case "$1" in | |
| -r|--repo) REPO="$2"; shift 2 ;; | |
| -o|--org) ORG="$2"; shift 2 ;; | |
| -v|--visibility) VISIBILITY="$2"; shift 2 ;; | |
| -t|--team) TEAM_TO_ADD="$2"; shift 2 ;; | |
| -p|--permission) TEAM_PERMISSION="$2"; shift 2 ;; | |
| -h|--help) usage ;; | |
| --) shift; break ;; | |
| *) echo "Invalid option: $1"; usage ;; | |
| esac | |
| done | |
| # Validate required arguments | |
| if [[ -z "$REPO" ]]; then | |
| echo "Error: Repository name is required." | |
| usage | |
| fi | |
| if [[ "$VISIBILITY" != "private" && "$VISIBILITY" != "public" ]]; then | |
| echo "Error: visibility must be 'private' or 'public'" | |
| usage | |
| fi | |
| # --------------------------- | |
| # Check prerequisites | |
| # --------------------------- | |
| check_command git | |
| check_command gh | |
| # --------------------------- | |
| # Check GitHub CLI login | |
| # --------------------------- | |
| echo "Checking GitHub CLI login..." | |
| if ! gh auth status >/dev/null 2>&1; then | |
| TOKEN_FILE="$PWD/token.txt" | |
| if [[ -f "$TOKEN_FILE" ]]; then | |
| echo "Logging in using token file at $TOKEN_FILE..." | |
| echo "Command: gh auth login --with-token <<<\$(head -1 $TOKEN_FILE)" | |
| gh auth login --with-token <<<"$(head -1 "$TOKEN_FILE")" | |
| else | |
| echo "Error: Not logged in to GitHub CLI and token file not found at $TOKEN_FILE" | |
| echo "Example: gh auth login --with-token <<<\$(head -1 $PWD/token.txt)" | |
| exit 1 | |
| fi | |
| else | |
| CURRENT_USER=$(gh api user --jq '.login' 2>/dev/null) | |
| if [[ -n "$CURRENT_USER" ]]; then | |
| echo "Logged in as $CURRENT_USER" | |
| else | |
| echo "Error: Unable to determine logged in user." | |
| exit 1 | |
| fi | |
| fi | |
| # --------------------------- | |
| # Template repo | |
| # --------------------------- | |
| TEMPLATE_SSH="git@github-${ORG}:${ORG}/template.git" | |
| echo "Template repository SSH URL: $TEMPLATE_SSH" | |
| # --------------------------- | |
| # Create the new repository | |
| # --------------------------- | |
| echo "Creating repository '$REPO' under org '$ORG' with visibility '$VISIBILITY'..." | |
| echo "Command: gh repo create $ORG/$REPO --$VISIBILITY" | |
| gh repo create "$ORG/$REPO" --"$VISIBILITY" | |
| # --------------------------- | |
| # New repository SSH URL | |
| # --------------------------- | |
| NEW_REPO_SSH="git@github-${ORG}:${ORG}/${REPO}.git" | |
| # --------------------------- | |
| # Mirror clone + push | |
| # --------------------------- | |
| TMP_DIR=$(mktemp -d) | |
| echo "Mirroring all branches and tags from template..." | |
| echo "Command: git clone --mirror $TEMPLATE_SSH $TMP_DIR" | |
| git clone --mirror "$TEMPLATE_SSH" "$TMP_DIR" | |
| cd "$TMP_DIR" || exit | |
| echo "Command: git push --mirror $NEW_REPO_SSH" | |
| git push --mirror "$NEW_REPO_SSH" | |
| cd .. | |
| rm -rf "$TMP_DIR" | |
| # --------------------------- | |
| # Clone the new repo for updates | |
| # --------------------------- | |
| echo "Cloning the new repository locally for updates: $NEW_REPO_SSH" | |
| git clone "$NEW_REPO_SSH" | |
| cd "$REPO" || exit | |
| # --------------------------- | |
| # Checkout default branch | |
| # --------------------------- | |
| git fetch origin | |
| DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch" | awk '{print $NF}') | |
| echo "Default branch: $DEFAULT_BRANCH" | |
| git checkout "$DEFAULT_BRANCH" || git checkout -b main | |
| # --------------------------- | |
| # Update README.md | |
| # --------------------------- | |
| echo -e "\nThis README was updated automatically via create_github_repo.sh script." >> README.md | |
| echo "Command: git add README.md && git commit -m 'Update README.md via script'" | |
| git add README.md | |
| git commit -m "Update README.md via script" | |
| echo "Pushing changes to $DEFAULT_BRANCH..." | |
| git push --set-upstream origin "$DEFAULT_BRANCH" | |
| # --------------------------- | |
| # Optional: Grant a team permission | |
| # --------------------------- | |
| if [[ -n "$TEAM_TO_ADD" ]]; then | |
| echo "Adding team '$TEAM_TO_ADD' with permission '$TEAM_PERMISSION' to repo $ORG/$REPO" | |
| echo "Command: gh api --method=PUT orgs/$ORG/teams/$TEAM_TO_ADD/repos/$ORG/$REPO -f permission=$TEAM_PERMISSION" | |
| gh api --method=PUT "orgs/$ORG/teams/$TEAM_TO_ADD/repos/$ORG/$REPO" -f permission="$TEAM_PERMISSION" | |
| fi | |
| # --------------------------- | |
| # List collaborators | |
| # --------------------------- | |
| echo "Listing collaborators:" | |
| echo "Command: gh api repos/${ORG}/${REPO}/collaborators --jq '.[] | \"\(.login): \(.role_name)\"'" | |
| gh api "repos/${ORG}/${REPO}/collaborators" --jq '.[] | "\(.login): \(.role_name)"' | |
| echo "Repository '$REPO' successfully created under org '$ORG' with all branches mirrored!" | |
| echo "Clone the repo using the command: git clone ${TEMPLATE_SSH}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment