Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A script to create and set a github repo up
#!/usr/bin/env bash
#
# Creates a new github repository with all our nice defaults,
# using a template repository
#
# Installation:
# - cd ~/bin
# - ln -s <this file>
# Running
# `git create-repo [name of the new repo (optional)]`
set -e -o pipefail -u
if [[ -d .git ]]; then
echo "This directory already contains a git repo."
exit
fi
github_org="YOUR COMPANY HERE"
github_base="https://api.github.com"
github_type="Accept: application/vnd.github.baptiste-preview+json"
github_team="THE NAME OF YOUR TEAM HERE" # Warning: the team will be given admin access (you can change it)!
# Will be requested to the user
github_template=""
# Read the repo name from the name of the directory or the first parameter
repo_name=${1:-${PWD##*/}}
repo_full_name="${github_org}/${repo_name}"
main() {
read_gh_token
echo "About to create a new repo named '${repo_full_name}'"
assert_repo_is_new
select_repo_template
if [[ "${github_template}" == "" ]]; then
echo "OK, bye."
exit
fi
create_repo
setup_repo
echo "https://github.com/${repo_full_name} created and updated"
echo "git clone git@github.com:${github_org}/${github_base}.git"
echo
echo "Things left to do now:"
echo "- Update the README"
echo "- Add a description to the repo"
echo "- Add the team to it"
}
read_gh_token() {
if [[ "${GH_TOKEN:-}" == "" ]]; then
# Try reading it out of local config
token_file=${HOME}/.config/github_token
if [[ -f ${token_file} ]]; then
GH_TOKEN=$(head -1 ${token_file})
fi
if [[ "${GH_TOKEN:-}" == "" ]]; then
echo "You need to provide the GH_TOKEN env variable (Settings => Developer Settings => Tokens)."
exit
fi
fi
}
assert_repo_is_new() {
# Does the repo already exist in Github?
local response=$(curl -H "Authorization: token ${GH_TOKEN}" -H "${github_type}" \
--silent \
--write-out '%{http_code}' \
--output /dev/null \
"${github_base}/repos/${repo_full_name}"
)
if [[ ${response} == 200 ]]; then
echo "The repository already exists"
exit
fi
}
select_repo_template() {
# Find all the available templates
local response=$(curl --silent -H "Authorization: token ${GH_TOKEN}" -H "${github_type}" \
"${github_base}/orgs/${github_org}/repos"
)
# According to the doc there will be a "is_template" key; we check the name for now
echo
local templates=($(echo ${response} | jq -r '.[] | select(.name | startswith("template-")) | .name'))
if [[ "${templates:-}" == "" ]]; then
echo "Can't find any templates: maybe your GH_TOKEN is wrong?"
exit
fi
PS3="Select a template to use (or ^C): "
select opt in "${templates[@]}"; do
if [[ "${opt}" != "" ]]; then
github_template=${opt}
fi
break
done
}
create_repo() {
echo
echo Creating the repo…
local response=$(curl -H "Authorization: token ${GH_TOKEN}" -H "${github_type}" \
--silent \
--write-out '%{http_code}' \
--output /dev/null \
-X POST \
${github_base}/repos/${github_org}/${github_template}/generate \
-d '{
"private": true,
"name": "'"${repo_name}"'",
"owner": "'"${github_org}"'"
}'
)
if [[ ${response} != 200 && ${response} != 201 ]]; then
echo "The repository creation failed (${response})"
exit
fi
}
setup_repo() {
echo
echo Setting up the new repo…
# Basic stuff
local response=$(curl -H "Authorization: token ${GH_TOKEN}" -H "${github_type}" \
--silent \
--write-out '%{http_code}' \
--output /dev/null \
-X PATCH \
${github_base}/repos/${repo_full_name} \
-d '{
"has_issues": false,
"has_projects": false,
"has_wiki": false,
"allow_squash_merge": true,
"allow_merge_commit": false,
"allow_rebase_merge": false,
"delete_branch_on_merge": true
}'
)
if [[ ${response} != 200 && ${response} != 201 ]]; then
echo "The repository failed, but the repo has been created. You may want to setup it manually (${response})"
exit
fi
# Main branch restrictions
# To support `required_approving_review_count` we must use `application/vnd.github.luke-cage-preview+json`
response=$(curl -H "Authorization: token ${GH_TOKEN}" -H "Accept: application/vnd.github.luke-cage-preview+json" \
--silent \
--write-out '%{http_code}' \
--output /dev/null \
-X PUT \
${github_base}/repos/${repo_full_name}/branches/main/protection \
-d '{
"required_status_checks": {
"strict": true,
"contexts": []
},
"required_pull_request_reviews": {
"dismiss_stale_reviews": false,
"require_code_owner_reviews": false,
"required_approving_review_count": 1
},
"enforce_admins": false,
"restrictions": null,
"allow_force_pushes": false,
"allow_deletions": false
}'
)
echo "Response for branch protection: ${response}"
# Requires signed commits
# Yet another preview header...
response=$(curl -H "Authorization: token ${GH_TOKEN}" -H "Accept: application/vnd.github.zzzax-preview+json" \
--silent \
--write-out '%{http_code}' \
--output /dev/null \
-X POST \
${github_base}/repos/${repo_full_name}/branches/main/protection/required_signatures
)
echo "Response for commit signatures: ${response}"
# "Don't push to main" is not easy to implement
# Add the Developers team to the repo
response=$(curl -H "Authorization: token ${GH_TOKEN}" -H "${github_type}" \
--silent \
--write-out '%{http_code}' \
--output /dev/null \
-X PUT \
${github_base}/orgs/${github_org}/teams/${github_team}/repos/${repo_full_name} \
-d '{
"permission": "admin"
}'
)
echo "Response for adding the developers team: ${response}"
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment