375 lines
14 KiB
YAML
375 lines
14 KiB
YAML
name: Run tests with twister
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- v*-branch
|
|
- collab-*
|
|
pull_request_target:
|
|
branches:
|
|
- main
|
|
- v*-branch
|
|
- collab-*
|
|
schedule:
|
|
# Run at 03:00 UTC on every Sunday
|
|
- cron: '0 3 * * 0'
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
twister-build-prep:
|
|
if: github.repository_owner == 'zephyrproject-rtos'
|
|
runs-on:
|
|
group: zephyr-runner-v2-linux-x64-4xlarge
|
|
container:
|
|
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.27.4.20241026
|
|
options: '--entrypoint /bin/bash'
|
|
outputs:
|
|
subset: ${{ steps.output-services.outputs.subset }}
|
|
size: ${{ steps.output-services.outputs.size }}
|
|
fullrun: ${{ steps.output-services.outputs.fullrun }}
|
|
env:
|
|
MATRIX_SIZE: 10
|
|
PUSH_MATRIX_SIZE: 20
|
|
DAILY_MATRIX_SIZE: 80
|
|
BSIM_OUT_PATH: /opt/bsim/
|
|
BSIM_COMPONENTS_PATH: /opt/bsim/components
|
|
TESTS_PER_BUILDER: 700
|
|
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
|
|
BASE_REF: ${{ github.base_ref }}
|
|
steps:
|
|
- name: Apply container owner mismatch workaround
|
|
run: |
|
|
# FIXME: The owner UID of the GITHUB_WORKSPACE directory may not
|
|
# match the container user UID because of the way GitHub
|
|
# Actions runner is implemented. Remove this workaround when
|
|
# GitHub comes up with a fundamental fix for this problem.
|
|
git config --global --add safe.directory ${GITHUB_WORKSPACE}
|
|
|
|
- name: Print cloud service information
|
|
run: |
|
|
echo "ZEPHYR_RUNNER_CLOUD_PROVIDER = ${ZEPHYR_RUNNER_CLOUD_PROVIDER}"
|
|
echo "ZEPHYR_RUNNER_CLOUD_NODE = ${ZEPHYR_RUNNER_CLOUD_NODE}"
|
|
echo "ZEPHYR_RUNNER_CLOUD_POD = ${ZEPHYR_RUNNER_CLOUD_POD}"
|
|
|
|
- name: Clone cached Zephyr repository
|
|
if: github.event_name == 'pull_request_target'
|
|
continue-on-error: true
|
|
run: |
|
|
git clone --shared /repo-cache/zephyrproject/zephyr .
|
|
git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}
|
|
|
|
- name: Checkout
|
|
if: github.event_name == 'pull_request_target'
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Environment Setup
|
|
if: github.event_name == 'pull_request_target'
|
|
run: |
|
|
git config --global user.email "bot@zephyrproject.org"
|
|
git config --global user.name "Zephyr Bot"
|
|
rm -fr ".git/rebase-apply"
|
|
git rebase origin/${BASE_REF}
|
|
git clean -f -d
|
|
git log --pretty=oneline | head -n 10
|
|
west init -l . || true
|
|
west config manifest.group-filter -- +ci,+optional
|
|
west config --global update.narrow true
|
|
west update --path-cache /repo-cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /repo-cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /repo-cache/zephyrproject)
|
|
west forall -c 'git reset --hard HEAD'
|
|
|
|
echo "ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-$( cat SDK_VERSION )" >> $GITHUB_ENV
|
|
|
|
- name: Generate Test Plan with Twister
|
|
if: github.event_name == 'pull_request_target'
|
|
id: test-plan
|
|
run: |
|
|
export ZEPHYR_BASE=${PWD}
|
|
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
|
|
python3 ./scripts/ci/test_plan.py -c origin/${BASE_REF}.. --pull-request -t $TESTS_PER_BUILDER
|
|
if [ -s .testplan ]; then
|
|
cat .testplan >> $GITHUB_ENV
|
|
else
|
|
echo "TWISTER_NODES=${MATRIX_SIZE}" >> $GITHUB_ENV
|
|
fi
|
|
rm -f testplan.json .testplan
|
|
|
|
- name: Determine matrix size
|
|
id: output-services
|
|
run: |
|
|
if [ "${{github.event_name}}" = "pull_request_target" ]; then
|
|
if [ -n "${TWISTER_NODES}" ]; then
|
|
subset="[$(seq -s',' 1 ${TWISTER_NODES})]"
|
|
else
|
|
subset="[$(seq -s',' 1 ${MATRIX_SIZE})]"
|
|
fi
|
|
size=${TWISTER_NODES}
|
|
elif [ "${{github.event_name}}" = "push" ]; then
|
|
subset="[$(seq -s',' 1 ${PUSH_MATRIX_SIZE})]"
|
|
size=${MATRIX_SIZE}
|
|
elif [ "${{github.event_name}}" = "schedule" -a "${{github.repository}}" = "zephyrproject-rtos/zephyr" ]; then
|
|
subset="[$(seq -s',' 1 ${DAILY_MATRIX_SIZE})]"
|
|
size=${DAILY_MATRIX_SIZE}
|
|
else
|
|
size=0
|
|
fi
|
|
echo "subset=${subset}" >> $GITHUB_OUTPUT
|
|
echo "size=${size}" >> $GITHUB_OUTPUT
|
|
echo "fullrun=${TWISTER_FULL}" >> $GITHUB_OUTPUT
|
|
|
|
twister-build:
|
|
runs-on:
|
|
group: zephyr-runner-v2-linux-x64-4xlarge
|
|
needs: twister-build-prep
|
|
if: needs.twister-build-prep.outputs.size != 0
|
|
container:
|
|
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.27.4.20241026
|
|
options: '--entrypoint /bin/bash'
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
subset: ${{fromJSON(needs.twister-build-prep.outputs.subset)}}
|
|
timeout-minutes: 1440
|
|
env:
|
|
CCACHE_DIR: /node-cache/ccache-zephyr
|
|
CCACHE_REMOTE_STORAGE: "redis://cache-*.keydb-cache.svc.cluster.local|shards=1,2,3"
|
|
CCACHE_REMOTE_ONLY: "true"
|
|
# `--specs` is ignored because ccache is unable to resolve the toolchain specs file path.
|
|
CCACHE_IGNOREOPTIONS: '-specs=* --specs=*'
|
|
BSIM_OUT_PATH: /opt/bsim/
|
|
BSIM_COMPONENTS_PATH: /opt/bsim/components
|
|
TWISTER_COMMON: ' --force-color --inline-logs -v -N -M --retry-failed 3 --timeout-multiplier 2 '
|
|
DAILY_OPTIONS: ' -M --build-only --all --show-footprint'
|
|
PR_OPTIONS: ' --clobber-output --integration'
|
|
PUSH_OPTIONS: ' --clobber-output -M --show-footprint'
|
|
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
|
|
BASE_REF: ${{ github.base_ref }}
|
|
steps:
|
|
- name: Print cloud service information
|
|
run: |
|
|
echo "ZEPHYR_RUNNER_CLOUD_PROVIDER = ${ZEPHYR_RUNNER_CLOUD_PROVIDER}"
|
|
echo "ZEPHYR_RUNNER_CLOUD_NODE = ${ZEPHYR_RUNNER_CLOUD_NODE}"
|
|
echo "ZEPHYR_RUNNER_CLOUD_POD = ${ZEPHYR_RUNNER_CLOUD_POD}"
|
|
|
|
- name: Apply container owner mismatch workaround
|
|
run: |
|
|
# FIXME: The owner UID of the GITHUB_WORKSPACE directory may not
|
|
# match the container user UID because of the way GitHub
|
|
# Actions runner is implemented. Remove this workaround when
|
|
# GitHub comes up with a fundamental fix for this problem.
|
|
git config --global --add safe.directory ${GITHUB_WORKSPACE}
|
|
|
|
- name: Clone cached Zephyr repository
|
|
continue-on-error: true
|
|
run: |
|
|
git clone --shared /repo-cache/zephyrproject/zephyr .
|
|
git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}
|
|
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Environment Setup
|
|
run: |
|
|
if [ "${{github.event_name}}" = "pull_request_target" ]; then
|
|
git config --global user.email "bot@zephyrproject.org"
|
|
git config --global user.name "Zephyr Builder"
|
|
rm -fr ".git/rebase-apply"
|
|
git rebase origin/${BASE_REF}
|
|
git clean -f -d
|
|
git log --pretty=oneline | head -n 10
|
|
fi
|
|
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
|
|
|
west init -l . || true
|
|
west config manifest.group-filter -- +ci,+optional
|
|
west config --global update.narrow true
|
|
west update --path-cache /repo-cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /repo-cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /repo-cache/zephyrproject)
|
|
west forall -c 'git reset --hard HEAD'
|
|
|
|
echo "ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-$( cat SDK_VERSION )" >> $GITHUB_ENV
|
|
|
|
- name: Check Environment
|
|
run: |
|
|
cmake --version
|
|
gcc --version
|
|
cargo --version
|
|
rustup target list --installed
|
|
ls -la
|
|
echo "github.ref: ${{ github.ref }}"
|
|
echo "github.base_ref: ${{ github.base_ref }}"
|
|
echo "github.ref_name: ${{ github.ref_name }}"
|
|
|
|
- name: Set up ccache
|
|
run: |
|
|
mkdir -p ${CCACHE_DIR}
|
|
ccache -M 10G
|
|
ccache -p
|
|
ccache -z -s -vv
|
|
|
|
- name: Update BabbleSim to manifest revision
|
|
run: |
|
|
export BSIM_VERSION=$( west list bsim -f {revision} )
|
|
echo "Manifest points to bsim sha $BSIM_VERSION"
|
|
cd /opt/bsim_west/bsim
|
|
git fetch -n origin ${BSIM_VERSION}
|
|
git -c advice.detachedHead=false checkout ${BSIM_VERSION}
|
|
west update
|
|
make everything -s -j 8
|
|
|
|
- if: github.event_name == 'push'
|
|
name: Run Tests with Twister (Push)
|
|
run: |
|
|
export ZEPHYR_BASE=${PWD}
|
|
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
|
|
./scripts/twister --subset ${{matrix.subset}}/${{ strategy.job-total }} ${TWISTER_COMMON} ${PUSH_OPTIONS}
|
|
if [ "${{matrix.subset}}" = "1" ]; then
|
|
./scripts/zephyr_module.py --twister-out module_tests.args
|
|
if [ -s module_tests.args ]; then
|
|
./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${PUSH_OPTIONS}
|
|
fi
|
|
fi
|
|
|
|
- if: github.event_name == 'pull_request_target'
|
|
name: Run Tests with Twister (Pull Request)
|
|
run: |
|
|
rm -f testplan.json
|
|
export ZEPHYR_BASE=${PWD}
|
|
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
|
|
python3 ./scripts/ci/test_plan.py -c origin/${BASE_REF}.. --pull-request
|
|
./scripts/twister --subset ${{matrix.subset}}/${{ strategy.job-total }} --load-tests testplan.json ${TWISTER_COMMON} ${PR_OPTIONS}
|
|
if [ "${{matrix.subset}}" = "1" -a ${{needs.twister-build-prep.outputs.fullrun}} = 'True' ]; then
|
|
./scripts/zephyr_module.py --twister-out module_tests.args
|
|
if [ -s module_tests.args ]; then
|
|
./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${PR_OPTIONS}
|
|
fi
|
|
fi
|
|
|
|
- if: github.event_name == 'schedule'
|
|
name: Run Tests with Twister (Daily)
|
|
run: |
|
|
export ZEPHYR_BASE=${PWD}
|
|
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
|
|
./scripts/twister --subset ${{matrix.subset}}/${{ strategy.job-total }} ${TWISTER_COMMON} ${DAILY_OPTIONS}
|
|
if [ "${{matrix.subset}}" = "1" ]; then
|
|
./scripts/zephyr_module.py --twister-out module_tests.args
|
|
if [ -s module_tests.args ]; then
|
|
./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${DAILY_OPTIONS}
|
|
fi
|
|
fi
|
|
|
|
- name: Print ccache stats
|
|
if: always()
|
|
run: |
|
|
ccache -s -vv
|
|
|
|
- name: Upload Unit Test Results
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: Unit Test Results (Subset ${{ matrix.subset }})
|
|
if-no-files-found: ignore
|
|
path: |
|
|
twister-out/twister.xml
|
|
twister-out/twister.json
|
|
module_tests/twister.xml
|
|
testplan.json
|
|
|
|
- if: matrix.subset == 1 && github.event_name == 'push'
|
|
name: Save the list of Python packages
|
|
shell: bash
|
|
run: |
|
|
FREEZE_FILE="frozen-requirements.txt"
|
|
timestamp="$(date)"
|
|
version="$(git describe --abbrev=12 --always)"
|
|
echo -e "# Generated at $timestamp ($version)\n" > $FREEZE_FILE
|
|
pip3 freeze | tee -a $FREEZE_FILE
|
|
|
|
- if: matrix.subset == 1 && github.event_name == 'push'
|
|
name: Upload the list of Python packages
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: Frozen PIP package set
|
|
path: |
|
|
frozen-requirements.txt
|
|
|
|
twister-test-results:
|
|
name: "Publish Unit Tests Results"
|
|
env:
|
|
ELASTICSEARCH_KEY: ${{ secrets.ELASTICSEARCH_KEY }}
|
|
ELASTICSEARCH_SERVER: "https://elasticsearch.zephyrproject.io:443"
|
|
needs: twister-build
|
|
runs-on: ubuntu-22.04
|
|
# the build-and-test job might be skipped, we don't need to run this job then
|
|
if: success() || failure()
|
|
|
|
steps:
|
|
# Needed for elasticearch and upload script
|
|
- if: github.event_name == 'push' || github.event_name == 'schedule'
|
|
name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: artifacts
|
|
|
|
- if: github.event_name == 'push' || github.event_name == 'schedule'
|
|
name: Upload to elasticsearch
|
|
run: |
|
|
pip3 install elasticsearch
|
|
# set run date on upload to get consistent and unified data across the matrix.
|
|
run_date=`date --iso-8601=minutes`
|
|
if [ "${{github.event_name}}" = "push" ]; then
|
|
python3 ./scripts/ci/upload_test_results_es.py -r ${run_date} \
|
|
--index zephyr-main-ci-push-1 artifacts/*/*/twister.json
|
|
elif [ "${{github.event_name}}" = "schedule" ]; then
|
|
python3 ./scripts/ci/upload_test_results_es.py -r ${run_date} \
|
|
--index zephyr-main-ci-weekly-1 artifacts/*/*/twister.json
|
|
fi
|
|
|
|
- name: Merge Test Results
|
|
run: |
|
|
pip3 install junitparser junit2html
|
|
junitparser merge artifacts/*/*/twister.xml junit.xml
|
|
junit2html junit.xml junit.html
|
|
|
|
- name: Upload Unit Test Results in HTML
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: HTML Unit Test Results
|
|
if-no-files-found: ignore
|
|
path: |
|
|
junit.html
|
|
|
|
- name: Publish Unit Test Results
|
|
uses: EnricoMi/publish-unit-test-result-action@v2
|
|
with:
|
|
check_name: Unit Test Results
|
|
files: "**/twister.xml"
|
|
comment_mode: off
|
|
twister-status-check:
|
|
if: always()
|
|
name: "Check Twister Status"
|
|
needs:
|
|
- twister-build-prep
|
|
- twister-build
|
|
uses: ./.github/workflows/ready-to-merge.yml
|
|
with:
|
|
needs_context: ${{ toJson(needs) }}
|