cut.sh 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #!/usr/bin/env bash
  2. ## cut a new 5.x release for EMQX (opensource or enterprise).
  3. set -euo pipefail
  4. if [ "${DEBUG:-}" = 1 ]; then
  5. set -x
  6. fi
  7. # ensure dir
  8. cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
  9. usage() {
  10. cat <<EOF
  11. $0 RELEASE_GIT_TAG [option]
  12. RELEASE_GIT_TAG is a 'v*' or 'e*' tag for example:
  13. v5.0.12
  14. e5.0.0-beta.6
  15. options:
  16. -h|--help: Print this usage.
  17. -b|--base: Specify the current release base branch, can be one of
  18. release-50
  19. NOTE: this option should be used when --dryrun.
  20. --dryrun: Do not actually create the git tag.
  21. --skip-appup: Skip checking appup
  22. Useful when you are sure that appup is already updated'
  23. --prev-tag: Provide the prev tag to automatically generate changelogs
  24. If this option is absent, the tag found by git describe will be used
  25. NOTE: For 5.0 series the current working branch must be 'release-50' for opensource edition
  26. and 'release-e50' for enterprise edition.
  27. --.--[ master ]---------------------------.-----------.---
  28. \\ /
  29. \`---[release-50]----(v5.0.12 | e5.0.0)
  30. EOF
  31. }
  32. logerr() {
  33. echo "$(tput setaf 1)ERROR: $1$(tput sgr0)"
  34. }
  35. logmsg() {
  36. echo "INFO: $1"
  37. }
  38. TAG="${1:-}"
  39. case "$TAG" in
  40. v*)
  41. TAG_PREFIX='v'
  42. PROFILE='emqx'
  43. SKIP_APPUP='yes'
  44. ;;
  45. e*)
  46. TAG_PREFIX='e'
  47. PROFILE='emqx-enterprise'
  48. #TODO change to no when we are ready to support hot-upgrade
  49. SKIP_APPUP='yes'
  50. ;;
  51. -h|--help)
  52. usage
  53. exit 0
  54. ;;
  55. *)
  56. logerr "Unknown version tag $TAG"
  57. usage
  58. exit 1
  59. ;;
  60. esac
  61. shift 1
  62. DRYRUN='no'
  63. while [ "$#" -gt 0 ]; do
  64. case $1 in
  65. -h|--help)
  66. usage
  67. exit 0
  68. ;;
  69. --skip-appup)
  70. shift
  71. SKIP_APPUP='yes'
  72. ;;
  73. --dryrun)
  74. shift
  75. DRYRUN='yes'
  76. ;;
  77. -b|--base)
  78. BASE_BR="${2:-}"
  79. if [ -z "${BASE_BR}" ]; then
  80. logerr "Must specify which base branch"
  81. exit 1
  82. fi
  83. shift 2
  84. ;;
  85. --prev-tag)
  86. shift
  87. PREV_TAG="$1"
  88. shift
  89. ;;
  90. *)
  91. logerr "Unknown option $1"
  92. exit 1
  93. ;;
  94. esac
  95. done
  96. rel_branch() {
  97. local tag="$1"
  98. case "$tag" in
  99. v5.0.*)
  100. echo 'release-50'
  101. ;;
  102. e5.0.*)
  103. echo 'release-50'
  104. ;;
  105. *)
  106. logerr "Unsupported version tag $TAG"
  107. exit 1
  108. ;;
  109. esac
  110. }
  111. ## Ensure the current work branch
  112. assert_work_branch() {
  113. local tag="$1"
  114. local release_branch
  115. release_branch="$(rel_branch "$tag")"
  116. local base_branch
  117. base_branch="${BASE_BR:-$(git branch --show-current)}"
  118. if [ "$base_branch" != "$release_branch" ]; then
  119. logerr "Base branch: $base_branch"
  120. logerr "Relase tag must be on the release branch: $release_branch"
  121. logerr "or must use -b|--base option to specify which release branch is current branch based on"
  122. exit 1
  123. fi
  124. }
  125. assert_work_branch "$TAG"
  126. ## Ensure no dirty changes
  127. assert_not_dirty() {
  128. local diff
  129. diff="$(git diff --name-only)"
  130. if [ -n "$diff" ]; then
  131. logerr "Git status is not clean? Changed files:"
  132. logerr "$diff"
  133. exit 1
  134. fi
  135. }
  136. assert_not_dirty
  137. ## Assert that the tag is not already created
  138. assert_tag_absent() {
  139. local tag="$1"
  140. ## Fail if the tag already exists
  141. EXISTING="$(git tag --list "$tag")"
  142. if [ -n "$EXISTING" ]; then
  143. logerr "$tag already released?"
  144. logerr 'This script refuse to force re-tag.'
  145. logerr 'If re-tag is intended, you must first delete the tag from both local and remote'
  146. exit 1
  147. fi
  148. }
  149. assert_tag_absent "$TAG"
  150. PKG_VSN=$(./pkg-vsn.sh "$PROFILE")
  151. ## Assert package version is updated to the tag which is being created
  152. assert_release_version() {
  153. local tag="$1"
  154. # shellcheck disable=SC2001
  155. pkg_vsn="$(echo "$PKG_VSN" | sed 's/-g[0-9a-f]\{8\}$//g')"
  156. if [ "${TAG_PREFIX}${pkg_vsn}" != "${tag}" ]; then
  157. logerr "The release version ($pkg_vsn) is different from the desired git tag."
  158. logerr "Update the release version in emqx_release.hrl"
  159. exit 1
  160. fi
  161. }
  162. assert_release_version "$TAG"
  163. ## Check if all upstream branches are merged
  164. if [ -z "${BASE_BR:-}" ]; then
  165. ./scripts/rel/sync-remotes.sh
  166. else
  167. ./scripts/rel/sync-remotes.sh --base "$BASE_BR"
  168. fi
  169. ## Check if the Chart versions are in sync
  170. ./scripts/rel/check-chart-vsn.sh "$PROFILE"
  171. ## Check if app versions are bumped
  172. ./scripts/apps-version-check.sh
  173. ## Ensure appup files are updated
  174. if [ "$SKIP_APPUP" = 'no' ]; then
  175. logmsg "Checking appups"
  176. ./scripts/update-appup.sh "$PROFILE" --check
  177. else
  178. logmsg "Skipped checking appup updates"
  179. fi
  180. ## Ensure relup paths are updated
  181. ## TODO: add relup path db
  182. #./scripts/relup-base-vsns.escript check-vsn-db "$PKG_VSN" "$RELUP_PATHS"
  183. ## Run some additional checks (e.g. some for enterprise edition only)
  184. CHECKS_DIR="./scripts/rel/checks"
  185. if [ -d "${CHECKS_DIR}" ]; then
  186. CHECKS="$(find "${CHECKS_DIR}" -name "*.sh" -print0 2>/dev/null | xargs -0)"
  187. for c in $CHECKS; do
  188. logmsg "Executing $c"
  189. $c
  190. done
  191. fi
  192. generate_changelog () {
  193. local from_tag="${PREV_TAG:-}"
  194. if [[ -z $from_tag ]]; then
  195. if [ $PROFILE == "emqx" ]; then
  196. from_tag="$(git describe --tags --abbrev=0 --match 'v*')"
  197. else
  198. from_tag="$(git describe --tags --abbrev=0 --match 'e*')"
  199. fi
  200. fi
  201. local output_dir="changes"
  202. ./scripts/format-changelog.sh $PROFILE "${from_tag}" "${TAG}" $output_dir
  203. git add $output_dir
  204. [ -n "$(git status -s)" ] && git commit -m "chore: Generate changelog for ${TAG}"
  205. }
  206. if [ "$DRYRUN" = 'yes' ]; then
  207. logmsg "Release tag is ready to be created with command: git tag $TAG"
  208. else
  209. case "$TAG" in
  210. *rc*)
  211. true
  212. ;;
  213. *alpha*)
  214. true
  215. ;;
  216. *beta*)
  217. true
  218. ;;
  219. e5.0.0*)
  220. # the first release has no change log
  221. true
  222. ;;
  223. *)
  224. generate_changelog
  225. ;;
  226. esac
  227. git tag "$TAG"
  228. logmsg "$TAG is created OK."
  229. fi