grpc_publish_packages.sh 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #!/bin/bash
  2. # Copyright 2018 The gRPC Authors
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. set -ex
  16. shopt -s nullglob
  17. cd "$(dirname "$0")/../../.."
  18. GRPC_VERSION=$(grep -e "^ *version: " build_handwritten.yaml | head -n 1 | sed 's/.*: //')
  19. INPUT_ARTIFACTS=$KOKORO_GFILE_DIR/github/grpc/artifacts
  20. INDEX_FILENAME=index.xml
  21. BUILD_ID=${KOKORO_BUILD_ID:-$(uuidgen)}
  22. BUILD_BRANCH_NAME=master
  23. BUILD_GIT_COMMIT=${KOKORO_GIT_COMMIT:-unknown}
  24. BUILD_TIMESTAMP=$(date -Iseconds)
  25. BUILD_RELPATH=$(date "+%Y/%m")/$BUILD_GIT_COMMIT-$BUILD_ID/
  26. GCS_ROOT=gs://packages.grpc.io/
  27. GCS_ARCHIVE_PREFIX=archive/
  28. GCS_ARCHIVE_ROOT=$GCS_ROOT$GCS_ARCHIVE_PREFIX
  29. GCS_INDEX=$GCS_ROOT$INDEX_FILENAME
  30. LOCAL_STAGING_TEMPDIR=$(mktemp -d)
  31. LOCAL_BUILD_ROOT=$LOCAL_STAGING_TEMPDIR/$BUILD_RELPATH
  32. LOCAL_BUILD_INDEX=$LOCAL_BUILD_ROOT$INDEX_FILENAME
  33. mkdir -p "$LOCAL_BUILD_ROOT"
  34. find "$INPUT_ARTIFACTS" -type f
  35. # protoc Plugins
  36. PROTOC_PLUGINS_ZIPPED_PACKAGES=$(mktemp -d)
  37. for zip_dir in protoc_windows_{x86,x64}
  38. do
  39. zip -jr "$PROTOC_PLUGINS_ZIPPED_PACKAGES/grpc-$zip_dir-$GRPC_VERSION.zip" "$INPUT_ARTIFACTS/$zip_dir/"*
  40. done
  41. for tar_dir in protoc_linux_{x86,x64} protoc_macos_x64
  42. do
  43. chmod +x "$INPUT_ARTIFACTS/$tar_dir"/*
  44. tar -cvzf "$PROTOC_PLUGINS_ZIPPED_PACKAGES/grpc-$tar_dir-$GRPC_VERSION.tar.gz" -C "$INPUT_ARTIFACTS/$tar_dir" .
  45. done
  46. PROTOC_PACKAGES=(
  47. "$PROTOC_PLUGINS_ZIPPED_PACKAGES"/grpc-protoc_windows_{x86,x64}-"$GRPC_VERSION.zip"
  48. "$PROTOC_PLUGINS_ZIPPED_PACKAGES"/grpc-protoc_linux_{x86,x64}-"$GRPC_VERSION.tar.gz"
  49. "$PROTOC_PLUGINS_ZIPPED_PACKAGES"/grpc-protoc_macos_x64-"$GRPC_VERSION.tar.gz"
  50. )
  51. # C#
  52. UNZIPPED_CSHARP_PACKAGES=$(mktemp -d)
  53. unzip "$INPUT_ARTIFACTS/csharp_nugets_windows_dotnetcli.zip" -d "$UNZIPPED_CSHARP_PACKAGES"
  54. CSHARP_PACKAGES=(
  55. "$UNZIPPED_CSHARP_PACKAGES"/*
  56. "$INPUT_ARTIFACTS"/grpc_unity_package.[0-9]*.zip
  57. )
  58. # Python
  59. PYTHON_GRPCIO_PACKAGES=(
  60. "$INPUT_ARTIFACTS"/grpcio-[0-9]*.tar.gz
  61. "$INPUT_ARTIFACTS"/grpcio-[0-9]*.whl
  62. "$INPUT_ARTIFACTS"/python_linux_extra_arm*/grpcio-[0-9]*.whl
  63. )
  64. PYTHON_GRPCIO_TOOLS_PACKAGES=(
  65. "$INPUT_ARTIFACTS"/grpcio-tools-[0-9]*.tar.gz
  66. "$INPUT_ARTIFACTS"/grpcio_tools-[0-9]*.whl
  67. "$INPUT_ARTIFACTS"/python_linux_extra_arm*/grpcio_tools-[0-9]*.whl
  68. )
  69. PYTHON_GRPCIO_HEALTH_CHECKING_PACKAGES=(
  70. "$INPUT_ARTIFACTS"/grpcio-health-checking-[0-9]*.tar.gz
  71. )
  72. PYTHON_GRPCIO_REFLECTION_PACKAGES=(
  73. "$INPUT_ARTIFACTS"/grpcio-reflection-[0-9]*.tar.gz
  74. )
  75. PYTHON_GRPCIO_TESTING_PACKAGES=(
  76. "$INPUT_ARTIFACTS"/grpcio-testing-[0-9]*.tar.gz
  77. )
  78. # PHP
  79. PHP_PACKAGES=(
  80. "$INPUT_ARTIFACTS"/grpc-[0-9]*.tgz
  81. )
  82. # Ruby
  83. RUBY_PACKAGES=(
  84. "$INPUT_ARTIFACTS"/grpc-[0-9]*.gem
  85. "$INPUT_ARTIFACTS"/grpc-tools-[0-9]*.gem
  86. )
  87. function add_to_manifest() {
  88. local artifact_type=$1
  89. local artifact_file=$2
  90. local artifact_prefix=$3
  91. local artifact_name
  92. artifact_name=$(basename "$artifact_file")
  93. local artifact_size
  94. artifact_size=$(stat -c%s "$artifact_file")
  95. local artifact_sha256
  96. artifact_sha256=$(openssl sha256 -r "$artifact_file" | cut -d " " -f 1)
  97. local artifact_target=$LOCAL_BUILD_ROOT/$artifact_type/$artifact_prefix
  98. mkdir -p "$artifact_target"
  99. cp "$artifact_file" "$artifact_target"
  100. cat <<EOF
  101. <artifact name='$artifact_name'
  102. type='$artifact_type'
  103. path='$artifact_type/$artifact_prefix$artifact_name'
  104. size='$artifact_size'
  105. sha256='$artifact_sha256' />
  106. EOF
  107. }
  108. {
  109. cat <<EOF
  110. <?xml version="1.0"?>
  111. <?xml-stylesheet href="/web-assets/build-201807.xsl" type="text/xsl"?>
  112. <build id='$BUILD_ID' timestamp='$BUILD_TIMESTAMP' version="201807">
  113. <metadata>
  114. <project>gRPC</project>
  115. <repository>https://github.com/grpc/grpc</repository>
  116. <branch>$BUILD_BRANCH_NAME</branch>
  117. <commit>$BUILD_GIT_COMMIT</commit>
  118. </metadata>
  119. <artifacts>
  120. EOF
  121. for pkg in "${PROTOC_PACKAGES[@]}"; do add_to_manifest protoc "$pkg"; done
  122. for pkg in "${CSHARP_PACKAGES[@]}"; do add_to_manifest csharp "$pkg"; done
  123. for pkg in "${PHP_PACKAGES[@]}"; do add_to_manifest php "$pkg"; done
  124. for pkg in "${PYTHON_GRPCIO_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio/; done
  125. for pkg in "${PYTHON_GRPCIO_TOOLS_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-tools/; done
  126. for pkg in "${PYTHON_GRPCIO_HEALTH_CHECKING_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-health-checking/; done
  127. for pkg in "${PYTHON_GRPCIO_REFLECTION_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-reflection/; done
  128. for pkg in "${PYTHON_GRPCIO_TESTING_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-testing/; done
  129. for pkg in "${RUBY_PACKAGES[@]}"; do add_to_manifest ruby "$pkg"; done
  130. cat <<EOF
  131. </artifacts>
  132. </build>
  133. EOF
  134. }> "$LOCAL_BUILD_INDEX"
  135. LOCAL_BUILD_INDEX_SIZE=$(stat -c%s "$LOCAL_BUILD_INDEX")
  136. LOCAL_BUILD_INDEX_SHA256=$(openssl sha256 -r "$LOCAL_BUILD_INDEX" | cut -d " " -f 1)
  137. OLD_INDEX=$(mktemp)
  138. NEW_INDEX=$(mktemp)
  139. # Download the current /index.xml into $OLD_INDEX
  140. gsutil cp "$GCS_INDEX" "$OLD_INDEX"
  141. {
  142. # we want to add an entry as the first child under <builds> tag
  143. # we can get by without a real XML parser by rewriting the header,
  144. # injecting our new tag, and then dumping the rest of the file as is.
  145. cat <<EOF
  146. <?xml version="1.0"?>
  147. <?xml-stylesheet href="/web-assets/home.xsl" type="text/xsl"?>
  148. <packages>
  149. <builds>
  150. <build id='$BUILD_ID'
  151. timestamp='$BUILD_TIMESTAMP'
  152. branch='$BUILD_BRANCH_NAME'
  153. commit='$BUILD_GIT_COMMIT'
  154. path='$GCS_ARCHIVE_PREFIX$BUILD_RELPATH$INDEX_FILENAME'
  155. size='$LOCAL_BUILD_INDEX_SIZE'
  156. sha256='$LOCAL_BUILD_INDEX_SHA256' />
  157. EOF
  158. tail --lines=+5 "$OLD_INDEX"
  159. }> "$NEW_INDEX"
  160. function generate_directory_index()
  161. {
  162. local target_dir=$1
  163. local current_directory_name
  164. current_directory_name=$(basename "$target_dir")
  165. cat <<EOF
  166. <!DOCTYPE html>
  167. <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
  168. <head>
  169. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  170. <title>Index of $current_directory_name - packages.grpc.io</title>
  171. <link rel="stylesheet" type="text/css" href="/web-assets/dirindex.css" />
  172. </head>
  173. <body>
  174. <h1>Index of <a href="#"><code>$current_directory_name</code></a></h1>
  175. <ul>
  176. <li><a href="#">.</a></li>
  177. <li><a href="..">..</a></li>
  178. EOF
  179. (
  180. cd "$target_dir"
  181. find * -maxdepth 0 -type d -print | sort | while read -r line
  182. do
  183. echo " <li><a href='$line/'>$line/</a></li>"
  184. done
  185. find * -maxdepth 0 -type f -print | sort | while read -r line
  186. do
  187. echo " <li><a href='$line'>$line</a></li>"
  188. done
  189. )
  190. cat <<EOF
  191. </ul>
  192. </body>
  193. </html>
  194. EOF
  195. }
  196. # Upload the current build artifacts
  197. gsutil -m cp -r "$LOCAL_STAGING_TEMPDIR/${BUILD_RELPATH%%/*}" "$GCS_ARCHIVE_ROOT"
  198. # Upload directory indices for subdirectories
  199. (
  200. cd "$LOCAL_BUILD_ROOT"
  201. find * -type d | while read -r directory
  202. do
  203. generate_directory_index "$directory" | gsutil -h 'Content-Type:text/html' cp - "$GCS_ARCHIVE_ROOT$BUILD_RELPATH$directory/$INDEX_FILENAME"
  204. done
  205. )
  206. # Upload the new /index.xml
  207. gsutil -h "Content-Type:application/xml" cp "$NEW_INDEX" "$GCS_INDEX"
  208. # Upload C# nugets to the dev nuget feed
  209. pushd "$UNZIPPED_CSHARP_PACKAGES"
  210. docker pull mcr.microsoft.com/dotnet/core/sdk:2.1
  211. for nugetfile in *.nupkg
  212. do
  213. echo "Going to push $nugetfile"
  214. # use nuget from a docker container to push the nupkg
  215. set +x # IMPORTANT: avoid revealing the nuget api key by the command echo
  216. docker run -v "$(pwd):/nugets:ro" --rm=true mcr.microsoft.com/dotnet/core/sdk:2.1 bash -c "dotnet nuget push /nugets/$nugetfile -k $(cat ${KOKORO_GFILE_DIR}/artifactory_grpc_nuget_dev_api_key) --source https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev"
  217. set -ex
  218. done
  219. popd