370 lines
15 KiB
YAML
370 lines
15 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: zephyr-runner-linux-x64-4xlarge
|
|
container:
|
|
image: ghcr.io/zephyrproject-rtos/ci:v0.26.7
|
|
options: '--entrypoint /bin/bash'
|
|
volumes:
|
|
- /repo-cache/zephyrproject:/github/cache/zephyrproject
|
|
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: 15
|
|
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: Clone cached Zephyr repository
|
|
if: github.event_name == 'pull_request_target'
|
|
continue-on-error: true
|
|
run: |
|
|
git clone --shared /github/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 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 /github/cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/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: zephyr-runner-linux-x64-4xlarge
|
|
needs: twister-build-prep
|
|
if: needs.twister-build-prep.outputs.size != 0
|
|
container:
|
|
image: ghcr.io/zephyrproject-rtos/ci:v0.26.7
|
|
options: '--entrypoint /bin/bash'
|
|
volumes:
|
|
- /repo-cache/zephyrproject:/github/cache/zephyrproject
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
subset: ${{fromJSON(needs.twister-build-prep.outputs.subset)}}
|
|
env:
|
|
BSIM_OUT_PATH: /opt/bsim/
|
|
BSIM_COMPONENTS_PATH: /opt/bsim/components
|
|
TWISTER_COMMON: ' --force-color --inline-logs -v -N -M --retry-failed 3 '
|
|
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: 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 /github/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 log --pretty=oneline | head -n 10
|
|
fi
|
|
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
|
|
west init -l . || true
|
|
west config manifest.group-filter -- +ci,+optional
|
|
west config --global update.narrow true
|
|
west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/cache/zephyrproject)
|
|
west forall -c 'git reset --hard HEAD'
|
|
|
|
# Hotfix until we have kitware ninja in the docker image.
|
|
# Needed for full functionality of the job server functionality in twister which only works with
|
|
# kitware supplied ninja version.
|
|
wget -c https://github.com/Kitware/ninja/releases/download/v1.11.1.g95dee.kitware.jobserver-1/ninja-1.11.1.g95dee.kitware.jobserver-1_x86_64-linux-gnu.tar.gz -O - | tar xz --strip-components=1
|
|
sudo cp ninja /usr/local/bin
|
|
|
|
echo "ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-$( cat SDK_VERSION )" >> $GITHUB_ENV
|
|
|
|
- name: Check Environment
|
|
run: |
|
|
cmake --version
|
|
gcc --version
|
|
ls -la
|
|
echo "github.ref: ${{ github.ref }}"
|
|
echo "github.base_ref: ${{ github.base_ref }}"
|
|
echo "github.ref_name: ${{ github.ref_name }}"
|
|
|
|
- name: Prepare ccache timestamp/data
|
|
id: ccache_cache_timestamp
|
|
shell: cmake -P {0}
|
|
run: |
|
|
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
|
string(REPLACE "/" "_" repo ${{github.repository}})
|
|
string(REPLACE "-" "_" repo2 ${repo})
|
|
file(APPEND $ENV{GITHUB_OUTPUT} "repo=${repo2}\n")
|
|
|
|
- name: use cache
|
|
id: cache-ccache
|
|
uses: zephyrproject-rtos/action-s3-cache@v1.2.0
|
|
continue-on-error: true
|
|
with:
|
|
key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-${{github.event_name}}-${{ matrix.subset }}-ccache
|
|
path: /github/home/.cache/ccache
|
|
aws-s3-bucket: ccache.zephyrproject.org
|
|
aws-access-key-id: ${{ vars.AWS_CCACHE_ACCESS_KEY_ID }}
|
|
aws-secret-access-key: ${{ secrets.AWS_CCACHE_SECRET_ACCESS_KEY }}
|
|
aws-region: us-east-2
|
|
|
|
- name: ccache stats initial
|
|
run: |
|
|
mkdir -p /github/home/.cache
|
|
test -d github/home/.cache/ccache && rm -rf /github/home/.cache/ccache && mv github/home/.cache/ccache /github/home/.cache/ccache
|
|
ccache -M 10G -s
|
|
|
|
- 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: ccache stats post
|
|
run: |
|
|
ccache -p
|
|
ccache -s
|
|
|
|
- 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 opensearch 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 opensearch
|
|
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) }}
|