utils.sh 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. # Modified from https://gitlab.com/gitlab-org/gitlab/-/blob/master/scripts/utils.sh
  2. function add_ssh_keys() {
  3. local key_string="${1}"
  4. mkdir -p ~/.ssh
  5. chmod 700 ~/.ssh
  6. echo -n "${key_string}" >~/.ssh/id_rsa_base64
  7. base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 >~/.ssh/id_rsa
  8. chmod 600 ~/.ssh/id_rsa
  9. }
  10. function add_gitlab_ssh_keys() {
  11. add_ssh_keys "${GITLAB_KEY}"
  12. echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >>~/.ssh/config
  13. # For gitlab geo nodes
  14. if [ "${LOCAL_GITLAB_SSH_SERVER:-}" ]; then
  15. SRV=${LOCAL_GITLAB_SSH_SERVER##*@} # remove the chars before @, which is the account
  16. SRV=${SRV%%:*} # remove the chars after :, which is the port
  17. printf "Host %s\n\tStrictHostKeyChecking no\n" "${SRV}" >>~/.ssh/config
  18. fi
  19. }
  20. function add_github_ssh_keys() {
  21. add_ssh_keys "${GH_PUSH_KEY}"
  22. echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >>~/.ssh/config
  23. }
  24. function add_doc_server_ssh_keys() {
  25. local key_string="${1}"
  26. local server_url="${2}"
  27. local server_user="${3}"
  28. add_ssh_keys "${key_string}"
  29. echo -e "Host ${server_url}\n\tStrictHostKeyChecking no\n\tUser ${server_user}\n" >>~/.ssh/config
  30. }
  31. function fetch_submodules() {
  32. python "${SUBMODULE_FETCH_TOOL}" -s "${SUBMODULES_TO_FETCH}"
  33. }
  34. function get_all_submodules() {
  35. git config --file .gitmodules --get-regexp path | awk '{ print $2 }' | sed -e 's|$|/**|' | xargs | sed -e 's/ /,/g'
  36. }
  37. function set_component_ut_vars() {
  38. local exclude_list_fp="${IDF_PATH}/tools/ci/component_ut_excludes.txt"
  39. export COMPONENT_UT_DIRS=$(find components/ -name test_apps -type d | xargs)
  40. export COMPONENT_UT_EXCLUDES=$([ -r $exclude_list_fp ] && cat $exclude_list_fp | xargs)
  41. echo "exported variables COMPONENT_UT_DIRS, COMPONENT_UT_EXCLUDES"
  42. }
  43. function upload_artifacts_to_s3() {
  44. # for detailed documents, please refer to .gitlab/ci/README.md#uploaddownload-artifacts-to-internal-minio-server
  45. python tools/ci/artifacts_handler.py upload
  46. }
  47. function error() {
  48. printf "\033[0;31m%s\n\033[0m" "${1}" >&2
  49. }
  50. function info() {
  51. printf "\033[0;32m%s\n\033[0m" "${1}" >&2
  52. }
  53. function warning() {
  54. printf "\033[0;33m%s\n\033[0m" "${1}" >&2
  55. }
  56. function run_cmd() {
  57. local cmd="$*"
  58. local start=$(date +%s)
  59. info "\$ ${cmd}"
  60. eval "${cmd}"
  61. local ret=$?
  62. local end=$(date +%s)
  63. local runtime=$((end-start))
  64. if [[ $ret -eq 0 ]]; then
  65. info "==> '\$ ${cmd}' succeeded in ${runtime} seconds."
  66. return 0
  67. else
  68. error "==> '\$ ${cmd}' failed (${ret}) in ${runtime} seconds."
  69. return $ret
  70. fi
  71. }
  72. # Retries a command RETRY_ATTEMPTS times in case of failure
  73. # Inspired by https://stackoverflow.com/a/8351489
  74. function retry_failed() {
  75. local max_attempts=${RETRY_ATTEMPTS-3}
  76. local timeout=${RETRY_TIMEWAIT-1}
  77. local attempt=1
  78. local exitCode=0
  79. whole_start=$(date +%s)
  80. while true; do
  81. if run_cmd "$@"; then
  82. exitCode=0
  83. break
  84. else
  85. exitCode=$?
  86. fi
  87. if ((attempt >= max_attempts)); then
  88. break
  89. fi
  90. error "Retrying in ${timeout} seconds..."
  91. sleep $timeout
  92. attempt=$((attempt + 1))
  93. timeout=$((timeout * 2))
  94. done
  95. local duration=$(($(date '+%s') - whole_start))
  96. if [[ $exitCode != 0 ]]; then
  97. error "Totally failed! Spent $duration sec in total"
  98. else
  99. info "Done! Spent $duration sec in total"
  100. fi
  101. return $exitCode
  102. }
  103. function join_by {
  104. local d=${1-} f=${2-}
  105. if shift 2; then
  106. printf %s "$f" "${@/#/$d}"
  107. fi
  108. }
  109. function is_based_on_commits() {
  110. # This function would accept space-separated args as multiple commits.
  111. # The return value would be 0 if current HEAD is based on any of the specified commits.
  112. #
  113. # In our CI, we use environment variable $REQUIRED_ANCESTOR_COMMITS to declare the ancestor commits.
  114. # Please remember to set one commit for each release branch.
  115. commits=$*
  116. if [[ -z $commits ]]; then
  117. info "Not specifying commits that branches should be based on, skipping check..."
  118. return 0
  119. fi
  120. commits_str="$(join_by " or " $commits)" # no doublequotes here, passing array
  121. info "Checking if current branch is based on $commits_str..."
  122. for i in $commits; do
  123. if git merge-base --is-ancestor "$i" HEAD >/dev/null 2>&1; then
  124. info "Current branch is based on $i"
  125. return 0
  126. else
  127. info "Current branch is not based on $i"
  128. fi
  129. done
  130. error "The base commit of your branch is too old."
  131. error "The branch should be more recent than either of the following commits:"
  132. error " $commits_str"
  133. error "To fix the issue:"
  134. error " - If your merge request is 'Draft', or has conflicts with the target branch, rebase it to the latest master or release branch"
  135. error " - Otherwise, simply run a new pipeline."
  136. return 1
  137. }