[sival, pwm] Adds smoketest #59
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
# Copyright lowRISC contributors (OpenTitan project). | |
# Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
# SPDX-License-Identifier: Apache-2.0 | |
name: CI | |
on: | |
pull_request: | |
push: | |
branches-ignore: | |
- "backport-*" | |
tags: | |
- "*" | |
permissions: | |
contents: read | |
# Needed for workload identity federation | |
id-token: write | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
env: | |
VIVADO_VERSION: "2021.1" | |
jobs: | |
quick_lint: | |
name: Lint (quick) | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # Required so we can lint commit messages. | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
- name: Show environment | |
run: ./ci/scripts/show-env.sh | |
- name: Commit metadata | |
run: ./ci/scripts/lint-commits.sh "$GITHUB_BASE_REF" | |
if: ${{ github.event_name == 'pull_request' }} | |
- name: License headers | |
run: ./ci/scripts/check-licence-headers.sh "$GITHUB_BASE_REF" | |
if: ${{ github.event_name == 'pull_request' }} | |
- name: Executable bits | |
run: ./ci/scripts/exec-check.sh | |
- name: Non-ASCII characters | |
run: ./ci/scripts/check-ascii.sh | |
- name: Python (flake8) | |
run: ./ci/scripts/python-lint.sh "$GITHUB_BASE_REF" | |
if: ${{ github.event_name == 'pull_request' }} | |
- name: Python (mypy) | |
run: ./ci/scripts/mypy.sh | |
- name: Validate testplans with schema | |
run: ./ci/scripts/validate_testplans.sh | |
- name: C/C++ formatting | |
run: ./bazelisk.sh test //quality:clang_format_check | |
- name: Rust formatting | |
run: ./bazelisk.sh test //quality:rustfmt_check | |
- name: Shellcheck | |
run: ./bazelisk.sh test //quality:shellcheck_check | |
- name: Header guards | |
run: ./ci/scripts/include-guard.sh "$GITHUB_BASE_REF" | |
if: ${{ github.event_name == 'pull_request' }} | |
- name: Trailing whitespace | |
run: ./ci/scripts/whitespace.sh "$GITHUB_BASE_REF" | |
if: ${{ github.event_name == 'pull_request' }} | |
- name: Broken links | |
run: ./ci/scripts/check-links.sh | |
- name: Generated documentation | |
run: ./ci/scripts/check-cmdgen.sh | |
slow_lint: | |
name: Lint (slow) | |
runs-on: ubuntu-22.04 | |
needs: quick_lint | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # Bitstream cache requires all commits. | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
- name: Countermeasures implemented (earlgrey) | |
run: ./ci/scripts/check-countermeasures.sh earlgrey | |
continue-on-error: true | |
- name: Countermeasures implemented (englishbreakfast) | |
run: ./ci/scripts/check-countermeasures.sh englishbreakfast | |
continue-on-error: true | |
- name: Bazel test suite tags | |
run: ./ci/scripts/check_bazel_test_suites.py | |
continue-on-error: true | |
# See #21973: disabled until Verilator tags are fixed. | |
# - name: Check Bazel tags | |
# run: ./ci/scripts/check-bazel-tags.sh | |
# continue-on-error: true | |
- name: Banned Bazel rules | |
run: ./ci/scripts/check-bazel-banned-rules.sh | |
- name: Bazel target names | |
run: ./ci/scripts/check_bazel_target_names.py | |
continue-on-error: true | |
- name: DV software images | |
run: ./ci/scripts/check_dv_sw_images.sh | |
continue-on-error: true | |
- name: Build documentation | |
run: ./ci/scripts/build-docs.sh | |
- name: Generated files | |
run: ./ci/scripts/check-generated.sh | |
env: | |
OT_DESTRUCTIVE: 1 # Required by the script to clean up. | |
- name: Buildifier | |
run: ./bazelisk.sh test //quality:buildifier_check | |
- name: Vendored files | |
run: ./ci/scripts/check-vendoring.sh | |
- name: Verible RTL | |
run: ./ci/scripts/verible-lint.sh rtl | |
- name: Verible DV | |
run: ./ci/scripts/verible-lint.sh dv | |
- name: Verible FPV | |
run: ./ci/scripts/verible-lint.sh fpv | |
airgapped_build: | |
name: Airgapped build | |
runs-on: ubuntu-22.04 | |
needs: quick_lint | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # Bitstream cache requires all commits. | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
configure-bazel: false | |
- name: Free disk space | |
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be | |
- name: Check disk space | |
run: | | |
df -h | |
- name: Prepare airgapped environment | |
run: ./util/prep-bazel-airgapped-build.sh | |
- name: Check disk space | |
run: | | |
df -h | |
- name: Build in the airgapped environment | |
run: ./ci/scripts/test-airgapped-build.sh | |
verible_lint: | |
name: Verible lint | |
runs-on: ubuntu-24.04 | |
needs: quick_lint | |
if: ${{ github.event_name == 'pull_request' }} | |
env: | |
verible_config: hw/lint/tools/veriblelint/lowrisc-styleguide.rules.verible_lint | |
verible_version: v0.0-3430-g060bde0f | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Prepare Verible config | |
run: | | |
echo "Concatenating Verible waivers" | |
find . -type f -name '*.vbl' -exec cat {} \; >> verible_waiver | |
echo "::group::Verible config" | |
cat "$verible_config" | |
echo "::endgroup::" | |
echo "::group::Verible waiver" | |
cat "verible_waiver" | |
echo "::endgroup::" | |
- name: Run Verible linter action | |
uses: chipsalliance/[email protected] | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
verible_version: ${{ env.verible_version }} | |
reviewdog_reporter: 'github-pr-check' | |
suggest_fixes: 'false' | |
config_file: ${{ env.verible_config }} | |
extra_args: "--waiver_files=verible_waiver" | |
verilator_englishbreakfast: | |
name: Verilated English Breakfast | |
runs-on: ubuntu-22.04 | |
needs: quick_lint | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
- name: Build simulator with Verilator | |
run: ./ci/scripts/build-chip-verilator.sh englishbreakfast | |
- name: Upload binary | |
uses: actions/upload-artifact@v4 | |
with: | |
name: verilated_englishbreakfast | |
path: build-bin/hw/top_englishbreakfast/Vchip_englishbreakfast_verilator | |
overwrite: true | |
- name: Test | |
run: ./ci/scripts/run-english-breakfast-verilator-tests.sh | |
verilator_earlgrey: | |
name: Verilated Earl Grey | |
runs-on: ubuntu-20.04 | |
needs: quick_lint | |
timeout-minutes: 240 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
- name: Run fast Verilator tests | |
run: ./ci/scripts/run-verilator-tests.sh | |
- name: Publish Bazel test results | |
uses: ./.github/actions/publish-bazel-test-results | |
if: ${{ !cancelled() }} | |
with: | |
artifact-name: verilator_earlgrey-test-results | |
# Build CW305 variant of the English Breakfast toplevel design using Vivado | |
chip_englishbreakfast_cw305: | |
name: CW305's Bitstream | |
runs-on: ubuntu-22.04-bitstream | |
needs: quick_lint | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
- name: Build bitstream | |
run: | | |
# Build CW305 test rom required by `build-bitstream-vivado.sh` | |
rom_path="sw/device/lib/testing/test_rom" | |
./bazelisk.sh build "//${rom_path}:test_rom_fpga_cw305" \ | |
--features=-rv32_bitmanip \ | |
--copt=-DOT_IS_ENGLISH_BREAKFAST_REDUCED_SUPPORT_FOR_INTERNAL_USE_ONLY_ | |
vmem="$(./bazelisk.sh cquery --output=files "//${rom_path}:test_rom_fpga_cw305" \ | |
--features=-rv32_bitmanip \ | |
--copt=-DOT_IS_ENGLISH_BREAKFAST_REDUCED_SUPPORT_FOR_INTERNAL_USE_ONLY_ | |
)" | |
mkdir -p "build-bin/${rom_path}" | |
cp "$vmem" "build-bin/${rom_path}" | |
module load "xilinx/vivado/${VIVADO_VERSION}" | |
ci/scripts/build-bitstream-vivado.sh top_englishbreakfast cw305 | |
- name: Upload bitstream | |
uses: actions/upload-artifact@v4 | |
with: | |
name: chip_englishbreakfast_cw305 | |
path: build-bin/hw/top_englishbreakfast/lowrisc_systems_chip_englishbreakfast_cw305_0.1.bit | |
overwrite: true | |
chip_earlgrey_cw310: | |
name: Earl Grey for CW310 | |
needs: quick_lint | |
uses: ./.github/workflows/bitstream.yml | |
secrets: inherit | |
with: | |
top_name: earlgrey | |
design_suffix: cw310 | |
chip_earlgrey_cw310_hyperdebug: | |
name: Earl Grey for CW310 Hyperdebug | |
needs: quick_lint | |
uses: ./.github/workflows/bitstream.yml | |
secrets: inherit | |
with: | |
top_name: earlgrey | |
design_suffix: cw310_hyperdebug | |
chip_earlgrey_cw340: | |
name: Earl Grey for CW340 | |
needs: quick_lint | |
uses: ./.github/workflows/bitstream.yml | |
secrets: inherit | |
with: | |
top_name: earlgrey | |
design_suffix: cw340 | |
cache_bitstreams: | |
name: Cache bitstreams to GCP | |
runs-on: ubuntu-22.04 | |
if: ${{ github.event_name != 'pull_request' }} | |
needs: | |
- chip_earlgrey_cw310 | |
- chip_earlgrey_cw310_hyperdebug | |
- chip_earlgrey_cw340 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
- name: Download partial build-bin | |
uses: ./.github/actions/download-partial-build-bin | |
with: | |
job-patterns: chip_earlgrey_{cw310,cw310_hyperdebug,cw340} | |
- name: Create bitstream cache archive | |
run: | | |
shopt -s globstar # Allow use of ** | |
./bazelisk.sh build //util/py/scripts:bitstream_cache_create | |
./bazelisk.sh run //util/py/scripts:bitstream_cache_create -- \ | |
--schema $PWD/rules/scripts/bitstreams_manifest.schema.json \ | |
--stamp-file $PWD/bazel-out/volatile-status.txt \ | |
--out $PWD/build-bin/bitstream-cache \ | |
$PWD/build-bin/**/manifest.json | |
- uses: google-github-actions/setup-gcloud@v2 | |
- name: Upload bitstreams to GCP bucket | |
run: | | |
BUCKET_URI=gs://opentitan-bitstreams/${{ github.ref_name }} | |
printf "$(date -u +%Y-%m-%dT%H:%M:%S)\n${{ github.sha }}" > latest.txt | |
gcloud storage cp build-bin/bitstream-cache/bitstream-cache.tar.gz $BUCKET_URI/bitstream-${{ github.sha }}.tar.gz | |
gcloud storage cp latest.txt $BUCKET_URI/latest.txt | |
gcloud storage cp $BUCKET_URI/bitstream-${{ github.sha }}.tar.gz $BUCKET_URI/bitstream-latest.tar.gz | |
# CW310 FPGA jobs. | |
execute_test_rom_fpga_tests_cw310: | |
name: CW310 Test ROM Tests | |
needs: chip_earlgrey_cw310 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_test_rom_fpga_tests_cw310 | |
bitstream: chip_earlgrey_cw310 | |
board: cw310 | |
interface: cw310 | |
tag_filters: cw310_test_rom | |
execute_rom_fpga_tests_cw310: | |
name: CW310 ROM Tests | |
needs: chip_earlgrey_cw310 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_rom_fpga_tests_cw310 | |
bitstream: chip_earlgrey_cw310 | |
board: cw310 | |
interface: cw310 | |
tag_filters: "cw310_rom_with_fake_keys,cw310_rom_with_real_keys,-manuf" | |
timeout: 90 | |
execute_rom_ext_fpga_tests_cw310: | |
name: CW310 ROM_EXT Tests | |
needs: chip_earlgrey_cw310 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_rom_ext_fpga_tests_cw310 | |
bitstream: chip_earlgrey_cw310 | |
board: cw310 | |
interface: cw310 | |
tag_filters: cw310_rom_ext | |
execute_sival_fpga_tests_cw310: | |
name: CW310 SiVal Tests | |
needs: chip_earlgrey_cw310_hyperdebug | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_sival_fpga_tests_cw310 | |
bitstream: chip_earlgrey_cw310_hyperdebug | |
board: cw310 | |
interface: hyper310 | |
tag_filters: "cw310_sival,-manuf" | |
execute_sival_rom_ext_fpga_tests_cw310: | |
name: CW310 SiVal ROM_EXT Tests | |
needs: chip_earlgrey_cw310_hyperdebug | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_sival_rom_ext_fpga_tests_cw310 | |
bitstream: chip_earlgrey_cw310_hyperdebug | |
board: cw310 | |
interface: hyper310 | |
tag_filters: cw310_sival_rom_ext | |
execute_manuf_fpga_tests_cw310: | |
name: CW310 Manufacturing Tests | |
needs: chip_earlgrey_cw310_hyperdebug | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_manuf_fpga_tests_cw310 | |
bitstream: chip_earlgrey_cw310_hyperdebug | |
board: cw310 | |
interface: hyper310 | |
tag_filters: "manuf,-cw340" | |
# CW340 FPGA jobs | |
execute_test_rom_fpga_tests_cw340: | |
name: CW340 Test ROM Tests | |
needs: chip_earlgrey_cw340 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_test_rom_fpga_tests_cw340 | |
bitstream: chip_earlgrey_cw340 | |
board: cw340 | |
interface: cw340 | |
tag_filters: cw340_test_rom | |
execute_rom_fpga_tests_cw340: | |
name: CW340 ROM Tests | |
needs: chip_earlgrey_cw340 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_rom_fpga_tests_cw340 | |
bitstream: chip_earlgrey_cw340 | |
board: cw340 | |
interface: cw340 | |
tag_filters: "cw340_rom_with_fake_keys,cw340_rom_with_real_keys,-manuf" | |
execute_rom_ext_fpga_tests_cw340: | |
name: CW340 ROM_EXT Tests | |
needs: chip_earlgrey_cw340 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_rom_ext_fpga_tests_cw340 | |
bitstream: chip_earlgrey_cw340 | |
board: cw340 | |
interface: cw340 | |
tag_filters: cw340_rom_ext | |
execute_sival_fpga_tests_cw340: | |
name: CW340 SiVal Tests | |
needs: chip_earlgrey_cw340 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_sival_fpga_tests_cw340 | |
bitstream: chip_earlgrey_cw340 | |
board: cw340 | |
interface: cw340 | |
tag_filters: "cw340_sival,-manuf" | |
execute_sival_rom_ext_fpga_tests_cw340: | |
name: CW340 SiVal ROM_EXT Tests | |
needs: chip_earlgrey_cw340 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_sival_rom_ext_fpga_tests_cw340 | |
bitstream: chip_earlgrey_cw340 | |
board: cw340 | |
interface: cw340 | |
tag_filters: cw340_sival_rom_ext | |
execute_manuf_fpga_tests_cw340: | |
name: CW340 Manufacturing Tests | |
needs: chip_earlgrey_cw340 | |
uses: ./.github/workflows/fpga.yml | |
secrets: inherit | |
with: | |
job_name: execute_manuf_fpga_tests_cw340 | |
bitstream: chip_earlgrey_cw340 | |
board: cw340 | |
interface: cw340 | |
tag_filters: "manuf,-hyper310" | |
verify_fpga_jobs: | |
name: Verify FPGA jobs | |
runs-on: ubuntu-22.04 | |
needs: | |
- execute_test_rom_fpga_tests_cw310 | |
- execute_rom_fpga_tests_cw310 | |
- execute_rom_ext_fpga_tests_cw310 | |
- execute_sival_fpga_tests_cw310 | |
- execute_sival_rom_ext_fpga_tests_cw310 | |
- execute_manuf_fpga_tests_cw310 | |
- execute_test_rom_fpga_tests_cw340 | |
- execute_rom_fpga_tests_cw340 | |
- execute_rom_ext_fpga_tests_cw340 | |
- execute_sival_fpga_tests_cw340 | |
- execute_sival_rom_ext_fpga_tests_cw340 | |
- execute_manuf_fpga_tests_cw340 | |
if: success() || failure() | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Download target pattern files | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: execute_*-targets | |
path: verify_fpga_jobs | |
- name: List all target pattern files | |
run: | | |
find verify_fpga_jobs | |
- name: Checking for duplicate test runs | |
run: | | |
# Find and display all duplicates: | |
# - for each target file and each line, print '<job_name> <target>' | |
# - then sort by the target name | |
# - then keep all duplicated lines | |
pattern_files=$(find verify_fpga_jobs -name target_pattern_file.txt) | |
awk '{ print(gensub(/.*\/(.+)\/target_pattern_file.txt/, "\\1", "g", FILENAME) " " $0) }' $pattern_files | sort -k2 | uniq -D -f1 > duplicates.txt | |
if [ -s duplicates.txt ]; then | |
echo "The following tests ran in two or more jobs:" | |
cat duplicates.txt | |
false | |
fi | |
- name: Checking for missing test runs | |
if: success() || failure() | |
run: | | |
# Find and display tests that did not run: | |
./ci/scripts/run-bazel-test-query.sh all_fpga.txt fpga,-manual,-broken,-skip_in_ci //... @manufacturer_test_hooks//... | |
sort -o all_fpga.txt all_fpga.txt | |
pattern_files=$(find verify_fpga_jobs -name target_pattern_file.txt) | |
sort $pattern_files > all_run.txt | |
comm -23 all_fpga.txt all_run.txt > missing.txt | |
if [ -s missing.txt ]; then | |
echo "The following tests did not run in any job:" | |
cat missing.txt | |
false | |
fi | |
build_docker_containers: | |
name: Build Docker Containers | |
runs-on: ubuntu-22.04 | |
needs: quick_lint | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Build Developer Utility Container | |
uses: docker/build-push-action@v6 | |
env: | |
DOCKER_BUILD_SUMMARY: false | |
DOCKER_BUILD_RECORD_UPLOAD: false | |
with: | |
context: . | |
file: util/container/Dockerfile | |
continue-on-error: true | |
- name: Build Documentation Redirector Container | |
uses: docker/build-push-action@v6 | |
env: | |
DOCKER_BUILD_SUMMARY: false | |
DOCKER_BUILD_RECORD_UPLOAD: false | |
with: | |
context: site/redirector/landing | |
sw_build_test: | |
name: Build and test software | |
runs-on: ubuntu-22.04-vivado | |
timeout-minutes: 120 | |
needs: quick_lint | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # Required for bitstream cache to work. | |
- name: Prepare environment | |
uses: ./.github/actions/prepare-env | |
with: | |
service_account_json: '${{ secrets.BAZEL_CACHE_CREDS }}' | |
- name: Check Bazel build graph | |
run: | | |
# Test the graph with both an empty and filled bitstream cache. | |
./ci/scripts/test-empty-bitstream-cache.sh | |
./bazelisk.sh build --nobuild //... | |
- name: Select software targets | |
run: | | |
target_pattern_file="$(mktemp)" | |
echo "target_pattern_file=${target_pattern_file}" >> "$GITHUB_ENV" | |
# Start with building the whole graph. | |
echo '//...' > "$target_pattern_file" | |
# Exclude some targets: | |
# | |
# 1. `//hw/...` is out of scope. | |
# 2. `//quality/...` is tested by the lint jobs. | |
# 3. `//sw/otbn/crypto/...` is tested by the OTBN job. | |
# 4. `//third_party/...` which is not our code. | |
printf "%s\n" \ | |
"-//hw/..." \ | |
"-//quality/..." \ | |
"-//sw/otbn/crypto/..." \ | |
"-//third_party/..." \ | |
>> "$target_pattern_file" | |
# Exclude anything that requires a bitstream splice. | |
./bazelisk.sh cquery \ | |
--noinclude_aspects \ | |
--output=starlark \ | |
--starlark:expr='"-{}".format(target.label)' \ | |
--define DISABLE_VERILATOR_BUILD=true \ | |
-- "rdeps(//..., kind(bitstream_splice, //...))" \ | |
>> "$target_pattern_file" | |
- name: Build software targets | |
run: | | |
# Build everything we selected, excluding some tags. | |
./bazelisk.sh build \ | |
--build_tests_only=false \ | |
--define DISABLE_VERILATOR_BUILD=true \ | |
--test_tag_filters=-broken,-cw310,-verilator,-dv \ | |
--target_pattern_file="$target_pattern_file" | |
- name: Run software unit tests | |
run: | | |
./bazelisk.sh test \ | |
--build_tests_only=false \ | |
--test_output=errors \ | |
--define DISABLE_VERILATOR_BUILD=true \ | |
--test_tag_filters=-broken,-cw310,-verilator,-dv,-silicon \ | |
--target_pattern_file="$target_pattern_file" | |
- name: Publish Bazel test results | |
uses: ./.github/actions/publish-bazel-test-results | |
if: ${{ !cancelled() }} | |
with: | |
artifact-name: sw_build_test-test-results | |
- name: Check for unrunnable tests | |
run: ./ci/scripts/check-unrunnable-tests.sh | |
continue-on-error: true |