-
Notifications
You must be signed in to change notification settings - Fork 38
268 lines (229 loc) · 8.94 KB
/
ci.yml
File metadata and controls
268 lines (229 loc) · 8.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
name: Linmo CI
on:
push:
branches:
- main
pull_request:
branches:
- main
# Cancel in-progress runs for the same PR/branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Least-privilege permissions
permissions:
contents: read
actions: write # Required for actions/cache@v4 to save/restore cache
jobs:
# Fast-running lint job to catch formatting issues early
lint:
runs-on: ubuntu-24.04
name: Code Quality Checks
timeout-minutes: 10
env:
CLANG_FORMAT_VERSION: 18
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install linting tools
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends clang-format-${{ env.CLANG_FORMAT_VERSION }} shfmt
- name: Check code formatting
run: .ci/check-format.sh
- name: Check newline at end of files
run: .ci/check-newline.sh
# Build and test matrix - runs in parallel after lint passes
# NOTE: LLVM toolchain performs build-only validation (no runtime tests)
# to verify cross-toolchain compilation compatibility. GNU toolchain
# runs the full test suite including application and functional tests.
matrix-tests:
runs-on: ubuntu-24.04
name: Test on ${{ matrix.toolchain }} toolchain
needs: lint
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
toolchain: [gnu, llvm]
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Cache toolchain
uses: actions/cache@v4
id: cache-toolchain
with:
path: riscv
key: ${{ runner.os }}-${{ matrix.toolchain }}-toolchain-${{ hashFiles('.ci/setup-toolchain.sh') }}
restore-keys: |
${{ runner.os }}-${{ matrix.toolchain }}-toolchain-
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends build-essential qemu-system-riscv32 wget
- name: Setup ${{ matrix.toolchain }} toolchain
if: steps.cache-toolchain.outputs.cache-hit != 'true'
run: .ci/setup-toolchain.sh ${{ matrix.toolchain }}
- name: Configure toolchain environment
if: steps.cache-toolchain.outputs.cache-hit == 'true'
run: |
echo "$PWD/riscv/bin" >> "$GITHUB_PATH"
echo "CROSS_COMPILE=riscv32-unknown-elf-" >> "$GITHUB_ENV"
echo "TOOLCHAIN_TYPE=${{ matrix.toolchain }}" >> "$GITHUB_ENV"
- name: Verify toolchain installation
run: |
if [ "${{ matrix.toolchain }}" = "gnu" ]; then
riscv32-unknown-elf-gcc --version
else
# LLVM toolchain fallback: try system llvm-objdump
riscv32-unknown-elf-clang --version || clang --version
riscv32-unknown-elf-llvm-objdump --version || llvm-objdump --version
fi
qemu-system-riscv32 --version
- name: Build Kernel
run: |
set -euo pipefail
make clean
make -j$(nproc)
env:
TOOLCHAIN_TYPE: ${{ matrix.toolchain }}
- name: Run All Apps
id: test
continue-on-error: true
if: matrix.toolchain == 'gnu'
run: |
set -euo pipefail
output=$(.ci/run-app-tests.sh 2>&1) || true
echo "TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
echo "$output" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
env:
TOOLCHAIN_TYPE: ${{ matrix.toolchain }}
- name: Run Functional Tests
id: functional_test
continue-on-error: true
if: matrix.toolchain == 'gnu'
run: |
set -euo pipefail
output=$(.ci/run-functional-tests.sh 2>&1) || true
echo "FUNCTIONAL_TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
echo "$output" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
env:
TOOLCHAIN_TYPE: ${{ matrix.toolchain }}
- name: Collect Test Data
if: always()
run: |
set -euo pipefail
COMMIT_SHA="${{ github.sha }}"
COMMIT_SHORT=$(git rev-parse --short HEAD 2>/dev/null || echo "${{ github.sha }}" | cut -c1-7)
GITHUB_REPO="${{ github.repository }}"
if [ "${{ matrix.toolchain }}" = "llvm" ]; then
# LLVM: Build-only validation, skip tests
mkdir -p test-results
echo "${{ matrix.toolchain }}" > test-results/toolchain
echo "$COMMIT_SHA" > test-results/commit_sha
echo "$COMMIT_SHORT" > test-results/commit_short
echo "$GITHUB_REPO" > test-results/github_repo
echo "skipped" > test-results/crash_exit_code
echo "skipped" > test-results/functional_exit_code
# Generate skipped status for all apps
apps=$(find app/ -name "*.c" -exec basename {} .c \; | sort)
for app in $apps; do
echo "$app=skipped" >> test-results/apps_data
done
# Generate skipped status for functional tests
echo "mutex=skipped" > test-results/functional_data
echo "semaphore=skipped" >> test-results/functional_data
# Generate skipped status for functional test criteria
echo "mutex:fairness=skipped" > test-results/functional_criteria_data
echo "mutex:mutual_exclusion=skipped" >> test-results/functional_criteria_data
echo "mutex:data_consistency=skipped" >> test-results/functional_criteria_data
echo "mutex:overall=skipped" >> test-results/functional_criteria_data
echo "semaphore:overall=skipped" >> test-results/functional_criteria_data
echo "LLVM toolchain: Build validation only (tests skipped)"
else
# GNU: Full test suite
.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 }}"
fi
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.toolchain }}
path: test-results/
retention-days: 3
if-no-files-found: warn
# Comprehensive test summary with detailed reporting
test-summary:
runs-on: ubuntu-24.04
needs: [lint, matrix-tests]
if: always()
timeout-minutes: 15
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download Test Results
uses: actions/download-artifact@v4
with:
pattern: test-results-*
path: all-test-results/
- name: Generate Test Summary
id: generate_summary
continue-on-error: true
run: |
echo "Aggregating test results..."
.ci/ci-tools.sh aggregate all-test-results test-summary.toml
if [ -f test-summary.toml ]; then
echo "summary_generated=true" >> $GITHUB_OUTPUT
echo "Test Summary:"
cat test-summary.toml
else
echo "summary_generated=false" >> $GITHUB_OUTPUT
echo "⚠️ Warning: test-summary.toml not generated"
fi
- name: Upload Test Summary
if: always() && steps.generate_summary.outputs.summary_generated == 'true'
uses: actions/upload-artifact@v4
with:
name: test-summary
path: test-summary.toml
retention-days: 30
if-no-files-found: error
- name: Comment PR with Formatted Summary
if: always() && github.event_name == 'pull_request' && steps.generate_summary.outputs.summary_generated == 'true'
continue-on-error: true
run: |
echo "Posting summary to PR #${{ github.event.number }}..."
.ci/ci-tools.sh post-comment test-summary.toml ${{ github.event.number }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Final Status Check
run: |
set -euo pipefail
echo "=== Final CI Status Check ==="
if [ ! -f test-summary.toml ]; then
echo "❌ Error: test-summary.toml not found"
echo "CI infrastructure issue - check test aggregation step"
exit 1
fi
overall_status=$(grep -A 1 '^\[summary\]' test-summary.toml | grep 'status =' | cut -d'"' -f2)
echo "Overall test status: $overall_status"
# Extract failure details if available
if [ "$overall_status" != "passed" ]; then
echo ""
echo "=== Failure Details ==="
grep -E '(failed|error|skipped)' test-summary.toml || true
fi
if [ "$overall_status" = "passed" ]; then
echo ""
echo "✅ All tests passed successfully"
exit 0
else
echo ""
echo "❌ Tests failed - see details above"
exit 1
fi