action.yml 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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 setup
  5. inputs:
  6. matrix_runner:
  7. required: true
  8. base_sha:
  9. required: true
  10. remote_cache_key:
  11. required: true
  12. targets_file:
  13. required: true
  14. use_direct_targets:
  15. default: 'false'
  16. outputs:
  17. has_code:
  18. value: ${{ steps.filter.outputs.has_code}}
  19. has_cpp_files:
  20. value: ${{ steps.filter.outputs.has_cpp_files}}
  21. runs:
  22. using: composite
  23. steps:
  24. # Tests should only run on applicable paths, but we still need to have an
  25. # action run for the merge queue. We filter steps based on the paths here,
  26. # and condition steps on the output.
  27. - id: filter
  28. uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
  29. with:
  30. filters: |
  31. has_code:
  32. - '!{**/*.md,LICENSE,CODEOWNERS,.git*}'
  33. has_cpp_files:
  34. - '{**/*.cpp,**/*.h}'
  35. # Disable uploads when the remote cache is read-only.
  36. - name: Set up remote cache access (read-only)
  37. if:
  38. steps.filter.outputs.has_code == 'true' && github.event_name ==
  39. 'pull_request'
  40. shell: bash
  41. run: |
  42. echo "remote_cache_upload=--remote_upload_local_results=false" \
  43. >> $GITHUB_ENV
  44. # Provide a cache key when the remote cache is read-write.
  45. - name: Set up remote cache access (read-write)
  46. if:
  47. steps.filter.outputs.has_code == 'true' && github.event_name !=
  48. 'pull_request'
  49. shell: bash
  50. env:
  51. REMOTE_CACHE_KEY: ${{ inputs.remote_cache_key }}
  52. run: |
  53. echo "$REMOTE_CACHE_KEY" | base64 -d > $HOME/remote_cache_key.json
  54. echo "remote_cache_upload=--google_credentials=$HOME/remote_cache_key.json" \
  55. >> $GITHUB_ENV
  56. - uses: ./.github/actions/build-setup-common
  57. if: steps.filter.outputs.has_code == 'true'
  58. with:
  59. matrix_runner: ${{ inputs.matrix_runner }}
  60. remote_cache_upload: ${{ env.remote_cache_upload }}
  61. # Just for visibility, print space before and after the build.
  62. - name: Disk space before build
  63. if: steps.filter.outputs.has_code == 'true'
  64. shell: bash
  65. run: df -h
  66. - name: Verify MODULE.bazel.lock
  67. if: steps.filter.outputs.has_code == 'true'
  68. shell: bash
  69. run: |
  70. exit_code=0
  71. ./scripts/run_bazel.py \
  72. --attempts=5 \
  73. mod deps --lockfile_mode=error || exit_code=$?
  74. if (( $exit_code != 0 )); then
  75. ./scripts/run_bazel.py \
  76. --attempts=5 \
  77. mod deps --lockfile_mode=update
  78. echo "MODULE.bazel.lock is out of date! Use below file for update."
  79. echo "Platforms may require merging output, for example by applying"
  80. echo "an update, re-running triggers, and applying the next update."
  81. echo "============================================================"
  82. cat MODULE.bazel.lock
  83. echo "============================================================"
  84. exit 1
  85. fi
  86. # Build and run all targets on branch pushes to ensure we always have a
  87. # clean tree. We don't expect this to be an interactive path and so don't
  88. # optimize the latency of this step.
  89. - name: Using all targets for push
  90. if: steps.filter.outputs.has_code == 'true' && github.event_name == 'push'
  91. shell: bash
  92. env:
  93. TARGETS_FILE: ${{ inputs.targets_file }}
  94. run: |
  95. echo "//..." >$TARGETS_FILE
  96. # Compute the set of possible rules impacted by this change using
  97. # Bazel-based diffing. This lets PRs and the merge queue have a much more
  98. # efficient test CI action by avoiding even enumerating (and downloading)
  99. # all of the unaffected Bazel targets.
  100. - name: Compute indirect pull request targets
  101. if:
  102. steps.filter.outputs.has_code == 'true' && github.event_name != 'push'
  103. && inputs.use_direct_targets != 'true'
  104. shell: bash
  105. env:
  106. # Compute the base SHA from the different event structures.
  107. GIT_BASE_SHA: ${{ inputs.base_sha }}
  108. TARGETS_FILE: ${{ inputs.targets_file }}
  109. run: |
  110. # First fetch the relevant base into the git repository.
  111. git fetch --depth=1 origin $GIT_BASE_SHA
  112. # Do a retried query to try to download things for target-determinator.
  113. ./scripts/run_bazel.py --attempts=5 cquery //... > /dev/null
  114. # Then use `target-determinator` as wrapped by our script.
  115. ./scripts/target_determinator.py $GIT_BASE_SHA >$TARGETS_FILE
  116. # Bazel requires a test target to run the test command. There may be
  117. # no targets or there may only be non-test targets that we want to
  118. # build, so simply inject an explicit no-op test target.
  119. echo "//scripts:no_op_test" >> $TARGETS_FILE
  120. # Run the query to generate the targets file.
  121. - name: Compute direct pull request targets
  122. if:
  123. steps.filter.outputs.has_code == 'true' && github.event_name != 'push'
  124. && inputs.use_direct_targets == 'true'
  125. shell: bash
  126. env:
  127. GIT_BASE_SHA: ${{ inputs.base_sha }}
  128. QUERY_FILE: ${{ inputs.targets_file }}.query
  129. TARGETS_FILE: ${{ inputs.targets_file }}
  130. run: |
  131. # First fetch the relevant base into the git repository.
  132. git fetch --depth=1 origin $GIT_BASE_SHA
  133. # Generate the query file. `same_pkg_direct_rdeps` is used to try to
  134. # only get targets that contain modified files as srcs or hdrs (or
  135. # similar artifacts).
  136. echo 'same_pkg_direct_rdeps(' > $QUERY_FILE
  137. # Start with an uninteresting file so that we can `union` below.
  138. echo ' scripts/no_op_test.py' >> $QUERY_FILE
  139. # Use `union` to join the list of files. Add quotes to defend against
  140. # spaces. Note we can filter to the intersection of Carbon extensions
  141. # and the supported list at:
  142. # https://github.com/erenon/bazel_clang_tidy/blob/master/clang_tidy/clang_tidy.bzl#L65
  143. for f in $(git diff --name-only --diff-filter=d \
  144. $GIT_BASE_SHA -- '**/*.h' '**/*.cpp'); do
  145. echo " union '$f'" >> $QUERY_FILE
  146. done
  147. echo ')' >> $QUERY_FILE
  148. # Use query because cquery doesn't support `same_pkg_direct_rdeps`.
  149. ./scripts/run_bazel.py \
  150. --attempts=5 \
  151. query --query_file=$QUERY_FILE \
  152. > $TARGETS_FILE