# Part of the Carbon Language project, under the Apache License v2.0 with LLVM # Exceptions. See /LICENSE for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception name: Test setup inputs: matrix_runner: required: true base_sha: required: true remote_cache_key: required: true targets_file: required: true use_direct_targets: default: 'false' outputs: has_code: value: ${{ steps.filter.outputs.has_code}} has_cpp_files: value: ${{ steps.filter.outputs.has_cpp_files}} runs: using: composite steps: # Tests should only run on applicable paths, but we still need to have an # action run for the merge queue. We filter steps based on the paths here, # and condition steps on the output. - id: filter uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 with: filters: | has_code: - '!{**/*.md,LICENSE,CODEOWNERS,.git*}' has_cpp_files: - '{**/*.cpp,**/*.h}' # Disable uploads when the remote cache is read-only. - name: Set up remote cache access (read-only) if: steps.filter.outputs.has_code == 'true' && github.event_name == 'pull_request' shell: bash run: | echo "remote_cache_upload=--remote_upload_local_results=false" \ >> $GITHUB_ENV # Provide a cache key when the remote cache is read-write. - name: Set up remote cache access (read-write) if: steps.filter.outputs.has_code == 'true' && github.event_name != 'pull_request' shell: bash env: REMOTE_CACHE_KEY: ${{ inputs.remote_cache_key }} run: | echo "$REMOTE_CACHE_KEY" | base64 -d > $HOME/remote_cache_key.json echo "remote_cache_upload=--google_credentials=$HOME/remote_cache_key.json" \ >> $GITHUB_ENV - uses: ./.github/actions/build-setup-common if: steps.filter.outputs.has_code == 'true' with: matrix_runner: ${{ inputs.matrix_runner }} remote_cache_upload: ${{ env.remote_cache_upload }} # Just for visibility, print space before and after the build. - name: Disk space before build if: steps.filter.outputs.has_code == 'true' shell: bash run: df -h - name: Verify MODULE.bazel.lock if: steps.filter.outputs.has_code == 'true' shell: bash run: | exit_code=0 ./scripts/run_bazel.py \ --attempts=5 \ mod deps --lockfile_mode=error || exit_code=$? if (( $exit_code != 0 )); then ./scripts/run_bazel.py \ --attempts=5 \ mod deps --lockfile_mode=update echo "MODULE.bazel.lock is out of date! Use below file for update." echo "Platforms may require merging output, for example by applying" echo "an update, re-running triggers, and applying the next update." echo "============================================================" cat MODULE.bazel.lock echo "============================================================" exit 1 fi # Build and run all targets on branch pushes to ensure we always have a # clean tree. We don't expect this to be an interactive path and so don't # optimize the latency of this step. - name: Using all targets for push if: steps.filter.outputs.has_code == 'true' && github.event_name == 'push' shell: bash env: TARGETS_FILE: ${{ inputs.targets_file }} run: | echo "//..." >$TARGETS_FILE # Compute the set of possible rules impacted by this change using # Bazel-based diffing. This lets PRs and the merge queue have a much more # efficient test CI action by avoiding even enumerating (and downloading) # all of the unaffected Bazel targets. - name: Compute indirect pull request targets if: steps.filter.outputs.has_code == 'true' && github.event_name != 'push' && inputs.use_direct_targets != 'true' shell: bash env: # Compute the base SHA from the different event structures. GIT_BASE_SHA: ${{ inputs.base_sha }} TARGETS_FILE: ${{ inputs.targets_file }} run: | # First fetch the relevant base into the git repository. git fetch --depth=1 origin $GIT_BASE_SHA # Do a retried query to try to download things for target-determinator. ./scripts/run_bazel.py --attempts=5 cquery //... > /dev/null # Then use `target-determinator` as wrapped by our script. ./scripts/target_determinator.py $GIT_BASE_SHA >$TARGETS_FILE # Bazel requires a test target to run the test command. There may be # no targets or there may only be non-test targets that we want to # build, so simply inject an explicit no-op test target. echo "//scripts:no_op_test" >> $TARGETS_FILE # Run the query to generate the targets file. - name: Compute direct pull request targets if: steps.filter.outputs.has_code == 'true' && github.event_name != 'push' && inputs.use_direct_targets == 'true' shell: bash env: GIT_BASE_SHA: ${{ inputs.base_sha }} QUERY_FILE: ${{ inputs.targets_file }}.query TARGETS_FILE: ${{ inputs.targets_file }} run: | # First fetch the relevant base into the git repository. git fetch --depth=1 origin $GIT_BASE_SHA # Generate the query file. `same_pkg_direct_rdeps` is used to try to # only get targets that contain modified files as srcs or hdrs (or # similar artifacts). echo 'same_pkg_direct_rdeps(' > $QUERY_FILE # Start with an uninteresting file so that we can `union` below. echo ' scripts/no_op_test.py' >> $QUERY_FILE # Use `union` to join the list of files. Add quotes to defend against # spaces. Note we can filter to the intersection of Carbon extensions # and the supported list at: # https://github.com/erenon/bazel_clang_tidy/blob/master/clang_tidy/clang_tidy.bzl#L65 for f in $(git diff --name-only --diff-filter=d \ $GIT_BASE_SHA -- '**/*.h' '**/*.cpp'); do echo " union '$f'" >> $QUERY_FILE done echo ')' >> $QUERY_FILE # Use query because cquery doesn't support `same_pkg_direct_rdeps`. ./scripts/run_bazel.py \ --attempts=5 \ query --query_file=$QUERY_FILE \ > $TARGETS_FILE