2020-04-23 19:48:55 +00:00
#!/bin/bash
2020-04-25 20:50:08 +00:00
# Executed when the master branch of PokeAPI/pokeapi gets updated
# Runs in CircleCI
# Generates new data using the latest changes of PokeAPI/pokeapi in order to open a Pull Request towards PokeAPI/api-data
2020-04-23 19:48:55 +00:00
set -o pipefail
org = 'PokeAPI'
data_repo = 'api-data'
2020-04-25 19:15:41 +00:00
engine_repo = 'pokeapi'
2020-05-02 17:59:09 +00:00
branch_name = 'staging'
2020-04-25 19:15:41 +00:00
username = 'pokeapi-machine-user'
email = 'pokeapi.co@gmail.com'
2020-05-13 14:14:42 +00:00
staging_environment_url = 'https://pokeapi-test-b6137.firebaseapp.com/api/v2/'
production_environment_url = 'https://pokeapi.co/api/v2/'
data_repo_url = 'https://github.com/PokeAPI/api-data'
engine_circleci_status_url = 'https://app.circleci.com/pipelines/github/PokeAPI/pokeapi'
deploy_circleci_status_url = 'https://app.circleci.com/pipelines/github/PokeAPI/deploy'
2020-05-13 15:38:08 +00:00
last_commit_message = $( git log --oneline --format= %B -n 1 HEAD | head -n 1)
2020-04-25 19:15:41 +00:00
2020-04-30 21:53:46 +00:00
# Exit the script notifying the user about its success
cleanexit( ) {
2020-04-25 19:15:41 +00:00
echo "Exiting"
echo " $2 "
2020-04-30 12:51:52 +00:00
if [ " $1 " -gt "0" ] ; then
notify_engine_pr "end_failed"
else
notify_engine_pr "end_success"
fi
2020-04-25 20:50:08 +00:00
exit $1
2020-04-25 19:15:41 +00:00
}
2020-04-23 19:48:55 +00:00
2020-04-25 20:40:21 +00:00
# Create and use a personal folder
2020-04-23 19:48:55 +00:00
prepare( ) {
2020-04-24 20:49:53 +00:00
mkdir -p ./repositories
2020-04-25 19:15:41 +00:00
cd repositories || cleanexit 1 "Failed to cd"
}
2020-04-25 20:40:21 +00:00
# Check and return the number of the Pull Request that started this job
2020-04-25 19:15:41 +00:00
get_invokator_pr_number( ) {
2020-05-26 15:28:16 +00:00
commit_msg_regex = "Merge pull request #([0-9]+) from PokeAPI/(.*)"
2020-05-02 17:59:09 +00:00
if ! [ -z " $CIRCLE_PULL_REQUEST " ] ; then
2020-04-25 19:15:41 +00:00
echo " ${ CIRCLE_PULL_REQUEST ##*/ } "
2020-05-26 15:28:16 +00:00
elif [ [ ${ last_commit_message } = ~ $commit_msg_regex ] ] ; then
echo " ${ BASH_REMATCH [1] } "
2020-05-02 17:59:09 +00:00
else
echo 'null'
2020-04-25 19:15:41 +00:00
fi
2020-04-23 19:48:55 +00:00
}
2020-04-25 20:40:21 +00:00
# Clone the repository containing the static JSON files
2020-04-23 19:48:55 +00:00
clone( ) {
2020-04-25 19:15:41 +00:00
git clone " https://github.com/ ${ org } / ${ data_repo } .git " " $data_repo "
2020-04-23 19:48:55 +00:00
}
2020-04-25 20:40:21 +00:00
# Configure git to use the supplied user when committing
2020-04-23 19:48:55 +00:00
configure_git( ) {
2020-04-25 19:15:41 +00:00
git config --global user.name " $username "
git config --global user.email " $email "
}
2020-04-30 12:51:52 +00:00
pr_input_updater_start( ) {
2020-04-25 19:15:41 +00:00
cat <<EOF
{
2020-05-13 14:14:42 +00:00
"body" : " A [PokeAPI/api-data]( ${ data_repo_url } ) refresh has started. In 45 minutes the staging branch of [PokeAPI/api-data]( ${ data_repo_url } /tree/staging) will be pushed with the new generated data. <br><br> The staging branch will be deployed in our [staging environment]( $staging_environment_url ) and you will be able to review the entire API. <br><br> A Pull Request ([master]( ${ data_repo_url } /tree/master)<-[staging]( ${ data_repo_url } /tree/staging)) will be also created at [PokeAPI/api-data]( ${ data_repo_url } /pulls) and assigned to the PokeAPI Core team to be reviewed. If approved and merged new data will soon be available worldwide at [pokeapi.co]( $production_environment_url ) "
2020-04-25 19:15:41 +00:00
}
EOF
}
2020-04-30 12:51:52 +00:00
pr_input_updater_end_success( ) {
cat <<EOF
{
2020-05-13 14:14:42 +00:00
"body" : " The updater script has finished its job and has now opened a Pull Request towards [PokeAPI/api-data]( ${ data_repo_url } /pulls) with the updated data. <br><br> You can see the Pull Request deployed at our [staging environment]( $staging_environment_url ) when [CircleCI deploy]( $deploy_circleci_status_url ) will be finished (_check the started time of the last build_) "
2020-04-30 12:51:52 +00:00
}
EOF
}
pr_input_updater_end_failed( ) {
cat <<EOF
{
2020-05-13 14:14:42 +00:00
"body" : " The updater script couldn't finish its job. Please check [CircleCI's builds]( $engine_circleci_status_url ) and [logs]( ${ CIRCLE_BUILD_URL } ). "
2020-04-30 12:51:52 +00:00
}
EOF
}
2020-04-30 21:53:46 +00:00
# If the job was started by a Pull Request, add a comment to notify the users
2020-04-30 12:51:52 +00:00
notify_engine_pr( ) {
2020-04-30 17:42:56 +00:00
if [ [ $1 = = "start" || $1 = = "end_failed" || $1 = = "end_success" ] ] ; then
2020-05-13 15:38:08 +00:00
engine_repo_pr_number = $( get_invokator_pr_number)
if [ " $engine_repo_pr_number " != "null" ] ; then
2020-04-30 12:51:52 +00:00
curl -f -H " Authorization: token $MACHINE_USER_GITHUB_API_TOKEN " -X POST --data " $( pr_input_updater_$1 ) " " https://api.github.com/repos/ $org / $engine_repo /issues/ ${ engine_repo_pr_number } /comments "
fi
2020-04-25 19:15:41 +00:00
fi
2020-04-23 19:48:55 +00:00
}
2020-04-25 20:40:21 +00:00
# Run the updater script (https://github.com/PokeAPI/api-data/blob/master/updater/cmd.bash) which will generate the new pokeapi data and push it to the api-data repository under a new branch
2020-04-24 20:49:53 +00:00
run_updater( ) {
2020-04-25 19:15:41 +00:00
cd " ${ data_repo } /updater " || cleanexit 1 "Failed to cd"
2020-05-13 14:01:54 +00:00
# Wait to be sure PokeAPI/pokeapi's master branch has been updated on Github with the lastest merged PR content
2020-04-25 19:15:41 +00:00
sleep 10
# Build the updater image
2020-04-24 20:49:53 +00:00
docker build -t pokeapi-updater .
2020-04-25 19:15:41 +00:00
if [ $? -ne 0 ] ; then
cleanexit 1 "Failed to build the pokeapi-updater image"
fi
# Run the updater
docker run --privileged -e COMMIT_EMAIL = " $email " -e COMMIT_NAME = " $username " -e BRANCH_NAME = " $branch_name " -e REPO_POKEAPI = " https://github.com/ ${ org } / ${ engine_repo } .git " -e REPO_DATA = " https:// ${ MACHINE_USER_GITHUB_API_TOKEN } @github.com/ ${ org } / ${ data_repo } .git " pokeapi-updater
if [ $? -ne 0 ] ; then
2020-04-25 20:50:08 +00:00
cleanexit 1 "Failed to run the pokeapi-updater container"
2020-04-25 19:15:41 +00:00
fi
cd .. || cleanexit 1 "Failed to cd"
2020-04-23 19:48:55 +00:00
}
2020-04-25 20:40:21 +00:00
# Check if the updater script has pushed the data to a new branch
2020-04-25 19:15:41 +00:00
check_remote_branch( ) {
2020-04-25 20:40:21 +00:00
# Wait for Github to update origin/${branch_name}
sleep 10
2020-04-25 19:15:41 +00:00
curl -f -H " Authorization: token $MACHINE_USER_GITHUB_API_TOKEN " -X GET " https://api.github.com/repos/ $org / $data_repo /branches/ $1 "
if [ $? -ne 0 ] ; then
2020-04-25 20:40:21 +00:00
cleanexit 1 "The updater script failed to push the new data"
2020-04-25 19:15:41 +00:00
fi
}
2020-04-24 20:49:53 +00:00
2020-05-26 15:28:16 +00:00
# Generate the input content that will be sent to Github's API to open a refresh-data PR towards PokeAPI/api-data
pr_input_content_with_pr_number( ) {
2020-04-23 19:48:55 +00:00
cat <<EOF
{
2020-05-02 17:59:09 +00:00
"title" : " API data update from \` ${ org } / ${ engine_repo } # ${ 1 } \` " ,
2020-05-13 14:14:42 +00:00
"body" : " Incoming data generated by [ ${ org } / ${ engine_repo } ](https://github.com/ ${ org } / ${ engine_repo } )'s CircleCI worker since Pull Request [# ${ 1 } ](https://github.com/ ${ org } / ${ engine_repo } /pull/ ${ 1 } ) was merged into the \`master\` branch. <br><br> The new data was generated using a copy of [ ${ org } / ${ engine_repo } ](https://github.com/ ${ org } / ${ engine_repo } /commits/master) repository when the \`HEAD\` was pointing to \` ${ CIRCLE_SHA1 } \`. <br><br> This Pull Request should have been deployed in our [staging environment]( $staging_environment_url ), check [here]( $deploy_circleci_status_url ) for the lastest build timestamp and status code. " ,
2020-04-23 19:48:55 +00:00
"head" : " $branch_name " ,
"base" : "master" ,
"assignees" : [
"Naramsim"
] ,
"labels" : [
"api-data-update"
]
}
EOF
}
2020-05-26 15:28:16 +00:00
# Copy of pr_input_content_with_pr_number
# run when the script cannot detect the merged PR number that started the CircleCI job
pr_input_content_without_pr_number( ) {
cat <<EOF
{
"title" : " API data update from \` ${ org } / ${ engine_repo } \` " ,
"body" : " Incoming data generated by [ ${ org } / ${ engine_repo } ](https://github.com/ ${ org } / ${ engine_repo } )'s CircleCI worker. <br><br> The new data was generated using a copy of [ ${ org } / ${ engine_repo } ](https://github.com/ ${ org } / ${ engine_repo } /commits/master) repository when the \`HEAD\` was pointing to \` ${ CIRCLE_SHA1 } \`. <br><br> This Pull Request should have been deployed in our [staging environment]( $staging_environment_url ), check [here]( $deploy_circleci_status_url ) for the lastest build timestamp and status code. " ,
"head" : " $branch_name " ,
"base" : "master" ,
"assignees" : [
"Naramsim"
] ,
"labels" : [
"api-data-update"
]
}
EOF
}
2020-04-25 20:40:21 +00:00
# Create a Pull Request to merge the branch recently pushed by the updater with the master branch
create_pr( ) {
2020-05-02 17:59:09 +00:00
engine_repo_pr_number = $( get_invokator_pr_number)
2020-05-26 15:28:16 +00:00
if [ " $engine_repo_pr_number " != "null" ] ; then
data_repo_pr_number = $( curl -H " Authorization: token $MACHINE_USER_GITHUB_API_TOKEN " -X POST --data " $( pr_input_content_with_pr_number " $engine_repo_pr_number " ) " " https://api.github.com/repos/ $org / $data_repo /pulls " | jq '.number' )
else
data_repo_pr_number = $( curl -H " Authorization: token $MACHINE_USER_GITHUB_API_TOKEN " -X POST --data " $( pr_input_content_without_pr_number) " " https://api.github.com/repos/ $org / $data_repo /pulls " | jq '.number' )
fi
2020-04-30 12:51:52 +00:00
if [ [ " $data_repo_pr_number " = "null" ] ] ; then
2020-04-25 20:40:21 +00:00
cleanexit 1 "Couldn't create the Pull Request"
fi
2020-04-30 12:51:52 +00:00
echo " $data_repo_pr_number "
2020-04-25 20:40:21 +00:00
}
pr_input_assignees_and_labels( ) {
2020-04-23 20:31:08 +00:00
cat <<EOF
{
"assignees" : [
"Naramsim"
] ,
"labels" : [
"api-data-update"
]
}
EOF
}
2020-04-25 20:40:21 +00:00
# Assign the PR to Naramsim and add a label
customize_pr( ) {
# Wait for Github to open the PR
sleep 10
2020-04-30 12:51:52 +00:00
data_repo_pr_number = $1
curl -H " Authorization: token $MACHINE_USER_GITHUB_API_TOKEN " -X PATCH --data " $( pr_input_assignees_and_labels) " " https://api.github.com/repos/ $org / $data_repo /issues/ $data_repo_pr_number "
2020-04-25 20:40:21 +00:00
if [ $? -ne 0 ] ; then
echo "Couldn't add Assignees and Labes to the Pull Request"
fi
}
2020-04-25 20:50:08 +00:00
pr_input_reviewers( ) {
2020-04-23 19:48:55 +00:00
cat <<EOF
{
"reviewers" : [
"Naramsim"
2020-04-25 20:50:08 +00:00
] ,
"team_reviewers" : [
"core-team"
2020-04-23 19:48:55 +00:00
]
}
EOF
}
2020-04-25 20:40:21 +00:00
# Request the Core team to review the Pull Request
add_reviewers_to_pr( ) {
2020-04-30 12:51:52 +00:00
data_repo_pr_number = $1
curl -H " Authorization: token $MACHINE_USER_GITHUB_API_TOKEN " -X POST --data " $( pr_input_reviewers) " " https://api.github.com/repos/ $org / $data_repo /pulls/ $data_repo_pr_number /requested_reviewers "
2020-04-24 19:18:26 +00:00
if [ $? -ne 0 ] ; then
echo "Couldn't add Reviewers to the Pull Request"
fi
2020-04-23 19:48:55 +00:00
}
prepare
configure_git
2020-04-30 21:53:46 +00:00
clone
2020-04-30 12:51:52 +00:00
notify_engine_pr "start"
2020-04-24 20:49:53 +00:00
run_updater
2020-04-25 19:15:41 +00:00
check_remote_branch " $branch_name "
2020-05-03 15:16:02 +00:00
if [ " $CIRCLE_BRANCH " = 'master' ] ; then
sleep 300 # 5 minutes, the time it takes for CircleCI's api-data script to generate the data and for CircleCI's deploy script to deploy it to the staging environment
check_remote_branch " $branch_name "
data_repo_pr_number = $( create_pr)
customize_pr " $data_repo_pr_number "
add_reviewers_to_pr " $data_repo_pr_number "
fi
2020-04-25 20:50:08 +00:00
cleanexit 0 'Done'