1name: Run tests with twister 2 3on: 4 push: 5 branches: 6 - main 7 - v*-branch 8 - collab-* 9 pull_request_target: 10 branches: 11 - main 12 - v*-branch 13 - collab-* 14 schedule: 15 # Run at 03:00 UTC on every Sunday 16 - cron: '0 3 * * 0' 17 18concurrency: 19 group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} 20 cancel-in-progress: true 21 22jobs: 23 twister-build-prep: 24 uses: ./.github/workflows/twister-prep.yaml 25 26 twister-build: 27 runs-on: 28 group: zephyr-runner-v2-linux-x64-4xlarge 29 needs: twister-build-prep 30 if: needs.twister-build-prep.outputs.size != 0 31 container: 32 image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.27.4.20241026 33 options: '--entrypoint /bin/bash' 34 strategy: 35 fail-fast: false 36 matrix: 37 subset: ${{fromJSON(needs.twister-build-prep.outputs.subset)}} 38 timeout-minutes: 1440 39 env: 40 CCACHE_DIR: /node-cache/ccache-zephyr 41 CCACHE_REMOTE_STORAGE: "redis://cache-*.keydb-cache.svc.cluster.local|shards=1,2,3" 42 CCACHE_REMOTE_ONLY: "true" 43 # `--specs` is ignored because ccache is unable to resolve the toolchain specs file path. 44 CCACHE_IGNOREOPTIONS: '-specs=* --specs=*' 45 BSIM_OUT_PATH: /opt/bsim/ 46 BSIM_COMPONENTS_PATH: /opt/bsim/components 47 TWISTER_COMMON: '--no-detailed-test-id --force-color --inline-logs -v -N -M --retry-failed 3 --timeout-multiplier 2 ' 48 WEEKLY_OPTIONS: ' -M --build-only --all --show-footprint --report-filtered' 49 PR_OPTIONS: ' --clobber-output --integration' 50 PUSH_OPTIONS: ' --clobber-output -M --show-footprint --report-filtered' 51 COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} 52 BASE_REF: ${{ github.base_ref }} 53 steps: 54 - name: Print cloud service information 55 run: | 56 echo "ZEPHYR_RUNNER_CLOUD_PROVIDER = ${ZEPHYR_RUNNER_CLOUD_PROVIDER}" 57 echo "ZEPHYR_RUNNER_CLOUD_NODE = ${ZEPHYR_RUNNER_CLOUD_NODE}" 58 echo "ZEPHYR_RUNNER_CLOUD_POD = ${ZEPHYR_RUNNER_CLOUD_POD}" 59 60 - name: Apply container owner mismatch workaround 61 run: | 62 # FIXME: The owner UID of the GITHUB_WORKSPACE directory may not 63 # match the container user UID because of the way GitHub 64 # Actions runner is implemented. Remove this workaround when 65 # GitHub comes up with a fundamental fix for this problem. 66 git config --global --add safe.directory ${GITHUB_WORKSPACE} 67 68 - name: Clone cached Zephyr repository 69 continue-on-error: true 70 run: | 71 git clone --shared /repo-cache/zephyrproject/zephyr . 72 git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} 73 74 - name: Checkout 75 uses: actions/checkout@v4 76 with: 77 ref: ${{ github.event.pull_request.head.sha }} 78 fetch-depth: 0 79 persist-credentials: false 80 81 - name: Environment Setup 82 run: | 83 if [ "${{github.event_name}}" = "pull_request_target" ]; then 84 git config --global user.email "bot@zephyrproject.org" 85 git config --global user.name "Zephyr Builder" 86 rm -fr ".git/rebase-apply" 87 rm -fr ".git/rebase-merge" 88 git rebase origin/${BASE_REF} 89 git clean -f -d 90 git log --pretty=oneline | head -n 10 91 fi 92 echo "$HOME/.local/bin" >> $GITHUB_PATH 93 echo "$HOME/.cargo/bin" >> $GITHUB_PATH 94 95 west init -l . || true 96 west config manifest.group-filter -- +ci,+optional 97 west config --global update.narrow true 98 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) 99 west forall -c 'git reset --hard HEAD' 100 101 echo "ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-$( cat SDK_VERSION )" >> $GITHUB_ENV 102 103 - name: Check Environment 104 run: | 105 cmake --version 106 gcc --version 107 cargo --version 108 rustup target list --installed 109 ls -la 110 echo "github.ref: ${{ github.ref }}" 111 echo "github.base_ref: ${{ github.base_ref }}" 112 echo "github.ref_name: ${{ github.ref_name }}" 113 114 - name: Set up ccache 115 run: | 116 mkdir -p ${CCACHE_DIR} 117 ccache -M 10G 118 ccache -p 119 ccache -z -s -vv 120 121 - name: Update BabbleSim to manifest revision 122 run: | 123 export BSIM_VERSION=$( west list bsim -f {revision} ) 124 echo "Manifest points to bsim sha $BSIM_VERSION" 125 cd /opt/bsim_west/bsim 126 git fetch -n origin ${BSIM_VERSION} 127 git -c advice.detachedHead=false checkout ${BSIM_VERSION} 128 west update 129 make everything -s -j 8 130 131 - if: github.event_name == 'push' 132 name: Run Tests with Twister (Push) 133 id: run_twister 134 run: | 135 export ZEPHYR_BASE=${PWD} 136 export ZEPHYR_TOOLCHAIN_VARIANT=zephyr 137 ./scripts/twister --subset ${{matrix.subset}}/${{ strategy.job-total }} ${TWISTER_COMMON} ${PUSH_OPTIONS} 138 if [ "${{matrix.subset}}" = "1" ]; then 139 ./scripts/zephyr_module.py --twister-out module_tests.args 140 if [ -s module_tests.args ]; then 141 ./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${PUSH_OPTIONS} 142 fi 143 fi 144 145 - if: github.event_name == 'pull_request_target' 146 name: Run Tests with Twister (Pull Request) 147 id: run_twister_pr 148 run: | 149 rm -f testplan.json 150 export ZEPHYR_BASE=${PWD} 151 export ZEPHYR_TOOLCHAIN_VARIANT=zephyr 152 python3 ./scripts/ci/test_plan.py -c origin/${BASE_REF}.. --pull-request --no-detailed-test-id 153 ./scripts/twister --subset ${{matrix.subset}}/${{ strategy.job-total }} --load-tests testplan.json ${TWISTER_COMMON} ${PR_OPTIONS} 154 if [ "${{matrix.subset}}" = "1" -a ${{needs.twister-build-prep.outputs.fullrun}} = 'True' ]; then 155 ./scripts/zephyr_module.py --twister-out module_tests.args 156 if [ -s module_tests.args ]; then 157 ./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${PR_OPTIONS} 158 fi 159 fi 160 161 - if: github.event_name == 'schedule' 162 name: Run Tests with Twister (Daily) 163 id: run_twister_sched 164 run: | 165 export ZEPHYR_BASE=${PWD} 166 export ZEPHYR_TOOLCHAIN_VARIANT=zephyr 167 ./scripts/twister --subset ${{matrix.subset}}/${{ strategy.job-total }} ${TWISTER_COMMON} ${WEEKLY_OPTIONS} 168 if [ "${{matrix.subset}}" = "1" ]; then 169 ./scripts/zephyr_module.py --twister-out module_tests.args 170 if [ -s module_tests.args ]; then 171 ./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${WEEKLY_OPTIONS} 172 fi 173 fi 174 175 - name: Print ccache stats 176 if: always() 177 run: | 178 ccache -s -vv 179 180 - name: Upload Unit Test Results 181 if: always() 182 uses: actions/upload-artifact@v4 183 with: 184 name: Unit Test Results (Subset ${{ matrix.subset }}) 185 if-no-files-found: ignore 186 path: | 187 twister-out/twister.xml 188 twister-out/twister.json 189 module_tests/twister.xml 190 testplan.json 191 192 - if: matrix.subset == 1 && github.event_name == 'push' 193 name: Save the list of Python packages 194 shell: bash 195 run: | 196 FREEZE_FILE="frozen-requirements.txt" 197 timestamp="$(date)" 198 version="$(git describe --abbrev=12 --always)" 199 echo -e "# Generated at $timestamp ($version)\n" > $FREEZE_FILE 200 pip freeze | tee -a $FREEZE_FILE 201 202 - if: matrix.subset == 1 && github.event_name == 'push' 203 name: Upload the list of Python packages 204 uses: actions/upload-artifact@v4 205 with: 206 name: Frozen PIP package set 207 path: | 208 frozen-requirements.txt 209 210 twister-test-results: 211 name: "Publish Unit Tests Results" 212 needs: 213 - twister-build 214 runs-on: ubuntu-22.04 215 # the build-and-test job might be skipped, we don't need to run this job then 216 if: success() || failure() 217 218 steps: 219 - name: Download Artifacts 220 uses: actions/download-artifact@v4 221 with: 222 path: artifacts 223 224 - name: Merge Test Results 225 run: | 226 pip install junitparser junit2html 227 junitparser merge artifacts/*/*/twister.xml junit.xml 228 junit2html junit.xml junit.html 229 230 - name: Upload Unit Test Results in HTML 231 if: always() 232 uses: actions/upload-artifact@v4 233 with: 234 name: HTML Unit Test Results 235 if-no-files-found: ignore 236 path: | 237 junit.html 238 239 - name: Publish Unit Test Results 240 uses: EnricoMi/publish-unit-test-result-action@v2 241 with: 242 check_name: Unit Test Results 243 files: "**/twister.xml" 244 comment_mode: off 245 twister-status-check: 246 if: always() 247 name: "Check Twister Status" 248 needs: 249 - twister-build-prep 250 - twister-build 251 uses: ./.github/workflows/ready-to-merge.yml 252 with: 253 needs_context: ${{ toJson(needs) }} 254