chore: don't kick off github actions jobs for unchanged nested Bazel modules #1168
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Configure plain GitHub Actions to run `bazel` commands on PRs to main as well as commits landed on main. | |
# This demonstrates one way to do Continuous Integration. | |
# | |
# Aspect Workflows is a more feature-rich, powerful, and cheaper approach. | |
# See the configuration in /.aspect/workflows for how that CI/CD system is configured. | |
name: CI | |
# Controls when the action will run. | |
on: | |
# Triggers the workflow on push or pull request events but only for the main branch | |
push: | |
branches: [main] | |
pull_request: | |
branches: [main] | |
# Allows you to run this workflow manually from the Actions tab | |
workflow_dispatch: | |
jobs: | |
# matrix-prep-* jobs dynamically generate a bit of JSON which we read later to construct a matrix of test jobs | |
matrix-prep-os: | |
# Prepares the 'os' axis of the test matrix | |
runs-on: ubuntu-latest | |
steps: | |
- id: linux | |
run: echo "os=ubuntu-latest" >> $GITHUB_OUTPUT | |
- id: macos | |
run: echo "os=macos-latest" >> $GITHUB_OUTPUT | |
# Only run on main branch (not PRs) to minimize macOS minutes (billed at 10X) | |
# https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes | |
if: ${{ github.ref == 'refs/heads/main' }} | |
outputs: | |
# Will look like ["ubuntu-latest", "macos-latest"] | |
os: ${{ toJSON(steps.*.outputs.os) }} | |
# The goal of this matrix prep is to determine whether nested Bazel modules need to be tested. | |
# When they do, we create a separate "matrix" job so they are tested in parallel with the root module. | |
matrix-prep-folder: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
# Clone the last two commits, so we can see what files were changed. | |
fetch-depth: 2 | |
# Get a list of nested Bazel modules that were touched | |
- uses: tj-actions/changed-files@v45 | |
with: | |
# Just print the top-level directory names | |
dir_names: true | |
dir_names_max_depth: 1 | |
# NB: this list must match all files that live within a nested Bazel module. | |
# Should match the /.bazelignore file as well. | |
files: | | |
angular/** | |
angular-ngc/** | |
jest/** | |
bzlmod/** | |
check-npm-determinism/** | |
directory_path/** | |
eager-fetch/** | |
git_push/** | |
go_workspaces/** | |
jest/** | |
nestjs/** | |
oci_go_image/** | |
oci_python_image/** | |
pnpm-workspaces/** | |
prisma/** | |
bufbuild/** | |
rules_nodejs_to_rules_js_migration/** | |
ts_project_transpiler/** | |
# Print results as json to files in .github/outputs folder. | |
json: true | |
write_output_files: true | |
# Unconditionally add the root folder. There are three cases to consider: | |
# 1. No nested Bazel modules were touched: zero results in the all_changed_and_modified_files.json. So the changed files are in the root module. | |
# 2. Only files in the root module were touched: run CI anyway since Aspect Workflows runs unconditionally, and we want to be able to compare. | |
# 3. Root module AND nested module touched in the PR: we need to add the root module since it won't match any entry above. | |
- run: (echo -n "dirs="; jq --compact-output '. + ["."]' < .github/outputs/all_changed_and_modified_files.json) >> $GITHUB_OUTPUT | |
id: changed-toplevel-dirs | |
outputs: | |
# Will look like [".", "some_folder"] | |
folder: ${{ steps.changed-toplevel-dirs.outputs.dirs }} | |
test: | |
# Wait for all matrix-prep jobs so we can reference the result | |
needs: | |
- matrix-prep-folder | |
- matrix-prep-os | |
# The type of runner that the job will run on | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: ${{ fromJSON(needs.matrix-prep-os.outputs.os) }} | |
folder: ${{ fromJSON(needs.matrix-prep-folder.outputs.folder) }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
# Clone the last two commits, so we can see what files were changed. | |
fetch-depth: 2 | |
# Get a list of top-level directories that were touched | |
- uses: tj-actions/changed-files@v45 | |
id: changed-toplevel-dirs | |
with: | |
dir_names: true | |
dir_names_max_depth: 1 | |
- uses: bazel-contrib/setup-bazel@0.8.5 | |
with: | |
repository-cache: true | |
bazelrc: | | |
common --announce_rc --color=yes | |
common --enable_platform_specific_config | |
# TODO: bring up a docker or podman container on our macos runners, OR | |
# use our testcontainers cloud account to get a remote one. | |
test:macos --test_tag_filters=-requires-docker | |
- name: Test Type | |
id: has_test_sh | |
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0 | |
with: | |
files: '${{ matrix.folder }}/test.sh' | |
- name: test.sh | |
working-directory: ${{ matrix.folder }} | |
if: steps.has_test_sh.outputs.files_exists == 'true' | |
run: ./test.sh | |
shell: bash | |
- name: bazel test //... | |
working-directory: ${{ matrix.folder }} | |
if: steps.has_test_sh.outputs.files_exists != 'true' | |
run: | | |
bazel \ | |
--bazelrc=$GITHUB_WORKSPACE/.aspect/bazelrc/ci.bazelrc \ | |
--bazelrc=$GITHUB_WORKSPACE/.github/workflows/ci.bazelrc \ | |
test //... |