git-push-all.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/env bash
  2. # Usage: git-push-all.sh -t <test-branch-prefix> -r <remote-name>
  3. # -- <git-opts>
  4. # env vars: TOR_UPSTREAM_REMOTE_NAME=upstream TOR_PUSH_DELAY=0
  5. # git-opts: --no-atomic --dry-run (any other git push option)
  6. #
  7. # TOR_PUSH_DELAY pushes the master and maint branches separately, so that CI
  8. # runs in a sensible order.
  9. # push --atomic is the default when TOR_PUSH_DELAY=0, and for release branches.
  10. set -e
  11. #################
  12. # Configuration #
  13. #################
  14. # Don't change this configuration - set the env vars in your .profile
  15. #
  16. # git push command and default arguments
  17. GIT_PUSH=${TOR_GIT_PUSH:-"git push --atomic"}
  18. # The upstream remote which git.torproject.org/tor.git points to.
  19. # In test branch mode, override this setting with -r <remote-name>
  20. UPSTREAM_REMOTE=${TOR_UPSTREAM_REMOTE_NAME:-"upstream"}
  21. # Add a delay between pushes, so CI runs on the most important branches first
  22. PUSH_DELAY=${TOR_PUSH_DELAY:-0}
  23. #######################
  24. # Argument processing #
  25. #######################
  26. # Controlled by the -t <test-branch-prefix> option. The test branch base
  27. # name option makes git-merge-forward.sh create new test branches:
  28. # <tbbn>_029, <tbbn>_035, ... , <tbbn>_master, and merge forward.
  29. TEST_BRANCH_PREFIX=
  30. while getopts ":r:t:" opt; do
  31. case "$opt" in
  32. r) UPSTREAM_REMOTE="$OPTARG"
  33. echo " *** PUSHING TO REMOTE: ${UPSTREAM_REMOTE} ***"
  34. shift
  35. shift
  36. OPTIND=$[$OPTIND - 2]
  37. ;;
  38. t) TEST_BRANCH_PREFIX="$OPTARG"
  39. echo " *** PUSHING TEST BRANCHES: ${TEST_BRANCH_PREFIX}_nnn ***"
  40. shift
  41. shift
  42. OPTIND=$[$OPTIND - 2]
  43. ;;
  44. *)
  45. # Assume we're done with script arguments,
  46. # and git push will handle the option
  47. break
  48. ;;
  49. esac
  50. done
  51. # getopts doesn't allow "-" as an option character,
  52. # so we have to handle -- manually
  53. if [ "$1" = "--" ]; then
  54. shift
  55. fi
  56. echo "Calling git push --atomic $@ <branches>"
  57. if [ "$TEST_BRANCH_PREFIX" ]; then
  58. if [ "$UPSTREAM_REMOTE" = ${TOR_UPSTREAM_REMOTE_NAME:-"upstream"} ]; then
  59. echo "Pushing test branches ${TEST_BRANCH_PREFIX}_nnn to " \
  60. "$UPSTREAM_REMOTE is not allowed."
  61. echo "Usage: $0 -r <remote-name> -t <test-branch-prefix> <git-opts>"
  62. exit 1
  63. fi
  64. fi
  65. ########################
  66. # Git branches to push #
  67. ########################
  68. PUSH_BRANCHES=$(echo \
  69. master \
  70. {release,maint}-0.4.1 \
  71. {release,maint}-0.4.0 \
  72. {release,maint}-0.3.5 \
  73. {release,maint}-0.2.9 \
  74. )
  75. if [ -z "$TEST_BRANCH_PREFIX" ]; then
  76. # maint/release push mode
  77. #
  78. # List of branches to push. Ordering is not important.
  79. PUSH_BRANCHES=$(echo \
  80. master \
  81. {release,maint}-0.4.1 \
  82. {release,maint}-0.4.0 \
  83. {release,maint}-0.3.5 \
  84. {release,maint}-0.2.9 \
  85. )
  86. else
  87. # Test branch mode: merge to maint only, and create a new branch for 0.2.9
  88. #
  89. # List of branches to push. Ordering is not important.
  90. PUSH_BRANCHES=$(echo \
  91. ${TEST_BRANCH_PREFIX}_master \
  92. ${TEST_BRANCH_PREFIX}_041 \
  93. ${TEST_BRANCH_PREFIX}_040 \
  94. ${TEST_BRANCH_PREFIX}_035 \
  95. ${TEST_BRANCH_PREFIX}_029 \
  96. )
  97. fi
  98. ###############
  99. # Entry point #
  100. ###############
  101. if [ "$PUSH_DELAY" -le 0 ]; then
  102. echo "Pushing $PUSH_BRANCHES"
  103. # We know that there are no spaces in any branch within $PUSH_BRANCHES, so
  104. # it is safe to use it unquoted. (This also applies to the other shellcheck
  105. # exceptions below.)
  106. #
  107. # Push all the branches at the same time
  108. # shellcheck disable=SC2086
  109. $GIT_PUSH "$@" "$UPSTREAM_REMOTE" $PUSH_BRANCHES
  110. else
  111. # Push the branches in optimal CI order, with a delay between each push
  112. PUSH_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | sort -V)
  113. MASTER_BRANCH=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep master)
  114. if [ -z "$TEST_BRANCH_PREFIX" ]; then
  115. MAINT_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep maint)
  116. RELEASE_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep release | \
  117. tr "\n" " ")
  118. printf "Pushing with %ss delays, so CI runs in this order:\n%s\n%s\n%s\n" \
  119. "$PUSH_DELAY" "$MASTER_BRANCH" "$MAINT_BRANCHES" "$RELEASE_BRANCHES"
  120. else
  121. # Actually test branches based on maint branches
  122. MAINT_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep -v master)
  123. printf "Pushing with %ss delays, so CI runs in this order:\n%s\n%s\n" \
  124. "$PUSH_DELAY" "$MASTER_BRANCH" "$MAINT_BRANCHES"
  125. # No release branches
  126. RELEASE_BRANCHES=
  127. fi
  128. $GIT_PUSH "$@" "$UPSTREAM_REMOTE" "$MASTER_BRANCH"
  129. sleep "$PUSH_DELAY"
  130. # shellcheck disable=SC2086
  131. for b in $MAINT_BRANCHES; do
  132. $GIT_PUSH "$@" "$UPSTREAM_REMOTE" "$b"
  133. sleep "$PUSH_DELAY"
  134. done
  135. if [ "$RELEASE_BRANCHES" ]; then
  136. # shellcheck disable=SC2086
  137. $GIT_PUSH "$@" "$UPSTREAM_REMOTE" $RELEASE_BRANCHES
  138. fi
  139. fi