@@ -16,7 +16,6 @@ concurrency:
1616# Least-privilege permissions
1717permissions :
1818 contents : read
19- actions : write # Required for actions/cache@v4 to save/restore cache
2019
2120jobs :
2221 # Fast-running lint job to catch formatting issues early
@@ -33,126 +32,111 @@ jobs:
3332 uses : actions/checkout@v6
3433
3534 - name : Install linting tools
36- run : |
37- sudo apt-get update
38- sudo apt-get install -y --no-install-recommends clang-format-${{ env.CLANG_FORMAT_VERSION }} shfmt
35+ run : sudo apt-get update && sudo apt-get install -y --no-install-recommends clang-format-${{ env.CLANG_FORMAT_VERSION }} shfmt
3936
4037 - name : Check code formatting
4138 run : .ci/check-format.sh
4239
4340 - name : Check newline at end of files
4441 run : .ci/check-newline.sh
4542
46- # Build and test matrix - runs in parallel after lint passes
47- # NOTE: LLVM toolchain performs build-only validation (no runtime tests)
48- # to verify cross-toolchain compilation compatibility. GNU toolchain
49- # runs the full test suite including application and functional tests.
43+ # Build and test matrix - GNU and LLVM run in parallel after lint passes
44+ # GNU: Full test suite (build + app tests + functional tests)
45+ # LLVM: Build-only validation (verifies cross-toolchain compatibility)
5046 matrix-tests :
5147 runs-on : ubuntu-24.04
52- name : Test on ${{ matrix.toolchain }} toolchain
48+ name : ${{ matrix.toolchain }} toolchain
5349 needs : lint
5450 timeout-minutes : 30
5551
5652 strategy :
5753 fail-fast : false
5854 matrix :
59- toolchain : [gnu, llvm ]
55+ toolchain : [GNU, LLVM ]
6056
6157 steps :
6258 - name : Checkout
6359 uses : actions/checkout@v6
6460
61+ - name : Install QEMU
62+ if : matrix.toolchain == 'GNU'
63+ run : sudo apt-get update && sudo apt-get install -y --no-install-recommends qemu-system-riscv32
64+
65+ - name : Set toolchain name
66+ id : toolchain
67+ run : echo "name=$(echo '${{ matrix.toolchain }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
68+
6569 - name : Cache toolchain
66- uses : actions/cache@v4
70+ uses : actions/cache@v5
6771 id : cache-toolchain
6872 with :
6973 path : riscv
70- key : ${{ runner.os }}-${{ matrix.toolchain }}-toolchain-${{ hashFiles('.ci/setup-toolchain.sh') }}
71- restore-keys : |
72- ${{ runner.os }}-${{ matrix.toolchain }}-toolchain-
73-
74- - name : Install build dependencies
75- run : |
76- sudo apt-get update
77- sudo apt-get install -y --no-install-recommends build-essential qemu-system-riscv32 wget
74+ key : riscv32-${{ steps.toolchain.outputs.name }}-${{ hashFiles('.ci/setup-toolchain.sh') }}
7875
7976 - name : Setup ${{ matrix.toolchain }} toolchain
8077 if : steps.cache-toolchain.outputs.cache-hit != 'true'
81- run : .ci/setup-toolchain.sh ${{ matrix .toolchain }}
78+ run : .ci/setup-toolchain.sh ${{ steps .toolchain.outputs.name }}
8279
8380 - name : Configure toolchain environment
84- if : steps.cache-toolchain.outputs.cache-hit == 'true'
8581 run : |
8682 echo "$PWD/riscv/bin" >> "$GITHUB_PATH"
8783 echo "CROSS_COMPILE=riscv32-unknown-elf-" >> "$GITHUB_ENV"
88- echo "TOOLCHAIN_TYPE=${{ matrix .toolchain }}" >> "$GITHUB_ENV"
84+ echo "TOOLCHAIN_TYPE=${{ steps .toolchain.outputs.name }}" >> "$GITHUB_ENV"
8985
90- - name : Verify toolchain installation
86+ - name : Verify toolchain
9187 run : |
92- if [ "${{ matrix.toolchain }}" = "gnu " ]; then
88+ if [ "${{ matrix.toolchain }}" = "GNU " ]; then
9389 riscv32-unknown-elf-gcc --version
90+ qemu-system-riscv32 --version
9491 else
95- # LLVM toolchain fallback: try system llvm-objdump
96- riscv32-unknown-elf-clang --version || clang --version
97- riscv32-unknown-elf-llvm-objdump --version || llvm-objdump --version
92+ riscv32-unknown-elf-clang --version
9893 fi
99- qemu-system-riscv32 --version
10094
101- - name : Build Kernel
102- run : |
103- set -euo pipefail
104- make clean
105- make -j$(nproc)
106- env :
107- TOOLCHAIN_TYPE : ${{ matrix.toolchain }}
95+ - name : Build kernel
96+ run : make -j$(nproc)
10897
109- - name : Run All Apps
98+ - name : Run app tests
11099 id : test
111100 continue-on-error : true
112- if : matrix.toolchain == 'gnu '
101+ if : matrix.toolchain == 'GNU '
113102 run : |
114- set -euo pipefail
115103 output=$(.ci/run-app-tests.sh 2>&1) || true
116- echo "TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
104+ delimiter=$(openssl rand -hex 8)
105+ echo "TEST_OUTPUT<<$delimiter" >> $GITHUB_OUTPUT
117106 echo "$output" >> $GITHUB_OUTPUT
118- echo "EOF" >> $GITHUB_OUTPUT
119- env :
120- TOOLCHAIN_TYPE : ${{ matrix.toolchain }}
107+ echo "$delimiter" >> $GITHUB_OUTPUT
121108
122- - name : Run Functional Tests
109+ - name : Run functional tests
123110 id : functional_test
124111 continue-on-error : true
125- if : matrix.toolchain == 'gnu '
112+ if : matrix.toolchain == 'GNU '
126113 run : |
127- set -euo pipefail
128114 output=$(.ci/run-functional-tests.sh 2>&1) || true
129- echo "FUNCTIONAL_TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
115+ delimiter=$(openssl rand -hex 8)
116+ echo "FUNCTIONAL_TEST_OUTPUT<<$delimiter" >> $GITHUB_OUTPUT
130117 echo "$output" >> $GITHUB_OUTPUT
131- echo "EOF" >> $GITHUB_OUTPUT
132- env :
133- TOOLCHAIN_TYPE : ${{ matrix.toolchain }}
118+ echo "$delimiter" >> $GITHUB_OUTPUT
134119
135- - name : Collect Test Data
120+ - name : Collect test data
136121 if : always()
137122 run : |
138123 set -euo pipefail
139124 COMMIT_SHA="${{ github.sha }}"
140125 COMMIT_SHORT=$(git rev-parse --short HEAD 2>/dev/null || echo "${{ github.sha }}" | cut -c1-7)
141126 GITHUB_REPO="${{ github.repository }}"
142127
143- if [ "${{ matrix.toolchain }}" = "llvm " ]; then
128+ if [ "${{ matrix.toolchain }}" = "LLVM " ]; then
144129 # LLVM: Build-only validation, skip tests
145130 mkdir -p test-results
146- echo "${{ matrix .toolchain }}" > test-results/toolchain
131+ echo "${{ steps .toolchain.outputs.name }}" > test-results/toolchain
147132 echo "$COMMIT_SHA" > test-results/commit_sha
148133 echo "$COMMIT_SHORT" > test-results/commit_short
149134 echo "$GITHUB_REPO" > test-results/github_repo
150135 echo "skipped" > test-results/crash_exit_code
151136 echo "skipped" > test-results/functional_exit_code
152137
153138 # Generate skipped status for all apps
154- apps=$(find app/ -name "*.c" -exec basename {} .c \; | sort)
155- for app in $apps; do
139+ for app in $(find app/ -name "*.c" -exec basename {} .c \; | sort); do
156140 echo "$app=skipped" >> test-results/apps_data
157141 done
158142
@@ -161,33 +145,35 @@ jobs:
161145 echo "semaphore=skipped" >> test-results/functional_data
162146
163147 # Generate skipped status for functional test criteria
164- echo "mutex:fairness=skipped" > test-results/functional_criteria_data
165- echo "mutex:mutual_exclusion=skipped" >> test-results/functional_criteria_data
166- echo "mutex:data_consistency=skipped" >> test-results/functional_criteria_data
167- echo "mutex:overall=skipped" >> test-results/functional_criteria_data
168- echo "semaphore:overall=skipped" >> test-results/functional_criteria_data
169-
170- echo "LLVM toolchain: Build validation only (tests skipped)"
148+ printf '%s\n' \
149+ "mutex:fairness=skipped" \
150+ "mutex:mutual_exclusion=skipped" \
151+ "mutex:data_consistency=skipped" \
152+ "mutex:overall=skipped" \
153+ "semaphore:overall=skipped" \
154+ > test-results/functional_criteria_data
155+
156+ echo "LLVM: Build validation only (tests skipped)"
171157 else
172158 # GNU: Full test suite
173- .ci/ci-tools.sh collect-data "${{ matrix .toolchain }}" "$COMMIT_SHA" "$COMMIT_SHORT" "$GITHUB_REPO" "${{ steps.test.outputs.TEST_OUTPUT }}" "${{ steps.functional_test.outputs.FUNCTIONAL_TEST_OUTPUT }}"
159+ .ci/ci-tools.sh collect-data "${{ steps .toolchain.outputs.name }}" "$COMMIT_SHA" "$COMMIT_SHORT" "$GITHUB_REPO" "${{ steps.test.outputs.TEST_OUTPUT }}" "${{ steps.functional_test.outputs.FUNCTIONAL_TEST_OUTPUT }}"
174160 fi
175161
176- - name : Upload Test Results
162+ - name : Upload test results
177163 if : always()
178- uses : actions/upload-artifact@v4
164+ uses : actions/upload-artifact@v6
179165 with :
180166 name : test-results-${{ matrix.toolchain }}
181167 path : test-results/
182- retention-days : 3
168+ retention-days : 7
183169 if-no-files-found : warn
184170
185- # Comprehensive test summary with detailed reporting
171+ # Aggregate results from all toolchain builds
186172 test-summary :
187173 runs-on : ubuntu-24.04
188- needs : [lint, matrix-tests]
174+ needs : matrix-tests
189175 if : always()
190- timeout-minutes : 15
176+ timeout-minutes : 10
191177 permissions :
192178 contents : read
193179 pull-requests : write
@@ -196,73 +182,53 @@ jobs:
196182 - name : Checkout
197183 uses : actions/checkout@v6
198184
199- - name : Download Test Results
200- uses : actions/download-artifact@v4
185+ - name : Download test results
186+ uses : actions/download-artifact@v7
201187 with :
202188 pattern : test-results-*
203189 path : all-test-results/
204190
205- - name : Generate Test Summary
206- id : generate_summary
207- continue-on-error : true
191+ - name : Generate test summary
192+ id : summary
208193 run : |
209- echo "Aggregating test results..."
210194 .ci/ci-tools.sh aggregate all-test-results test-summary.toml
211-
212195 if [ -f test-summary.toml ]; then
213- echo "summary_generated=true" >> $GITHUB_OUTPUT
214- echo "Test Summary:"
196+ echo "generated=true" >> $GITHUB_OUTPUT
215197 cat test-summary.toml
216198 else
217- echo "summary_generated =false" >> $GITHUB_OUTPUT
218- echo "⚠️ Warning: test-summary.toml not generated"
199+ echo "generated =false" >> $GITHUB_OUTPUT
200+ echo "Warning: test-summary.toml not generated"
219201 fi
220202
221- - name : Upload Test Summary
222- if : always() && steps.generate_summary .outputs.summary_generated == 'true'
223- uses : actions/upload-artifact@v4
203+ - name : Upload test summary
204+ if : steps.summary .outputs.generated == 'true'
205+ uses : actions/upload-artifact@v6
224206 with :
225207 name : test-summary
226208 path : test-summary.toml
227209 retention-days : 30
228- if-no-files-found : error
229210
230- - name : Comment PR with Formatted Summary
231- if : always() && github.event_name == 'pull_request' && steps.generate_summary .outputs.summary_generated == 'true'
211+ - name : Post PR comment
212+ if : github.event_name == 'pull_request' && steps.summary .outputs.generated == 'true'
232213 continue-on-error : true
233- run : |
234- echo "Posting summary to PR #${{ github.event.number }}..."
235- .ci/ci-tools.sh post-comment test-summary.toml ${{ github.event.number }}
214+ run : .ci/ci-tools.sh post-comment test-summary.toml ${{ github.event.number }}
236215 env :
237216 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
238217
239- - name : Final Status Check
218+ - name : Check final status
240219 run : |
241- set -euo pipefail
242- echo "=== Final CI Status Check ==="
243-
244220 if [ ! -f test-summary.toml ]; then
245- echo "❌ Error: test-summary.toml not found"
246- echo "CI infrastructure issue - check test aggregation step"
221+ echo "Error: test-summary.toml not found"
247222 exit 1
248223 fi
249224
250- overall_status=$(grep -A 1 '^\[summary\]' test-summary.toml | grep 'status =' | cut -d'"' -f2)
251- echo "Overall test status: $overall_status"
252-
253- # Extract failure details if available
254- if [ "$overall_status" != "passed" ]; then
255- echo ""
256- echo "=== Failure Details ==="
257- grep -E '(failed|error|skipped)' test-summary.toml || true
258- fi
225+ status=$(grep -A1 '^\[summary\]' test-summary.toml | grep 'status =' | cut -d'"' -f2)
226+ echo "Overall status: $status"
259227
260- if [ "$overall_status" = "passed" ]; then
261- echo ""
262- echo "✅ All tests passed successfully"
263- exit 0
228+ if [ "$status" = "passed" ]; then
229+ echo "All tests passed"
264230 else
265- echo ""
266- echo "❌ Tests failed - see details above"
231+ echo "Tests failed "
232+ grep -E '( failed|error)' test-summary.toml || true
267233 exit 1
268234 fi
0 commit comments