| 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, 1.x] |
| pull_request: |
| branches: [main, 1.x] |
| |
| # Allows you to run this workflow manually from the Actions tab |
| workflow_dispatch: |
| |
| concurrency: |
| # Cancel previous actions from the same PR or branch except 'main' branch. |
| # See https://docs.github.com/en/actions/using-jobs/using-concurrency and https://docs.github.com/en/actions/learn-github-actions/contexts for more info. |
| group: concurrency-group::${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}${{ github.ref_name == 'main' && format('::{0}', github.run_id) || ''}} |
| cancel-in-progress: ${{ github.ref_name != 'main' }} |
| |
| jobs: |
| # matrix-prep-* steps dynamically generate a bit of JSON depending on whether our action has |
| # access to repository secrets. When running on a pull_request from a fork, the author is |
| # untrusted so the secret will be absent. Insanely complex for how simple this requirement is... |
| # inspired from |
| # https://stackoverflow.com/questions/65384420/how-to-make-a-github-action-matrix-element-conditional |
| |
| matrix-prep-config: |
| # Prepares the 'config' axis of the test matrix |
| runs-on: ubuntu-latest |
| env: |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| steps: |
| - id: local |
| run: echo "config=local" >> $GITHUB_OUTPUT |
| - id: rbe |
| run: echo "config=rbe" >> $GITHUB_OUTPUT |
| # Don't run RBE if there is no API key which is the case on forks |
| if: ${{ env.BUILDBUDDY_API_KEY != '' }} |
| outputs: |
| # Will look like '["local", "rbe"]' |
| configs: ${{ toJSON(steps.*.outputs.config) }} |
| |
| matrix-prep-bazelversion: |
| # Prepares the 'bazelversion' axis of the test matrix |
| runs-on: ubuntu-latest |
| steps: |
| - uses: actions/checkout@v4 |
| - id: bazel_6 |
| run: echo "bazelversion=$(head -n 1 .bazelversion)" >> $GITHUB_OUTPUT |
| - id: bazel_7 |
| run: echo "bazelversion=7.0.0" >> $GITHUB_OUTPUT |
| outputs: |
| # Will look like '["<version from .bazelversion>", "7.0.0"]' |
| bazelversions: ${{ toJSON(steps.*.outputs.bazelversion) }} |
| |
| matrix-prep-os: |
| # Prepares the 'os' axis of the test matrix |
| runs-on: ubuntu-latest |
| steps: |
| - uses: actions/checkout@v4 |
| - id: linux |
| run: echo "os=ubuntu-latest" >> $GITHUB_OUTPUT |
| - id: macos |
| run: echo "os=macos-latest" >> $GITHUB_OUTPUT |
| # Only run on main branch (or PR branches that contain 'macos') 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' || contains(github.head_ref, 'macos') }} |
| - id: windows |
| run: echo "os=windows-latest" >> $GITHUB_OUTPUT |
| # Only run on main branch (or PR branches that contain 'windows') to minimize Windows minutes (billed at 2X) |
| # 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' || contains(github.head_ref, 'windows') }} |
| outputs: |
| # Will look like ["ubuntu-latest", "macos-latest", "windows-latest"] |
| os: ${{ toJSON(steps.*.outputs.os) }} |
| |
| test: |
| # The type of runner that the job will run on |
| runs-on: ${{ matrix.os }} |
| |
| needs: |
| - matrix-prep-config |
| - matrix-prep-bazelversion |
| - matrix-prep-os |
| |
| strategy: |
| fail-fast: false |
| matrix: |
| config: ${{ fromJSON(needs.matrix-prep-config.outputs.configs) }} |
| bazelversion: ${{ fromJSON(needs.matrix-prep-bazelversion.outputs.bazelversions) }} |
| os: ${{ fromJSON(needs.matrix-prep-os.outputs.os) }} |
| bzlmodEnabled: [true, false] |
| folder: |
| - "." |
| - "e2e/copy_action" |
| - "e2e/copy_to_directory" |
| - "e2e/coreutils" |
| - "e2e/external_copy_to_directory" |
| - "e2e/smoke" |
| - "e2e/write_source_files" |
| exclude: |
| # Don't test MacOS with RBE to minimize MacOS minutes (billed at 10X) |
| - config: rbe |
| os: macos-latest |
| # Don't test MacOS with Bazel 7 to minimize MacOS minutes (billed at 10X) |
| - bazelversion: 7.0.0 |
| os: macos-latest |
| # Don't test Windows with RBE to minimize Windows minutes (billed at 2X) |
| - config: rbe |
| os: windows-latest |
| # Don't test Windows with Bazel 7 to minimize Windows minutes (billed at 2X) |
| - bazelversion: 7.0.0 |
| os: windows-latest |
| |
| # Steps represent a sequence of tasks that will be executed as part of the job |
| steps: |
| # Checks-out your repository under ${{ github.workspace }} , so your job can access it |
| - uses: actions/checkout@v4 |
| |
| - name: Mount bazel caches |
| uses: actions/cache@v4 |
| with: |
| path: | |
| ~/.cache/bazel |
| ~/.cache/bazel-repo |
| key: bazel-cache-${{ matrix.os }}-${{ matrix.bazelversion }}-${{ matrix.folder }}-${{ matrix.bzlmodEnabled }}-${{ matrix.config }}-${{ hashFiles('.bazelrc', '.bazelversion', '.bazeliskrc', '**/BUILD', '**/BUILD.bazel', '**/*.bzl', 'WORKSPACE', 'WORKSPACE.bazel', 'WORKSPACE.bzlmod', 'MODULE.bazel', 'MODULE.bazel.lock') }} |
| restore-keys: bazel-cache-${{ matrix.os }}-${{ matrix.bazelversion }}-${{ matrix.folder }}-${{ matrix.bzlmodEnabled }}-${{ matrix.config }}- |
| |
| - name: Configure Bazel version |
| if: ${{ matrix.os != 'windows-latest' }} |
| working-directory: ${{ matrix.folder }} |
| # - Overwrite the .bazelversion instead of using USE_BAZEL_VERSION so that Bazelisk |
| # still bootstraps Aspect CLI from configuration in .bazeliskrc. Aspect CLI will |
| # then use .bazelversion to determine which Bazel version to use. |
| # - Delete the .aspect/bazelrc/bazel6.bazelrc file if we are not testing |
| # against Bazel 6 which has a try-import in the root .bazelrc for local development. |
| run: | |
| BAZEL_VERSION=${{ matrix.bazelversion }} |
| echo "${{ matrix.bazelversion }}" > .bazelversion |
| if [ ${BAZEL_VERSION::1} != "6" ]; then rm -f .aspect/bazelrc/bazel6.bazelrc; fi |
| |
| - name: Configure Bazel version (Windows) |
| if: ${{ matrix.os == 'windows-latest' }} |
| working-directory: ${{ matrix.folder }} |
| # - Overwrite the .bazelversion instead of using USE_BAZEL_VERSION so that Bazelisk |
| # still bootstraps Aspect CLI from configuration in .bazeliskrc. Aspect CLI will |
| # then use .bazelversion to determine which Bazel version to use. |
| # - Delete the .aspect/bazelrc/bazel6.bazelrc file if we are not testing |
| # against Bazel 6 which has a try-import in the root .bazelrc for local development. |
| # - Delete the .bazeliskrc file since Aspect CLI doesn't current ship Windows binaries |
| run: | |
| echo "${{ matrix.bazelversion }}" > .bazelversion |
| $BAZEL_MAJOR_VERSION = "${{ matrix.bazelversion }}".substring(0, 1) |
| if ($BAZEL_MAJOR_VERSION -ne "6") { |
| rm -Force .aspect/bazelrc/bazel6.bazelrc |
| } |
| rm -Force .bazeliskrc |
| |
| - name: Set bzlmod flag |
| # Store the --enable_bzlmod flag that we add to the test command below |
| # only when we're running bzlmod in our test matrix. |
| id: set_bzlmod_flag |
| if: matrix.bzlmodEnabled |
| run: echo "bzlmod_flag=--enable_bzlmod" >> $GITHUB_OUTPUT |
| |
| - name: Write rbe credentials |
| if: ${{ matrix.config == 'rbe' }} |
| working-directory: ${{ matrix.folder }} |
| run: | |
| touch $HOME/.bazelrc |
| chmod 0600 $HOME/.bazelrc |
| echo "build --remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY" > $HOME/.bazelrc |
| env: |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| |
| - name: bazel test //... |
| if: ${{ matrix.os != 'windows-latest' }} |
| working-directory: ${{ matrix.folder }} |
| run: | |
| BAZEL_VERSION=${{ matrix.bazelversion }} |
| bazel --bazelrc=${{ github.workspace }}/.aspect/bazelrc/ci.bazelrc \ |
| --bazelrc=${{ github.workspace }}/.github/workflows/ci.bazelrc \ |
| --bazelrc=${{ github.workspace }}/.aspect/bazelrc/bazel${BAZEL_VERSION::1}.bazelrc \ |
| test --config=${{ matrix.config }} //... \ |
| ${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} |
| env: |
| # Bazelisk will download bazel to here |
| XDG_CACHE_HOME: ~/.cache/bazel-repo |
| |
| - name: bazel test //... (Windows) |
| # A different run command is needed on Windows to account for differences between bash and Powershell |
| if: ${{ matrix.os == 'windows-latest' }} |
| working-directory: ${{ matrix.folder }} |
| run: | |
| $BAZEL_MAJOR_VERSION = "${{ matrix.bazelversion }}".substring(0, 1) |
| bazel --bazelrc=${{ github.workspace }}/.aspect/bazelrc/ci.bazelrc ` |
| --bazelrc=${{ github.workspace }}/.github/workflows/ci.bazelrc ` |
| --bazelrc=${{ github.workspace }}/.aspect/bazelrc/bazel$BAZEL_MAJOR_VERSION.bazelrc ` |
| test --config=${{ matrix.config }} //... ` |
| ${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} |
| env: |
| # Bazelisk will download bazel to here |
| XDG_CACHE_HOME: ~/.cache/bazel-repo |
| |
| - name: integration tests |
| # Don't run integration tests on Windows since they are bash scripts and Windows runs Powershell |
| if: ${{ matrix.folder == '.' && matrix.os != 'windows-latest' }} |
| # Find all shell scripts within e2e, echo the filename, execute, fail on error |
| run: find e2e/*.sh -maxdepth 1 -type f -exec sh -c 'echo "\n\n------------------------------- $0 -------------------------------" && BZLMOD_FLAG=${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} "$0" || kill $PPID' \{\} \; |
| |
| - name: verify bcr patches |
| if: matrix.bzlmodEnabled && matrix.os == 'ubuntu-latest' |
| run: patch --dry-run -p1 < .bcr/patches/*.patch |