-
Notifications
You must be signed in to change notification settings - Fork 282
/
create-practice-repos
executable file
·189 lines (157 loc) · 6.33 KB
/
create-practice-repos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/env bash
#
# Create practice repos
#################################################################
# NOTE: You must have a personal access token (PAT) #
# saved to your environment variables to use this script. #
# We recommend a dedicated service account (e.g. githubteacher) #
#################################################################
# shellcheck disable=SC1091
source "$HOME/.trainingmanualrc"
# shellcheck source=script/shared_functions
source ./shared_functions
# shell variables
collab_repo=$1
template_name=$2
practice_repo_name=$3
safe_org_url="https://$ROOT_URL/$CLASS_ORG"
org_url="https://$TOKEN_OWNER:$TEACHER_PAT@$ROOT_URL/$CLASS_ORG"
org_repos_endpoint="https://$INSTANCE_URL/repos/$CLASS_ORG"
template_url="https://github.com/githubtraining/$template_name"
template_url_ghes="https://$ROOT_URL/$CLASS_ORG/$template_name"
template_pages_url="https://$CLASS_ORG.github.io/$template_name"
template_pages_url_ghes="https://$ROOT_URL/pages/$CLASS_ORG/$template_name"
check_template_url() {
# if root url is not github.com
if [ "$ROOT_URL" != "github.com" ]; then
# if template can be found on GHES
if repo_is_reachable "$template_url_ghes"; then
# use template and GitHub Pages URL from GHES instead of the public template
template_url="$template_url_ghes"
template_pages_url="$template_pages_url_ghes"
# otherwise check if public template can be reached
elif repo_is_reachable "$template_url"; then
echo "Template not found on $ROOT_URL. Using public template instead: $template_url"
else # template could not be reached
print_error "Could not reach template repo. Please grab a copy from $template_url and upload it to your GHES instance."
fi
# if template cannot be reached
elif ! repo_is_reachable "$template_url"; then
print_error "Unable to reach template repo: $template_url"
fi
}
clone_template() {
# create a temporary directory for temporary files
temp_dir=$(mktemp -d)
# delete the temporary directory on script exit
trap 'rm -rf "$temp_dir"' EXIT
# attempt to clone template repo
git clone --bare "$template_url" "$temp_dir" >>log.out 2>&1 || {
# if git clone command failed
print_error "Failed to clone template repository."
exit 1
}
default_branch=$(sed 's@^ref: refs/heads/@@' "$temp_dir"/HEAD)
}
generate_repos() {
# Create practice repos based on collaborators in the inital class repo
# :? will display an error if $collaborators is empty or unset
for username in "${collaborators[@]:?}"; do
# if a practice repo has already been created for the user
if repo_is_reachable "$org_url/$practice_repo_name-$username"; then
# ask if the repository should be deleted and recreated
if ask "A $practice_repo_name repo already exists for $username.\nIs it OK to delete and recreate?" N; then
echo "Deleting $CLASS_ORG/$practice_repo_name-$username... "
# delete the existing practice repo
http --auth "$TOKEN_OWNER:$TEACHER_PAT" \
DELETE "$org_repos_endpoint/$practice_repo_name-$username" >>log.out 2>&1
# create a new practice repo
create_practice_repo "$username"
else
echo "OK. Skipping $username... "
fi
else
# create a new practice repository
create_practice_repo "$username"
fi
done
}
create_practice_repo() {
student=$1
local repo_name="$practice_repo_name-$student"
local repo_url="https://$ROOT_URL/$CLASS_ORG/$repo_name"
if [[ "$ROOT_URL" == "github.com" ]]; then
export local pages_url="https://$CLASS_ORG.github.io/$repo_name"
else
export local pages_url="https://$ROOT_URL/pages/$CLASS_ORG/$repo_name"
fi
case $practice_repo_name in
conflict-practice)
local repo_description="Let's resolve some conflicts."
# Create a new repo named $repo_name in $CLASS_ORG
create_repo \
--name "$repo_name" \
--description "$repo_description" \
--private true \
--has_wiki false
git_push "$repo_name"
# Create PRs for each branch
echo "Creating practice pull requests for $CLASS_ORG/$repo_name... "
create_pull_request --repo "$repo_name" --head 'manual' --base "$default_branch" \
--title "Updates to game manual" \
--body "$(<"$practice_repos_dir/conflict-practice/pull_request_1.md")"
create_pull_request --repo "$repo_name" --head 'css-changes' --base "$default_branch" \
--title "Minor CSS fixes" \
--body "$(<"$practice_repos_dir/conflict-practice/pull_request_2.md")"
create_pull_request --repo "$repo_name" --head 'readme-update' --base "$default_branch" \
--title "Update README" \
--body "$(<"$practice_repos_dir/conflict-practice/pull_request_3.md")"
;;
github-games)
local repo_description="A fun way to learn about git troubleshooting."
# Create a new practice repo named $repo_name in $CLASS_ORG
create_repo \
--name "$repo_name" \
--description "$repo_description" \
--homepage "$template_pages_url" \
--private true \
--has_wiki false
git_push "$repo_name"
# Create issues for problems
echo "Creating practice issues for $CLASS_ORG/$repo_name... "
create_issue --repo "$repo_name" \
--title "Game broken" \
--body "$(envsubst <"$practice_repos_dir/github-games/issue_1.md")"
create_issue --repo "$repo_name" \
--title "URL in description and README broken" \
--body "$(envsubst <"$practice_repos_dir/github-games/issue_2.md")"
;;
*)
print_error "Practice repo name \'$practice_repo_name\' not recognized."
exit 1
;;
esac
# Invite student as a collaborator
add_repo_collaborator \
--repo "$repo_name" \
--user "$student" \
--permission "admin"
print_done "Repo URL: $repo_url"
}
# Navigate to the practice-repos directory
cd "$(dirname "$0")/../practice-repos" || exit
# set $practice_repos_dir to the "physical" path of the working directory
practice_repos_dir=$(pwd -P)
# get list of repo collaborators
get_collaborators "$collab_repo"
# check template url
check_template_url
# clone template repository
clone_template
# switch to temp directory and push it on the stack
pushd "$temp_dir" >>log.out 2>&1 || return
# generate a repo for each collaborator
generate_repos
# switch back to original directory
popd >>log.out 2>&1 || return
print_success "All $practice_repo_name repos can be found here: $safe_org_url"