update-go-version.sh 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/bin/bash
  2. # Make updating to a new version of go a bit easier.
  3. #
  4. # Usage:
  5. # scripts/update-go-version.sh 1.21.8
  6. #
  7. # Any actual go package dependency updates should be manually done for
  8. # correctness and safety. Always verify any major dependency updates.
  9. DOCKER=${DOCKER:-docker}
  10. DOCKER_IMAGE_DEBIAN_DISTRO=bullseye
  11. REPO_ROOT_DIR=$(dirname "$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )")
  12. # Update the github actions to use the updated version of go
  13. function update_github_actions() {
  14. local version=$1
  15. local directory=.github/workflows
  16. # Don't cd in and then cd out
  17. (
  18. cd "$directory" || return 1
  19. echo "Updating github actions under $directory"
  20. git grep -l go-version | xargs sed -r -i -e '/go-version/s/:.*$/: "'"${version}"'"/g'
  21. return "${PIPESTATUS[1]}"
  22. )
  23. return $?
  24. }
  25. # Update the documentation on versions of go to use
  26. function update_developer_docs() {
  27. local version=$1
  28. local documents="DEVELOP.md docs/operations.md"
  29. echo "Updating developer docs: $documents"
  30. # shellcheck disable=SC2086
  31. sed -i -e '/golang.org\/dl/s/>= 1\.[0-9]*\.[0-9x]*/>= '"${version}"'/' $documents
  32. return $?
  33. }
  34. # Determine the digest from an image name and tag. This makes builds more
  35. # repeatable as docker tags are mutable and can be changed.
  36. #
  37. # See also: scripts/check-docker-pin.sh
  38. #
  39. function get_docker_image_digest() {
  40. local version="$1"
  41. local image="${2:-docker.io/golang}"
  42. echo "Attempting to pull ${image}:${version} to retrieve the image digest" >&2
  43. # shellcheck disable=SC2155
  44. local digest=$($DOCKER pull "${image}:${version}" | awk '/^Digest:/{print $NF}')
  45. if [[ ${PIPESTATUS[0]} -ne 0 || -z "$digest" ]]; then
  46. echo "WARNING: could not determine digest for ${image}:${version} container image" >&2
  47. return 1
  48. fi
  49. echo "$digest"
  50. }
  51. # Keep go in Dockerfiles for wormhole specific stuff up to date with the latest go
  52. # It is often impossible to update third party Dockerfiles due to the necessity of
  53. # actual code changes to build with newer versions of go or go.mod dependency sad.
  54. function update_our_dockerfiles() {
  55. local version=$1
  56. local image=docker.io/golang
  57. # shellcheck disable=SC2207
  58. local wormhole_dockerfiles=($(git grep -lEi 'FROM.*go(lang)' | grep -Ev '^(wormchain/D|third_party|algorand|terra|docs)'))
  59. # shellcheck disable=SC2155
  60. local digest=$(get_docker_image_digest "$version" "docker.io/golang")
  61. if [[ $? -ne 0 ]] || [[ -z "$digest" ]]; then
  62. echo "WARNING: Problem getting docker image digest" >&2
  63. return 1
  64. fi
  65. for dockerfile in "${wormhole_dockerfiles[@]}"; do
  66. if grep -qEi 'FROM.*go.*alpine' "$dockerfile"; then
  67. echo "WARNING: '$dockerfile' uses alpine and not debian. Please update manually" >&2
  68. continue
  69. fi
  70. # Flag ordering here is important to work correctly on macOS
  71. # with crappy bsd sed and on Linux with more sensible gnu sed.
  72. #
  73. # Also:
  74. # https://xkcd.com/208/
  75. sed -E -i -e '/docker\.io\/golang:/s/(:)[0-9]*\.[0-9]*\.([0-9]|[0-9a-zA-Z-])*(@)sha256:[0-9a-zA-Z-]*( (AS|as)*.*$)?/\1'"$version"'\3'"$digest"'\4/g' "$dockerfile"
  76. # shellcheck disable=SC2181
  77. if [[ $? -ne 0 ]]; then
  78. echo "ERROR: problem updating $dockerfile to ${version}@${digest}" >&2
  79. return 1
  80. fi
  81. if ! grep -q "${image}:${version}@${digest}" "$dockerfile"; then
  82. echo "ERROR: Problem updating $dockerfile to ${version}@${digest}, please manually verify" >&2
  83. return 1
  84. fi
  85. printf "Successfully updated %-38s to %s\n" "$dockerfile" "${image}:${version}@${digest}"
  86. done
  87. }
  88. function update_go_mod() {
  89. local version=$1
  90. (
  91. cd "${REPO_ROOT_DIR}/node" || exit 1
  92. go mod edit -go "$version" -toolchain "go${version}"
  93. # This is mandatory after go mod edit or it refuses to build
  94. go mod tidy
  95. )
  96. return $?
  97. }
  98. function main() {
  99. local version=$1
  100. if [ -z "$version" ]; then
  101. echo -e "ERROR: Missing go version\nUsage:\n\t$0 <GO VERSION>" >&2
  102. exit 1
  103. elif echo "$version" | grep -q ^v; then
  104. echo "ERROR: use explicit semver versions, not a git tag for this script" >&2
  105. exit 1
  106. fi
  107. if ! update_github_actions "$version"; then
  108. echo "ERROR: Problem updating github actions" >&2
  109. exit 1
  110. fi
  111. if ! update_developer_docs "$version"; then
  112. echo "ERROR: Problem updating developer docs" >&2
  113. exit 1
  114. fi
  115. if ! update_our_dockerfiles "${version}-${DOCKER_IMAGE_DEBIAN_DISTRO}"; then
  116. echo "ERROR: Problem updating dockerfiles" >&2
  117. exit 1
  118. fi
  119. if ! update_go_mod "${version}"; then
  120. echo "ERROR: Problem updating dockerfiles" >&2
  121. exit 1
  122. fi
  123. }
  124. main "$@"