Skip to content

Commit c81c156

Browse files
committed
CI: Refine workflow for performance/reliability
This improves CI pipeline with toolchain caching, parallel builds, and error handling. It separates lint job to avoid duplication across matrix builds, adding concurrency control, job timeouts, and least-privilege permissions.
1 parent b106e8c commit c81c156

File tree

1 file changed

+103
-19
lines changed

1 file changed

+103
-19
lines changed

.github/workflows/ci.yml

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,84 @@ on:
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+
1120
jobs:
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
@@ -49,8 +99,9 @@ jobs:
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

@@ -59,6 +110,7 @@ jobs:
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
@@ -71,6 +123,7 @@ jobs:
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
@@ -81,6 +134,7 @@ jobs:
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

Comments
 (0)