github-deploy.sh 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #!/usr/bin/env bash
  2. ##
  3. # Pushes commits to a GitHub repo
  4. #
  5. # @author Daniel Rudolf
  6. # @link http://picocms.org
  7. # @license http://opensource.org/licenses/MIT
  8. #
  9. set -e
  10. # parameters
  11. CHECK_REPO_SLUG="$1" # optional GitHub repo (e.g. picocms/Pico) to check
  12. # its latest commit as basic race condition protection
  13. CHECK_REMOTE_REF="$2" # optional remote Git reference (e.g. heads/master)
  14. CHECK_LOCAL_COMMIT="$3" # optional local commit SHA1
  15. # print parameters
  16. echo "Deploying repo..."
  17. printf 'CHECK_REPO_SLUG="%s"\n' "$CHECK_REPO_SLUG"
  18. printf 'CHECK_REMOTE_REF="%s"\n' "$CHECK_REMOTE_REF"
  19. printf 'CHECK_LOCAL_COMMIT="%s"\n' "$CHECK_LOCAL_COMMIT"
  20. echo
  21. # check for changes
  22. if [ -z "$(git log --oneline '@{upstream}..')" ]; then
  23. printf 'Nothing to deploy; skipping...\n\n'
  24. exit 0
  25. fi
  26. # race condition protection for concurrent Travis builds
  27. # this is no definite protection (race conditions are still possible during `git push`),
  28. # but it should give a basic protection without disabling concurrent builds completely
  29. if [ -n "$CHECK_REPO_SLUG" ] && [ -n "$CHECK_REMOTE_REF" ] && [ -n "$CHECK_LOCAL_COMMIT" ]; then
  30. # retrieve information using GitHub APIv3
  31. printf 'Checking latest commit...\n'
  32. CHECK_API_URL="https://api.github.com/repos/$CHECK_REPO_SLUG/git/refs/$CHECK_REMOTE_REF"
  33. if [ -n "$GITHUB_OAUTH_TOKEN" ]; then
  34. CHECK_API_RESPONSE="$(wget -O- --header="Authorization: token $GITHUB_OAUTH_TOKEN" "$CHECK_API_URL" 2> /dev/null)"
  35. else
  36. CHECK_API_RESPONSE="$(wget -O- "$CHECK_API_URL" 2> /dev/null)"
  37. fi
  38. # evaluate JSON response
  39. CHECK_REMOTE_COMMIT="$(echo "$CHECK_API_RESPONSE" | php -r "
  40. \$json = json_decode(stream_get_contents(STDIN), true);
  41. if (\$json !== null) {
  42. if (isset(\$json['ref']) && (\$json['ref'] === 'refs/$CHECK_REMOTE_REF')) {
  43. if (isset(\$json['object']) && isset(\$json['object']['sha'])) {
  44. echo \$json['object']['sha'];
  45. }
  46. }
  47. }
  48. ")"
  49. # compare source reference against the latest commit
  50. if [ "$CHECK_REMOTE_COMMIT" != "$CHECK_LOCAL_COMMIT" ]; then
  51. echo "Latest local commit '$CHECK_LOCAL_COMMIT' doesn't match latest remote commit '$CHECK_REMOTE_COMMIT'; aborting..." >&2
  52. exit 1
  53. fi
  54. echo
  55. fi
  56. # push changes
  57. printf 'Pushing changes...\n'
  58. git push
  59. echo