name: "CI" on: pull_request: paths-ignore: - "release-plz.toml" push: paths-ignore: - "docs/**" - "**.md" - "LICENSE" - "release-plz.toml" branches: - main env: RUST_BACKTRACE: 1 CARGO_TERM_COLOR: always CLICOLOR: 1 CLICOLOR_FORCE: 1 permissions: actions: read contents: read # Only allow one run of the workflow per branch / PR at a time. concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: # Build and upload release binaries for all relevant architectures. build: strategy: fail-fast: false matrix: include: # Build for x86_64/linux target on native host. # N.B. We intentionally pin to Ubuntu 22.04 for now to increase # the range of distros that will be able to run the produced binaries. # Newer release of Ubuntu upgrade glibc to a point not yet supported # by some latest stable versions of distros. - host: "ubuntu-22.04" target: "" cross_command: "" cross_tool_to_install: "" os: "linux" arch: "x86_64" binary_name: "brush" extra_build_args: "" # Build for x86_64/linux using musl as target C runtime. # We don't bother pinning to an ealier version of Ubuntu because # the produced binary will statically link the C runtime anyhow. - host: "ubuntu-24.04" target: "x86_64-unknown-linux-musl" cross_command: "cross" cross_tool_to_install: "cross" os: "linux-musl" arch: "x86_64" binary_name: "brush" extra_build_args: "" # Build for aarch64/macos target on native host. - host: "macos-latest" target: "" cross_command: "" cross_tool_to_install: "" os: "macos" arch: "aarch64" required_tools: "" binary_name: "brush" extra_build_args: "" # Build for aarch64/linux target on x86_64/Linux host. - host: "ubuntu-24.04" target: "aarch64-unknown-linux-gnu" cross_command: "cross" cross_tool_to_install: "cross" os: "linux" arch: "aarch64" required_tools: "gcc-aarch64-linux-gnu" binary_name: "brush" extra_build_args: "" # Build for wasm32 target on x86_64/linux host. - host: "ubuntu-24.04" target: "wasm32-unknown-unknown" cross_command: "cross" cross_tool_to_install: "cross" os: "unknown" arch: "wasm32" required_tools: "" binary_name: "brush.wasm" extra_build_args: "--no-default-features --features minimal" # Build for WASI-0.2 target on x86_64/linux host. - host: "ubuntu-24.04" target: "wasm32-wasip2" cross_command: "cross" cross_tool_to_install: "cross" os: "wasi-0.2" arch: "wasm32" required_tools: "" binary_name: "brush.wasm" extra_build_args: "--no-default-features --features minimal" # Build for x86_64/windows target on x86_64/linux host. - host: "ubuntu-24.04" target: "x86_64-pc-windows-gnu" cross_command: "cross" cross_tool_to_install: "cross" os: "windows" arch: "x86_64" required_tools: "" binary_name: "brush.exe" extra_build_args: "" # Build for x86_64/android target on x86_64/linux host. - host: "ubuntu-24.04" target: "x86_64-linux-android" cross_command: "cargo ndk" cross_tool_to_install: "cargo-ndk" os: "android" arch: "x86_64" required_tools: "" binary_name: "brush" extra_build_args: "" # x86_64/FreeBSD target on x86_64/linux host, via cross. Compile-check # only (check_only): cross's curated sysroot omits some base-system # libraries (libgeom/libkvm/...) that `sysinfo` links against, so the # final link of a real binary fails. Checking still validates that the # shell compiles for the target; producing a binary is a TODO (would # need a full sysroot with those libraries present). - host: "ubuntu-24.04" target: "x86_64-unknown-freebsd" cross_command: "cross" cross_tool_to_install: "cross" os: "freebsd" arch: "x86_64" required_tools: "" binary_name: "brush" extra_build_args: "" check_only: true # x86_64/NetBSD target on x86_64/linux host, via cross. Compile-check # only for the same reason as FreeBSD above. - host: "ubuntu-24.04" target: "x86_64-unknown-netbsd" cross_command: "cross" cross_tool_to_install: "cross" os: "netbsd" arch: "x86_64" required_tools: "" binary_name: "brush" extra_build_args: "" check_only: true # OpenBSD is tier-3 with no prebuilt std, so even compile-checking it # requires building std from source (-Zbuild-std, hence nightly + # rust-src + no rustup target). panic_abort is built explicitly because # our release profile sets panic = "abort" (plain -Zbuild-std only # builds std + panic_unwind). Compile-check only, like the other BSDs; # check links nothing, so no C cross-compiler/sysroot/linker is needed # (none of the workspace's C-compiling deps are in this default graph). - host: "ubuntu-24.04" target: "x86_64-unknown-openbsd" cross_command: "cargo" cross_tool_to_install: "" os: "openbsd" arch: "x86_64" required_tools: "" binary_name: "brush" extra_build_args: "-Zbuild-std=std,panic_abort" toolchain: "nightly" components: "rust-src" # std is built from source, so there's no prebuilt target to install. skip_rustup_target: true check_only: true name: "${{ matrix.check_only && 'Check' || 'Build' }} (${{ matrix.arch }}/${{ matrix.os }})" runs-on: ${{ matrix.host }} steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Set up rust toolchain uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: ${{ matrix.toolchain || 'stable' }} targets: ${{ !matrix.skip_rustup_target && matrix.target || '' }} components: ${{ matrix.components || '' }} - name: Enable cargo cache uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: key: "${{ matrix.target }}" - name: Install additional prerequisite tools if: ${{ matrix.required_tools != '' }} env: REQUIRED_TOOLS: ${{ matrix.required_tools }} run: sudo apt-get update -y && sudo apt-get install -y ${REQUIRED_TOOLS} - name: Install cross-compilation toolchain if: ${{ matrix.cross_tool_to_install != '' }} uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2 with: tool: ${{ matrix.cross_tool_to_install }} - name: "Build (native)" if: ${{ matrix.target == '' }} env: EXTRA_BUILD_ARGS: ${{ matrix.extra_build_args }} run: cargo build --release --all-targets ${EXTRA_BUILD_ARGS} - name: "${{ matrix.check_only && 'Check' || 'Build' }} (cross)" if: ${{ matrix.target != '' }} env: CROSS_COMMAND: ${{ matrix.cross_command }} CARGO_SUBCOMMAND: ${{ matrix.check_only && 'check' || 'build' }} TARGET: ${{ matrix.target }} EXTRA_BUILD_ARGS: ${{ matrix.extra_build_args }} CARGO_NDK_PLATFORM: 24 run: ${CROSS_COMMAND} ${CARGO_SUBCOMMAND} --release --target=${TARGET} ${EXTRA_BUILD_ARGS} - name: "Upload binaries" # check_only targets don't produce a binary to upload. if: ${{ !matrix.check_only }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: binaries-${{ matrix.arch }}-${{ matrix.os }} path: target/${{ matrix.target }}/release/${{ matrix.binary_name }} - name: "Upload integration test binaries" if: ${{ matrix.target == '' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: integration-tests-${{ matrix.arch }}-${{ matrix.os }} path: | target/${{ matrix.target }}/release/deps/brush_*_tests-* !**/*.d # Test functional correctness test: strategy: fail-fast: false matrix: include: - host: "ubuntu-24.04" variant: "linux-x86_64" artifact_suffix: "linux-x86_64" name_suffix: "(linux/x86_64)" homebrew_supported: true coverage: true coverage_min_percent: 70 - host: "ubuntu-24.04-arm" variant: "linux-aarch64" artifact_suffix: "linux-aarch64" name_suffix: "(linux/aarch64)" homebrew_supported: false coverage: true coverage_min_percent: 70 - host: "macos-latest" variant: "macos" artifact_suffix: "-macos" name_suffix: "(macOS)" homebrew_supported: true coverage: true coverage_min_percent: 70 - host: "windows-2025" variant: "windows" artifact_suffix: "-windows" name_suffix: "(windows)" homebrew_supported: false coverage: true coverage_min_percent: 20 - host: "ubuntu-24.04" variant: "wasi" artifact_suffix: "-wasi" name_suffix: "(wasm32/wasi-0.2)" homebrew_supported: false coverage: false extra_rust_targets: "wasm32-wasip2" wasi_runtime: "wasmtime" xtask_test_args: "--wasi" name: "Test ${{ matrix.name_suffix }}" runs-on: ${{ matrix.host }} defaults: run: shell: bash steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Set up rust toolchain uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: stable targets: ${{ matrix.extra_rust_targets || '' }} components: llvm-tools-preview - name: Enable cargo cache uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: # Needed to make sure cargo-deny is correctly cached. cache-all-crates: true - name: Install cargo-nextest uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2 with: tool: cargo-nextest - name: Install cargo-llvm-cov if: ${{ matrix.coverage }} uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2 with: tool: cargo-llvm-cov - name: Install WASI runtime if: ${{ matrix.wasi_runtime }} uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2 with: tool: ${{ matrix.wasi_runtime }} - name: Set up Homebrew if: ${{ matrix.homebrew_supported }} id: set-up-homebrew # We ignore the stale-action-refs check because this action does not have any releases or tags. # We're forced to pick a specific commit. uses: Homebrew/actions/setup-homebrew@df4b09108a1de9d6f995fe68f302b3f68bd6d2ef # zizmor: ignore[stale-action-refs] with: stable: true - name: "Install recent bash for tests" if: ${{ matrix.homebrew_supported }} run: | set -x # Install it brew install bash # Find the path BASH_PATH="$(brew --prefix bash)/bin/bash" # Log what we're using echo "Using bash from: ${BASH_PATH}" echo "bash version:" ${BASH_PATH} --version echo "BASH_PATH=${BASH_PATH}">>$GITHUB_ENV - name: "Download recent bash-completion sources for tests" uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false repository: "scop/bash-completion" ref: "2.17.0" path: "bash-completion" - name: "Setup bash-completion" run: echo "BASH_COMPLETION_PATH=${GITHUB_WORKSPACE}/bash-completion/bash_completion">>$GITHUB_ENV - name: Test env: VARIANT: ${{ matrix.variant }} run: | args="${{ matrix.xtask_test_args || '' }}" args="${args} --results-output ./test-results-${VARIANT}.xml" if [[ "${{ matrix.coverage }}" == "true" ]]; then args="${args} --coverage --coverage-output ./codecov-${VARIANT}.xml" fi cargo xtask test integration ${args} - name: "Upload test results" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: always() with: name: test-reports${{ matrix.artifact_suffix }} path: test-results-*.xml - name: "Generate code coverage report" uses: clearlyip/code-coverage-report-action@110af9d4ec87b6706f182fd90e3102af9e5203bf # v7.0.0 if: ${{ always() && matrix.coverage }} id: "code_coverage_report" with: artifact_download_workflow_names: "CI" artifact_name: coverage-%name%${{ matrix.artifact_suffix }} filename: codecov-${{ matrix.variant }}.xml overall_coverage_fail_threshold: ${{ matrix.coverage_min_percent }} only_list_changed_files: ${{ github.event_name == 'pull_request' }} fail_on_negative_difference: true negative_difference_by: "overall" negative_difference_threshold: 5 - name: "Upload code coverage report" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: always() with: name: codecov-reports${{ matrix.artifact_suffix }} path: code-coverage-results.md # Static analysis of the code. check: name: "Source code checks" runs-on: ${{ matrix.os }} strategy: matrix: # Test latest stable as well as MSRV. rust-version: ["stable", "1.88.0"] # Run checks on Linux, Windows, and macOS. os: ["ubuntu-24.04", "windows-2025", "macos-latest"] steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Set up rust toolchain (${{ matrix.rust-version }}) uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: ${{ matrix.rust-version }} components: clippy, rustfmt - name: Enable cargo cache uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: # Needed to make sure cargo-deny is correctly cached. cache-all-crates: true - name: Format check run: cargo xtask check fmt - name: Check run: cargo xtask check build - name: Install cargo-deny if: runner.os == 'Linux' uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2 with: tool: cargo-deny # NOTE: Only run on Linux. cargo-deny checks (advisories, licenses, bans, # sources) are platform-independent, so running on one OS is sufficient. # Also works around a cargo-deny 0.19.x bug where its advisory DB parser # panics on Windows due to CRLF line endings (hardcoded LF-only matching). - name: Deny check if: runner.os == 'Linux' run: cargo xtask check deps - name: Clippy check if: matrix.rust-version == 'stable' run: cargo xtask check lint # Check for unneeded dependencies. check-deps: name: "Check for unneeded dependencies" runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Set up nightly rust toolchain uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: nightly - name: Install cargo-udeps uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2 with: tool: cargo-udeps - name: Check for unused dependencies run: cargo xtask check unused-deps # Check that generated schemas are up-to-date check-schemas: name: "Check generated schemas" runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Set up rust toolchain uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: stable - name: Enable cargo cache uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - name: Check generated schemas run: cargo xtask check schemas # Analyze public API surface analyze-public-api: if: github.event_name == 'pull_request' name: "Analyze public API" runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Set up nightly rust toolchain uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: nightly - name: Install cargo-public-api uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2 with: tool: cargo-public-api - name: Set up branches run: | set -euo pipefail git fetch origin main - name: Compare public APIs with main run: cargo xtask analyze public-api --base origin/main --output-dir reports - name: Upload test report uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test-reports-public-api path: reports/*.md # Performance analysis of the code. benchmark: if: github.event_name == 'pull_request' name: "Benchmarks" runs-on: ubuntu-24.04 steps: - name: Checkout PR sources uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false path: pr - name: Checkout main sources uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false path: main ref: main - name: Set up rust toolchain uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: stable - name: Enable cargo cache uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: workspaces: | ./pr ./main - name: Performance analysis on PR run: cargo xtask analyze bench --output benchmarks.txt working-directory: pr - name: Performance analysis on main run: cargo bench --workspace --benches -- --output-format bencher | tee benchmarks.txt working-directory: main - name: Compare benchmark results run: | ./pr/scripts/compare-benchmark-results.py -b main/benchmarks.txt -t pr/benchmarks.txt >benchmark-results.md - name: Upload performance results uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: perf-reports path: | pr/benchmarks.txt main/benchmarks.txt benchmark-results.md # Run bash-completion test suite bash-completion-tests: name: "External tests / bash-completion test suite" runs-on: ubuntu-latest needs: build steps: - name: Checkout brush uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false path: "brush" - name: Checkout bash-completion uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false repository: "scop/bash-completion" ref: "2.16.0" path: "bash-completion" - name: Download prebuilt brush binaries uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: "binaries-x86_64-linux" path: "binaries" - name: Setup downloads run: | chmod +x binaries/* ls -l binaries - name: Install prerequisites for running tests run: | set -x sudo apt-get update -y sudo apt-get install -y python3 python3 -m pip install --user pytest pytest-xdist pytest-md-report pytest-json-report - name: "Run test suite (brush)" working-directory: brush run: | cargo xtask test \ --brush-path $GITHUB_WORKSPACE/binaries/brush \ external bash-completion \ --bash-completion-path $GITHUB_WORKSPACE/bash-completion \ --output $GITHUB_WORKSPACE/test-results-bash-completion.json \ --summary-output $GITHUB_WORKSPACE/test-results-bash-completion.md || true - name: Upload test report uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test-reports-bash-completion path: | test-results-bash-completion.md # Test release binary on a variety of OS platforms. os-tests: strategy: fail-fast: false matrix: include: # N.B. We don't include Ubuntu because it's already covered by the initial test job. - container: "archlinux:latest" description: "Arch Linux/latest" prereqs_command: "pacman -Sy --noconfirm bash-completion iputils grep less sed util-linux which" - container: "mcr.microsoft.com/azurelinux-beta/base/core:4.0" description: "Azure Linux/4.0" prereqs_command: "dnf install -y bash-completion ca-certificates git iputils grep less sed util-linux which" - container: "debian:testing" description: "Debian/testing" prereqs_command: "apt-get update -y && apt-get install -y bash-completion bsdmainutils iputils-ping grep less sed which" - container: "fedora:latest" description: "Fedora/latest" prereqs_command: "dnf install -y bash-completion iputils grep less sed util-linux which" - container: "nixos/nix:latest" description: "NixOS/latest" prereqs_command: "nix --extra-experimental-features nix-command --extra-experimental-features flakes profile install nixpkgs#gnused nixpkgs#hexdump nixpkgs#bash-completion" # NOTE: We use Tumbleweed to make sure we get a recent enough version of bash. - container: "opensuse/tumbleweed:latest" description: "openSUSE Tumbleweed/latest" prereqs_command: "zypper install -y bash-completion git which" name: "OS target tests (${{ matrix.description }})" runs-on: ubuntu-24.04 container: ${{ matrix.container }} needs: build env: # Reference: https://github.com/Azure/azure-cli/issues/29835 GNUPGHOME: /root/.gnupg steps: # Install prerequisites *first*; may need some of them for checkout itself. - name: Install prerequisites if: ${{ matrix.prereqs_command != '' }} env: PREREQS_COMMAND: ${{ matrix.prereqs_command }} run: bash -c "${PREREQS_COMMAND}" # Workaround path issues on NixOS - name: "Apply workarounds: NixOS" if: ${{ matrix.container == 'nixos/nix:latest' }} run: | set -x # Allow use of experimental features to avoid nix from complaining. export NIX_CONFIG="extra-experimental-features = nix-command flakes" # The nixos/nix image ships no /etc/os-release (unlike a full NixOS install # and every other container we test against). Provide one so the test harness # can identify the OS, which it relies on for tests' `incompatible_os` tags. printf 'NAME=NixOS\nID=nixos\nPRETTY_NAME="NixOS (nix container)"\n' > /etc/os-release # Hacks to get the mounted nodejs by github actions work as it's dynamically linked # https://github.com/actions/checkout/issues/334#issuecomment-716068696 nix build --no-link --max-jobs 2 --cores 0 'nixpkgs#stdenv.cc.cc.lib' 'nixpkgs#glibc' echo "LD_LIBRARY_PATH=$(nix path-info 'nixpkgs#stdenv.cc.cc.lib')/lib" >> "$GITHUB_ENV" ln -s "$(nix path-info 'nixpkgs#glibc' --recursive | grep glibc | grep -v bin)/lib64" /lib64 # Provide alternate path for bash-completion echo "BASH_COMPLETION_PATH=$(nix path-info 'nixpkgs#bash-completion')/share/bash-completion/bash_completion">>"$GITHUB_ENV" # Forcibly add system paths echo "BRUSH_TEST_PATH_VAR=$PATH">>"$GITHUB_ENV" # Checkout sources for YAML-based test cases - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false path: sources - name: Download prebuilt brush binaries uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: binaries-x86_64-linux path: binaries - name: Download integration test binaries uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: integration-tests-x86_64-linux path: binaries - name: Setup downloads run: | # N.B. Can't use -o pipefail because it's not supported on Debian. set -eux chmod +x binaries/* ls -l -R sources/brush-shell/tests ls -l binaries - name: Run tests shell: bash run: | export BRUSH_PATH=$PWD/binaries/brush export BRUSH_VERBOSE=true result=0 for test_name in binaries/*tests*; do if [[ ${test_name} == *compat* ]]; then export BRUSH_TEST_CASES=$PWD/sources/brush-shell/tests/cases/compat elif [[ ${test_name} == *integration* ]]; then export BRUSH_TEST_CASES=$PWD/sources/brush-shell/tests/cases/brush elif [[ ${test_name} == *interactive* || ${test_name} == *version* ]]; then # TODO(tests): Re-enable these tests. echo "WARNING: skipping test: ${test_name}" continue fi echo "Running test: ${test_name}" chmod +x ${test_name} ${test_name} || result=$? done exit ${result}