cut.sh 7.7 KB

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