-
Notifications
You must be signed in to change notification settings - Fork 282
/
create-files
executable file
·215 lines (189 loc) · 9.36 KB
/
create-files
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/env bash
#
# Create Files
# Source it up
# shellcheck disable=SC1091
source "$HOME/.trainingmanualrc"
# shellcheck source=script/shared_functions
source ./shared_functions
#################################################################
# 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) #
#################################################################
# Shell variables
collab_repo=$1
repo_endpoint="https://$INSTANCE_URL/repos/$CLASS_ORG/$collab_repo"
repo_url="https://$ROOT_URL/$CLASS_ORG/$collab_repo"
add_collaborators() {
echo -e "\nAdding collaborators..."
for commenter in "${commenters[@]}"; do
# Check if commenter is already a collaborator
if [[ ${collaborators[*]:?} == *"${commenter}"* ]]; then
existing_collaborators+=("$commenter")
else # Add collaborator
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" \
-X PUT "$repo_endpoint/collaborators/$commenter" >>log.out 2>&1
get_collaborators "$collab_repo" # Update list of collaborators
fi
done
# Check if any commenters are already collaborators
print_list "The following commenters are already collaborators" "${existing_collaborators[@]}"
}
create_files() {
echo -e "\nCreating files for collaborators..."
# Iterate through the list of collaborators
for collaborator in "${collaborators[@]}"; do
get_existing_files # Update list of existing files
# Check a file has already been created for this collaborator
if [[ ${existing_files[*]} == *"-${collaborator}.md"* ]]; then
collaborators_with_existing_files+=("$collaborator")
else
# Get the last element of the $existing_files array
last_file=${existing_files[*]: -1}
# Get the file number from the last file in $existing_files
# Assumes the file number is eactly two digits long
last_file_num="${last_file:0:2}" # ${VAR:OFFSET:LENGTH}
# New file number (one greater than the last file number)
new_file_num=$(printf '%02d\n' $((10#$last_file_num + 1))) # two digits (pad with zero if < 10)
# create file for collaborator
new_file="$new_file_num-$collaborator.md"
cat "../slide_template.md" >>"$new_file"
# Pick a random image for slide
random_image=${slide_images[$RANDOM % ${#slide_images[@]}]}
# Check the operating system to determine which commands to run
if [[ "$OSTYPE" = "msys" || "$OSTYPE" = "linux-gnu" ]]; then
# Insert slide image into slide
sed -i "s|IMAGE|$random_image|g" "$new_file" >>log.out 2>&1
# Encode the file
content=$(base64 <"$new_file" --wrap=0)
else
# Insert slide image into slide
sed -i "" "s|IMAGE|$random_image|g" "$new_file" >>log.out 2>&1
# Encode the file
content=$(base64 <"$new_file")
fi
# Put the file in the repository
path="_slides/$new_file"
message="Create activity file for $collaborator"
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"path\": \"$path\", \"message\": \"$message\", \"content\": \"$content\" }" \
-X PUT "$repo_endpoint/contents/$path" >>log.out 2>&1
# Remove the local file
rm "./$new_file"
# List of collaborators that new files are being created for
collaborators_with_new_files+=("$collaborator")
fi
done
# Print list of collaborators that new files were created for
print_list "New files were created for the following collaborators" "${collaborators_with_new_files[@]}"
# Print list of collaborators that already had files
print_list "The following collaborators already had files" "${collaborators_with_existing_files[@]}"
}
create_issues() {
get_issues # Get a list of issues in the repository
issue_body="Using the API, I have just created a file with a random octocat for you to caption. In this activity, we will learn how to make changes to files in our GitHub repository.\n\n"
for collaborator in "${collaborators[@]}"; do
issue_body="$issue_body- [ ] @$collaborator\n"
done
issue_title="Activity 1: Your First Caption"
# Check if any of the existing issue titles contain $issue_title
if [[ ${issues[*]} == *"$issue_title"* ]]; then
# Find the issue that contains issue_title so it can be patched
for issue in "${issues[@]}"; do
if [[ $issue == *"$issue_title"* ]]; then
caption_issue_number=$(echo "$issue" | cut -d. -f1)
# Update the issue text since it already exists
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"body\": \"$issue_body\" }" -X PATCH "$repo_endpoint/issues/$caption_issue_number" >>log.out 2>&1
# Print the updated issue text
echo -e "The activity issue has been updated: $repo_url/issues/$caption_issue_number\n"
fi
done
else
# This is the first run - create activity issues
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"title\": \"$issue_title\", \"body\": \"$issue_body\" }" -X POST "$repo_endpoint/issues" >>log.out 2>&1
issue_title="Add A New Slide"
issue_body="## We Need More Slides\nGrab another octocat and create a new slide from scratch.\nIf you need help, check out the Appendix in the training manual."
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"title\": \"$issue_title\", \"body\": \"$issue_body\" }" -X POST "$repo_endpoint/issues" >>log.out 2>&1
issue_title="Add a Caption To an Existing Slide"
issue_body="## Can you think of a better caption?\nEach slide can have more than one caption. Check out the current slide show and add a caption (or two).\nIf you need help, check out the Appendix in the training manual."
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"title\": \"$issue_title\", \"body\": \"$issue_body\" }" -X POST "$repo_endpoint/issues" >>log.out 2>&1
issue_title="Improve the README"
issue_body="## Do you have a favorite Git Resource?\nAdd it to the README!\n If you need help, check out the Appendix in the training manual."
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"title\": \"$issue_title\", \"body\": \"$issue_body\" }" -X POST "$repo_endpoint/issues" >>log.out 2>&1
issue_title="Restyle the Slides"
issue_body="## Do you have an eye for design?\nHelp us improve the look of the slide deck.\nIf you need help, check out the Appendix in the training manual."
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"title\": \"$issue_title\", \"body\": \"$issue_body\" }" -X POST "$repo_endpoint/issues" >>log.out 2>&1
issue_title="Parking Lot"
issue_body="## Post any questions you may have here during the training."
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"title\": \"$issue_title\", \"body\": \"$issue_body\" }" -X POST "$repo_endpoint/issues" >>log.out 2>&1
fi
}
make_repo_private() {
# Check if the repo is private
repo_is_private=$(curl -s -S -u "$TOKEN_OWNER:$TEACHER_PAT" -X GET "$repo_endpoint" | jq .private) >>log.out 2>&1
# If the repo is private
if "$repo_is_private"; then
echo "This repo is already private."
return # exit the function
fi
# Default to 'yes' if no answer is given
if ask "Are you ready to make this repo private?" Y; then
# Make the repo private
curl -s -S -i -u "$TOKEN_OWNER:$TEACHER_PAT" -d "{ \"name\": \"$collab_repo\", \"private\": true }" -X PATCH "$repo_endpoint" >>log.out 2>&1
else
echo "OK, just remember to make the repo private and add the info for booking 1:1 appointments to the README."
fi
}
get_commenters() {
# Array of commenters
IFS=" " read -ra commenters <<<"$(
curl -s -S -u "$TOKEN_OWNER:$TEACHER_PAT" -X GET "$repo_endpoint/issues/1/comments?per_page=100" |
jq -r 'map(.user.login) | unique | @sh' | tr -d \'
)" >>log.out 2>&1
}
get_existing_files() {
# Get existing file names
IFS=" " read -ra existing_files <<<"$(
curl -s -S -u "$TOKEN_OWNER:$TEACHER_PAT" -X GET "$repo_endpoint/contents/_slides" | jq -r 'map(.name) | @sh' | tr -d \'
)"
}
get_issues() {
# Get list of issues from the repository (formatted as '$NUM. $TITLE')
IFS=$'\n' read -d "" -ra issues <<<"$(
curl -s -S -u "$TOKEN_OWNER:$TEACHER_PAT" -X GET "$repo_endpoint/issues?state=all" | jq -r 'reverse | .[] | "\(.number). \(.title)" | @sh' | tr -d \'
)" >>log.out 2>&1
}
print_list() {
list_title=$1 # Save first argument in a variable
shift # shift all arguments to the left (original $1 gets lost)
list_items=("$@") # Rebuild the array with rest of arguments
# Check if any commenters are already collaborators
if [ "${#list_items[@]}" -ne 0 ]; then
echo -e "$list_title:"
# Prefix each collaborator with '- '
list_items=("${list_items[@]/#/- }")
# Print list of collaborators that are already collaborators
printf '%s\n' "${list_items[@]}"
echo # line break
fi
}
# Make sure repo exists before attempting to interact with it
repo_status=$(curl -s -S -u "${TOKEN_OWNER}:${TEACHER_PAT}" -X GET "$repo_endpoint") >>log.out 2>&1
# Exit the script if the repo cannot be found
if [[ $repo_status == *"Not Found"* ]]; then
echo "Repo not found. Please try again."
exit
fi
# Array of slide images from file
IFS=$'\n' read -d "" -ra slide_images <"../slide_images.md"
# Get a list of collaborators and commenters
get_collaborators "$collab_repo"
get_commenters
# Add collaborators
add_collaborators
# Create files
create_files
# Create issues
create_issues
# Make it private
make_repo_private