88 branches :
99 - main
1010
11+ # Cancel in-progress runs for the same PR/branch
12+ concurrency :
13+ group : ${{ github.workflow }}-${{ github.ref }}
14+ cancel-in-progress : true
15+
16+ # Least-privilege permissions
17+ permissions :
18+ contents : read
19+
1120jobs :
12- matrix-tests :
21+ # Fast-running lint job to catch formatting issues early
22+ lint :
1323 runs-on : ubuntu-24.04
14- name : Test on ${{ matrix.toolchain }} toolchain
24+ name : Code Quality Checks
25+ timeout-minutes : 10
1526
16- strategy :
17- fail-fast : false
18- matrix :
19- toolchain : [gnu, llvm]
27+ env :
28+ CLANG_FORMAT_VERSION : 18
2029
2130 steps :
2231 - name : Checkout
23- uses : actions/checkout@v4
32+ uses : actions/checkout@v5
2433
25- - name : Install base dependencies
34+ - name : Install linting tools
2635 run : |
2736 sudo apt-get update
28- sudo apt-get install -y build-essential qemu-system-riscv32 wget clang-format-18 shfmt
37+ sudo apt-get install -y --no-install-recommends clang-format-${{ env.CLANG_FORMAT_VERSION }} shfmt
2938
3039 - name : Check code formatting
3140 run : .ci/check-format.sh
3241
3342 - name : Check newline at end of files
3443 run : .ci/check-newline.sh
3544
45+ # Build and test matrix - runs in parallel after lint passes
46+ # NOTE: LLVM toolchain performs build-only validation (no runtime tests)
47+ # to verify cross-toolchain compilation compatibility. GNU toolchain
48+ # runs the full test suite including application and functional tests.
49+ matrix-tests :
50+ runs-on : ubuntu-24.04
51+ name : Test on ${{ matrix.toolchain }} toolchain
52+ needs : lint
53+ timeout-minutes : 30
54+
55+ strategy :
56+ fail-fast : false
57+ matrix :
58+ toolchain : [gnu, llvm]
59+
60+ steps :
61+ - name : Checkout
62+ uses : actions/checkout@v5
63+
64+ - name : Cache toolchain
65+ uses : actions/cache@v4
66+ id : cache-toolchain
67+ with :
68+ path : riscv
69+ key : ${{ runner.os }}-${{ matrix.toolchain }}-toolchain-${{ hashFiles('.ci/setup-toolchain.sh') }}
70+ restore-keys : |
71+ ${{ runner.os }}-${{ matrix.toolchain }}-toolchain-
72+
73+ - name : Install build dependencies
74+ run : |
75+ sudo apt-get update
76+ sudo apt-get install -y --no-install-recommends build-essential qemu-system-riscv32 wget
77+
3678 - name : Setup ${{ matrix.toolchain }} toolchain
79+ if : steps.cache-toolchain.outputs.cache-hit != 'true'
3780 run : .ci/setup-toolchain.sh ${{ matrix.toolchain }}
3881
82+ - name : Configure toolchain environment
83+ if : steps.cache-toolchain.outputs.cache-hit == 'true'
84+ run : |
85+ echo "$PWD/riscv/bin" >> "$GITHUB_PATH"
86+ echo "CROSS_COMPILE=riscv32-unknown-elf-" >> "$GITHUB_ENV"
87+ echo "TOOLCHAIN_TYPE=${{ matrix.toolchain }}" >> "$GITHUB_ENV"
88+
3989 - name : Verify toolchain installation
4090 run : |
4191 if [ "${{ matrix.toolchain }}" = "gnu" ]; then
4999
50100 - name : Build Kernel
51101 run : |
102+ set -euo pipefail
52103 make clean
53- make
104+ make -j$(nproc)
54105 env :
55106 TOOLCHAIN_TYPE : ${{ matrix.toolchain }}
56107
59110 continue-on-error : true
60111 if : matrix.toolchain == 'gnu'
61112 run : |
113+ set -euo pipefail
62114 output=$(.ci/run-app-tests.sh 2>&1) || true
63115 echo "TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
64116 echo "$output" >> $GITHUB_OUTPUT
71123 continue-on-error : true
72124 if : matrix.toolchain == 'gnu'
73125 run : |
126+ set -euo pipefail
74127 output=$(.ci/run-functional-tests.sh 2>&1) || true
75128 echo "FUNCTIONAL_TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
76129 echo "$output" >> $GITHUB_OUTPUT
81134 - name : Collect Test Data
82135 if : always()
83136 run : |
137+ set -euo pipefail
84138 if [ "${{ matrix.toolchain }}" = "llvm" ]; then
85139 # LLVM: Build-only validation, skip tests
86140 mkdir -p test-results
@@ -103,7 +157,7 @@ jobs:
103157 echo "mutex:mutual_exclusion=skipped" >> test-results/functional_criteria_data
104158 echo "mutex:data_consistency=skipped" >> test-results/functional_criteria_data
105159 echo "mutex:overall=skipped" >> test-results/functional_criteria_data
106- echo "semaphore:all_tests_passed! =skipped" >> test-results/functional_criteria_data
160+ echo "semaphore:all_tests_passed=skipped" >> test-results/functional_criteria_data
107161
108162 echo "LLVM toolchain: Build validation only (tests skipped)"
109163 else
@@ -117,13 +171,18 @@ jobs:
117171 with :
118172 name : test-results-${{ matrix.toolchain }}
119173 path : test-results/
120- retention-days : 1
174+ retention-days : 3
175+ if-no-files-found : warn
121176
122177 # Comprehensive test summary with detailed reporting
123178 test-summary :
124179 runs-on : ubuntu-24.04
125- needs : matrix-tests
180+ needs : [lint, matrix-tests]
126181 if : always()
182+ timeout-minutes : 15
183+ permissions :
184+ contents : read
185+ pull-requests : write
127186
128187 steps :
129188 - name : Checkout
@@ -136,41 +195,66 @@ jobs:
136195 path : all-test-results/
137196
138197 - name : Generate Test Summary
198+ id : generate_summary
139199 continue-on-error : true
140200 run : |
201+ echo "Aggregating test results..."
141202 .ci/ci-tools.sh aggregate all-test-results test-summary.toml
142- cat test-summary.toml
203+
204+ if [ -f test-summary.toml ]; then
205+ echo "summary_generated=true" >> $GITHUB_OUTPUT
206+ echo "Test Summary:"
207+ cat test-summary.toml
208+ else
209+ echo "summary_generated=false" >> $GITHUB_OUTPUT
210+ echo "⚠️ Warning: test-summary.toml not generated"
211+ fi
143212
144213 - name : Upload Test Summary
145- if : always()
214+ if : always() && steps.generate_summary.outputs.summary_generated == 'true'
146215 uses : actions/upload-artifact@v4
147216 with :
148217 name : test-summary
149218 path : test-summary.toml
150219 retention-days : 30
220+ if-no-files-found : error
151221
152222 - name : Comment PR with Formatted Summary
153- if : always() && github.event_name == 'pull_request'
223+ if : always() && github.event_name == 'pull_request' && steps.generate_summary.outputs.summary_generated == 'true'
154224 continue-on-error : true
155225 run : |
226+ echo "Posting summary to PR #${{ github.event.number }}..."
156227 .ci/ci-tools.sh post-comment test-summary.toml ${{ github.event.number }}
157228 env :
158229 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
159230
160231 - name : Final Status Check
161232 run : |
233+ set -euo pipefail
234+ echo "=== Final CI Status Check ==="
235+
162236 if [ ! -f test-summary.toml ]; then
163- echo "Error: test-summary.toml not found"
237+ echo "❌ Error: test-summary.toml not found"
238+ echo "CI infrastructure issue - check test aggregation step"
164239 exit 1
165240 fi
166241
167242 overall_status=$(grep -A 1 '^\[summary\]' test-summary.toml | grep 'status =' | cut -d'"' -f2)
168243 echo "Overall test status: $overall_status"
169244
245+ # Extract failure details if available
246+ if [ "$overall_status" != "passed" ]; then
247+ echo ""
248+ echo "=== Failure Details ==="
249+ grep -E '(failed|error|skipped)' test-summary.toml || true
250+ fi
251+
170252 if [ "$overall_status" = "passed" ]; then
171- echo "✅ All tests passed"
253+ echo ""
254+ echo "✅ All tests passed successfully"
172255 exit 0
173256 else
174- echo "❌ Tests failed"
257+ echo ""
258+ echo "❌ Tests failed - see details above"
175259 exit 1
176260 fi
0 commit comments