tests.yaml 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. # Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. # Exceptions. See /LICENSE for license information.
  3. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. name: test
  5. on:
  6. push:
  7. branches: [trunk]
  8. pull_request_target:
  9. merge_group:
  10. # Cancel previous workflows on the PR when there are multiple fast commits.
  11. # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
  12. concurrency:
  13. group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
  14. cancel-in-progress: true
  15. jobs:
  16. test:
  17. strategy:
  18. matrix:
  19. # At present, these images are newer than "latest". We use them to test
  20. # against more recent tooling versions.
  21. # https://github.com/actions/runner-images
  22. os: [ubuntu-22.04, macos-12]
  23. build_mode: [fastbuild, opt]
  24. runs-on: ${{ matrix.os }}
  25. steps:
  26. # Ubuntu images start with 23GB available, and this adds 14GB more. For
  27. # comparison, MacOS images have >100GB free.
  28. - name: Free up disk space (Ubuntu)
  29. if: matrix.os == 'ubuntu-22.04'
  30. uses: jlumbroso/free-disk-space@v1.2.0
  31. with:
  32. android: true
  33. dotnet: true
  34. haskell: true
  35. # Although we could delete more, if we run into a limit, it provides a
  36. # little flexibility to get space while trying to shrink the build.
  37. # There's also support for docker images at head (1.2.0 is still
  38. # the latest release).
  39. large-packages: false
  40. swap-storage: false
  41. # Checkout the pull request head or the branch.
  42. - name: Checkout pull request
  43. if: github.event_name == 'pull_request_target'
  44. uses: actions/checkout@v3
  45. with:
  46. ref: ${{ github.event.pull_request.head.sha }}
  47. - name: Checkout branch
  48. if: github.event_name != 'pull_request_target'
  49. uses: actions/checkout@v3
  50. # Tests should only run on applicable paths, but we still need to have an
  51. # action run for the merge queue. We filter steps based on the paths here,
  52. # and condition steps on the output.
  53. - id: filter
  54. uses: dorny/paths-filter@v2
  55. with:
  56. filters: |
  57. ignore:
  58. - '**/*.md'
  59. - 'LICENSE'
  60. - 'CODEOWNERS'
  61. - '.git*'
  62. # Setup Python and related tools.
  63. - uses: actions/setup-python@v4
  64. if: steps.filter.outputs.ignore == 'false'
  65. with:
  66. # Match the min version listed in docs/project/contribution_tools.md
  67. python-version: '3.9'
  68. # Use LLVM following:
  69. # https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
  70. # Both 14 and 15 are candidates because GitHub is testing new images.
  71. - name: Setup LLVM and Clang (macOS)
  72. if: steps.filter.outputs.ignore == 'false' && matrix.os == 'macos-12'
  73. run: |
  74. LLVM_PATH="$(brew --prefix llvm@15)"
  75. if [[ ! -e "${LLVM_PATH}" ]]; then
  76. LLVM_PATH="$(brew --prefix llvm@14)"
  77. fi
  78. echo "Using ${LLVM_PATH}"
  79. echo "${LLVM_PATH}/bin" >> $GITHUB_PATH
  80. echo '*** ls "${LLVM_PATH}"'
  81. ls "${LLVM_PATH}"
  82. echo '*** ls "${LLVM_PATH}/bin"'
  83. ls "${LLVM_PATH}/bin"
  84. # Use LLVM following:
  85. # https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md
  86. # Both 14 and 15 are candidates for forwards compatibility, although 15
  87. # isn't provided.
  88. - name: Setup LLVM and Clang (Ubuntu)
  89. if:
  90. steps.filter.outputs.ignore == 'false' && matrix.os == 'ubuntu-22.04'
  91. run: |
  92. # TODO: Re-enable once llvm-15 is working.
  93. # https://github.com/actions/runner-images/issues/8253
  94. # LLVM_PATH="/usr/lib/llvm-15"
  95. # if [[ ! -e "${LLVM_PATH}" ]]; then
  96. LLVM_PATH="/usr/lib/llvm-14"
  97. # fi
  98. echo "Using ${LLVM_PATH}"
  99. echo "${LLVM_PATH}/bin" >> $GITHUB_PATH
  100. echo '*** ls "${LLVM_PATH}"'
  101. ls "${LLVM_PATH}"
  102. echo '*** ls "${LLVM_PATH}/bin"'
  103. ls "${LLVM_PATH}/bin"
  104. # Print the various tool paths and versions to help in debugging.
  105. - name: Print tool debugging info
  106. if: steps.filter.outputs.ignore == 'false'
  107. run: |
  108. echo '*** PATH'
  109. echo $PATH
  110. echo '*** bazelisk'
  111. which bazelisk
  112. bazelisk --version
  113. echo '*** python'
  114. which python
  115. python --version
  116. echo '*** clang'
  117. which clang
  118. clang --version
  119. echo '*** clang++'
  120. which clang++
  121. clang++ --version
  122. # Extract our access key for our build cache.
  123. - name: Extract access key
  124. if: steps.filter.outputs.ignore == 'false'
  125. env:
  126. GCP_BUILDS_SERVICE_ACCOUNT: ${{ secrets.GCP_BUILDS_SERVICE_ACCOUNT }}
  127. run: |
  128. echo "$GCP_BUILDS_SERVICE_ACCOUNT" \
  129. | base64 -d > $HOME/gcp-builds-service-account.json
  130. # We need to replace the `.` with a `_` for the build cache.
  131. - name: Setup LLVM and Clang (macOS)
  132. if: steps.filter.outputs.ignore == 'false' && matrix.os == 'macos-12'
  133. run: |
  134. echo "os_for_cache=macos-12" >> $GITHUB_ENV
  135. - name: Setup LLVM and Clang (Ubuntu)
  136. if:
  137. steps.filter.outputs.ignore == 'false' && matrix.os == 'ubuntu-22.04'
  138. run: |
  139. echo "os_for_cache=ubuntu-22_04" >> $GITHUB_ENV
  140. # Add our bazel configuration and print basic info to ease debugging.
  141. - name: Configure Bazel and print info
  142. if: steps.filter.outputs.ignore == 'false'
  143. env:
  144. # Add a cache version for changes that bazel won't otherwise detect,
  145. # like llvm version changes.
  146. CACHE_VERSION: 1
  147. run: |
  148. cat >user.bazelrc <<EOF
  149. # Enable remote cache for our CI but minimize downloads.
  150. build --remote_cache=https://storage.googleapis.com/carbon-builds-github-v${CACHE_VERSION}-${{ env.os_for_cache }}
  151. build --google_credentials=$HOME/gcp-builds-service-account.json
  152. build --remote_download_minimal
  153. # Set an artificially high jobs count. This flag controls the number
  154. # of concurrency Bazel itself uses, which is essential for actions
  155. # that are internally blocked on for example downloading results form
  156. # the cache above. Without setting this high, Bazel will pick a small
  157. # number based on the available host CPUs and the reality will be a
  158. # long chain of largely serialized download events with little or no
  159. # usage of the host machine. Fortunately, local actions are
  160. # *separately* gated on '--local_*_resources' that will avoid a large
  161. # jobs value overwhelming the host. There is a bug to make downloads
  162. # behave completely asynchronously and remove the need for this filed
  163. # back in 2018 but work seemed to not finish:
  164. # https://github.com/bazelbuild/bazel/issues/6394
  165. #
  166. # There is a new effort (yay!) but until then it seems worth using the
  167. # workaround of a high jobs value. The biggest downside (increased
  168. # heap usage) seems like it isn't currently a big loss for our builds.
  169. #
  170. # Higher values like 50 have led to CI failures with network errors
  171. # and IOExceptions, see
  172. # https://discord.com/channels/655572317891461132/707150492370862090/1151605725576056934
  173. build --jobs=32
  174. # General build options.
  175. build --verbose_failures
  176. test --test_output=errors
  177. EOF
  178. bazelisk info
  179. # Just for visibility, print space before and after the build.
  180. - name: Disk space before build
  181. if: steps.filter.outputs.ignore == 'false'
  182. run: df -h
  183. # Build and run all targets on branch pushes to ensure we always have a
  184. # clean tree. We don't expect this to be an interactive path and so don't
  185. # optimize the latency of this step.
  186. - name: Test (${{ matrix.build_mode }})
  187. if:
  188. steps.filter.outputs.ignore == 'false' && github.event_name == 'push'
  189. env:
  190. # 'libtool_check_unique failed to generate' workaround.
  191. # https://github.com/bazelbuild/bazel/issues/14113#issuecomment-999794586
  192. BAZEL_USE_CPP_ONLY_TOOLCHAIN: 1
  193. run: |
  194. bazelisk test -c ${{ matrix.build_mode }} //...
  195. # Compute the set of possible rules impacted by this change using
  196. # Bazel-based diffing. This lets PRs and the merge queue have a much more
  197. # efficient test CI action by avoiding even enumerating (and downloading)
  198. # all of the unaffected Bazel targets.
  199. - name: Compute impacted pull request targets
  200. if:
  201. steps.filter.outputs.ignore == 'false' && github.event_name != 'push'
  202. env:
  203. # Compute the base SHA from the different event structures.
  204. GIT_BASE_SHA:
  205. ${{ github.event_name == 'pull_request_target' &&
  206. github.event.pull_request.base.sha ||
  207. github.event.merge_group.base_sha }}
  208. TARGETS_FILE: ${{ runner.temp }}/targets
  209. run: |
  210. # First fetch the relevant base into the git repository.
  211. git fetch --depth=1 origin $GIT_BASE_SHA
  212. # Then use `target-determinator` as wrapped by our script.
  213. ./scripts/target_determinator.py $GIT_BASE_SHA >$TARGETS_FILE
  214. # Build and run just the tests impacted by the PR or merge group.
  215. - name: Test (${{ matrix.build_mode }})
  216. if:
  217. steps.filter.outputs.ignore == 'false' && github.event_name != 'push'
  218. env:
  219. # 'libtool_check_unique failed to generate' workaround.
  220. # https://github.com/bazelbuild/bazel/issues/14113#issuecomment-999794586
  221. BAZEL_USE_CPP_ONLY_TOOLCHAIN: 1
  222. TARGETS_FILE: ${{ runner.temp }}/targets
  223. run: |
  224. # Bazel requires a test target to run the test command. There may be
  225. # no targets or there may only be non-test targets that we want to
  226. # build, so simply inject an explicit no-op test target.
  227. echo "//scripts:no_op_test" >> $TARGETS_FILE
  228. bazelisk test -c ${{ matrix.build_mode }} \
  229. --target_pattern_file=$TARGETS_FILE
  230. # See "Disk space before build".
  231. - name: Disk space after build
  232. if: steps.filter.outputs.ignore == 'false'
  233. run: df -h