Skip to content

Commit bb01758

Browse files
authored
Merge pull request #45 from sysprog21/ci-refine
CI: Refine workflow for performance/reliability
2 parents b106e8c + 26465ce commit bb01758

File tree

3 files changed

+111
-23
lines changed

3 files changed

+111
-23
lines changed

.ci/run-functional-tests.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#!/bin/bash
22

3+
# Strict error handling
4+
set -euo pipefail
5+
36
# Configuration
47
TIMEOUT=30
58
TOOLCHAIN_TYPE=${TOOLCHAIN_TYPE:-gnu}
69

710
# Define functional tests and their expected PASS criteria
811
declare -A FUNCTIONAL_TESTS
912
FUNCTIONAL_TESTS["mutex"]="Fairness: PASS,Mutual Exclusion: PASS,Data Consistency: PASS,Overall: PASS"
10-
FUNCTIONAL_TESTS["semaphore"]="All tests PASSED!"
13+
FUNCTIONAL_TESTS["semaphore"]="Overall: PASS"
1114
#FUNCTIONAL_TESTS["test64"]="Unsigned Multiply: PASS,Unsigned Divide: PASS,Signed Multiply: PASS,Signed Divide: PASS,Left Shifts: PASS,Logical Right Shifts: PASS,Arithmetic Right Shifts: PASS,Overall: PASS"
1215
#FUNCTIONAL_TESTS["suspend"]="Suspend: PASS,Resume: PASS,Self-Suspend: PASS,Overall: PASS"
1316

@@ -37,7 +40,7 @@ test_functional_app() {
3740

3841
# Build phase
3942
echo "[+] Building..."
40-
make clean > /dev/null 2>&1
43+
make clean > /dev/null 2>&1 || true # Clean previous build artifacts (failures ignored)
4144
if ! make "$test" TOOLCHAIN_TYPE="$TOOLCHAIN_TYPE" > /dev/null 2>&1; then
4245
echo "[!] Build failed"
4346

.github/workflows/ci.yml

Lines changed: 104 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,85 @@ 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+
actions: write # Required for actions/cache@v4 to save/restore cache
20+
1121
jobs:
12-
matrix-tests:
22+
# Fast-running lint job to catch formatting issues early
23+
lint:
1324
runs-on: ubuntu-24.04
14-
name: Test on ${{ matrix.toolchain }} toolchain
25+
name: Code Quality Checks
26+
timeout-minutes: 10
1527

16-
strategy:
17-
fail-fast: false
18-
matrix:
19-
toolchain: [gnu, llvm]
28+
env:
29+
CLANG_FORMAT_VERSION: 18
2030

2131
steps:
2232
- name: Checkout
23-
uses: actions/checkout@v4
33+
uses: actions/checkout@v5
2434

25-
- name: Install base dependencies
35+
- name: Install linting tools
2636
run: |
2737
sudo apt-get update
28-
sudo apt-get install -y build-essential qemu-system-riscv32 wget clang-format-18 shfmt
38+
sudo apt-get install -y --no-install-recommends clang-format-${{ env.CLANG_FORMAT_VERSION }} shfmt
2939
3040
- name: Check code formatting
3141
run: .ci/check-format.sh
3242

3343
- name: Check newline at end of files
3444
run: .ci/check-newline.sh
3545

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.
50+
matrix-tests:
51+
runs-on: ubuntu-24.04
52+
name: Test on ${{ matrix.toolchain }} toolchain
53+
needs: lint
54+
timeout-minutes: 30
55+
56+
strategy:
57+
fail-fast: false
58+
matrix:
59+
toolchain: [gnu, llvm]
60+
61+
steps:
62+
- name: Checkout
63+
uses: actions/checkout@v5
64+
65+
- name: Cache toolchain
66+
uses: actions/cache@v4
67+
id: cache-toolchain
68+
with:
69+
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
78+
3679
- name: Setup ${{ matrix.toolchain }} toolchain
80+
if: steps.cache-toolchain.outputs.cache-hit != 'true'
3781
run: .ci/setup-toolchain.sh ${{ matrix.toolchain }}
3882

83+
- name: Configure toolchain environment
84+
if: steps.cache-toolchain.outputs.cache-hit == 'true'
85+
run: |
86+
echo "$PWD/riscv/bin" >> "$GITHUB_PATH"
87+
echo "CROSS_COMPILE=riscv32-unknown-elf-" >> "$GITHUB_ENV"
88+
echo "TOOLCHAIN_TYPE=${{ matrix.toolchain }}" >> "$GITHUB_ENV"
89+
3990
- name: Verify toolchain installation
4091
run: |
4192
if [ "${{ matrix.toolchain }}" = "gnu" ]; then
@@ -49,8 +100,9 @@ jobs:
49100
50101
- name: Build Kernel
51102
run: |
103+
set -euo pipefail
52104
make clean
53-
make
105+
make -j$(nproc)
54106
env:
55107
TOOLCHAIN_TYPE: ${{ matrix.toolchain }}
56108

@@ -59,6 +111,7 @@ jobs:
59111
continue-on-error: true
60112
if: matrix.toolchain == 'gnu'
61113
run: |
114+
set -euo pipefail
62115
output=$(.ci/run-app-tests.sh 2>&1) || true
63116
echo "TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
64117
echo "$output" >> $GITHUB_OUTPUT
@@ -71,6 +124,7 @@ jobs:
71124
continue-on-error: true
72125
if: matrix.toolchain == 'gnu'
73126
run: |
127+
set -euo pipefail
74128
output=$(.ci/run-functional-tests.sh 2>&1) || true
75129
echo "FUNCTIONAL_TEST_OUTPUT<<EOF" >> $GITHUB_OUTPUT
76130
echo "$output" >> $GITHUB_OUTPUT
@@ -81,6 +135,7 @@ jobs:
81135
- name: Collect Test Data
82136
if: always()
83137
run: |
138+
set -euo pipefail
84139
if [ "${{ matrix.toolchain }}" = "llvm" ]; then
85140
# LLVM: Build-only validation, skip tests
86141
mkdir -p test-results
@@ -103,7 +158,7 @@ jobs:
103158
echo "mutex:mutual_exclusion=skipped" >> test-results/functional_criteria_data
104159
echo "mutex:data_consistency=skipped" >> test-results/functional_criteria_data
105160
echo "mutex:overall=skipped" >> test-results/functional_criteria_data
106-
echo "semaphore:all_tests_passed!=skipped" >> test-results/functional_criteria_data
161+
echo "semaphore:overall=skipped" >> test-results/functional_criteria_data
107162
108163
echo "LLVM toolchain: Build validation only (tests skipped)"
109164
else
@@ -117,13 +172,18 @@ jobs:
117172
with:
118173
name: test-results-${{ matrix.toolchain }}
119174
path: test-results/
120-
retention-days: 1
175+
retention-days: 3
176+
if-no-files-found: warn
121177

122178
# Comprehensive test summary with detailed reporting
123179
test-summary:
124180
runs-on: ubuntu-24.04
125-
needs: matrix-tests
181+
needs: [lint, matrix-tests]
126182
if: always()
183+
timeout-minutes: 15
184+
permissions:
185+
contents: read
186+
pull-requests: write
127187

128188
steps:
129189
- name: Checkout
@@ -136,41 +196,66 @@ jobs:
136196
path: all-test-results/
137197

138198
- name: Generate Test Summary
199+
id: generate_summary
139200
continue-on-error: true
140201
run: |
202+
echo "Aggregating test results..."
141203
.ci/ci-tools.sh aggregate all-test-results test-summary.toml
142-
cat test-summary.toml
204+
205+
if [ -f test-summary.toml ]; then
206+
echo "summary_generated=true" >> $GITHUB_OUTPUT
207+
echo "Test Summary:"
208+
cat test-summary.toml
209+
else
210+
echo "summary_generated=false" >> $GITHUB_OUTPUT
211+
echo "⚠️ Warning: test-summary.toml not generated"
212+
fi
143213
144214
- name: Upload Test Summary
145-
if: always()
215+
if: always() && steps.generate_summary.outputs.summary_generated == 'true'
146216
uses: actions/upload-artifact@v4
147217
with:
148218
name: test-summary
149219
path: test-summary.toml
150220
retention-days: 30
221+
if-no-files-found: error
151222

152223
- name: Comment PR with Formatted Summary
153-
if: always() && github.event_name == 'pull_request'
224+
if: always() && github.event_name == 'pull_request' && steps.generate_summary.outputs.summary_generated == 'true'
154225
continue-on-error: true
155226
run: |
227+
echo "Posting summary to PR #${{ github.event.number }}..."
156228
.ci/ci-tools.sh post-comment test-summary.toml ${{ github.event.number }}
157229
env:
158230
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
159231

160232
- name: Final Status Check
161233
run: |
234+
set -euo pipefail
235+
echo "=== Final CI Status Check ==="
236+
162237
if [ ! -f test-summary.toml ]; then
163-
echo "Error: test-summary.toml not found"
238+
echo "❌ Error: test-summary.toml not found"
239+
echo "CI infrastructure issue - check test aggregation step"
164240
exit 1
165241
fi
166242
167243
overall_status=$(grep -A 1 '^\[summary\]' test-summary.toml | grep 'status =' | cut -d'"' -f2)
168244
echo "Overall test status: $overall_status"
169245
246+
# Extract failure details if available
247+
if [ "$overall_status" != "passed" ]; then
248+
echo ""
249+
echo "=== Failure Details ==="
250+
grep -E '(failed|error|skipped)' test-summary.toml || true
251+
fi
252+
170253
if [ "$overall_status" = "passed" ]; then
171-
echo "✅ All tests passed"
254+
echo ""
255+
echo "✅ All tests passed successfully"
172256
exit 0
173257
else
174-
echo "❌ Tests failed"
258+
echo ""
259+
echo "❌ Tests failed - see details above"
175260
exit 1
176261
fi

app/semaphore.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ void print_test_results(void)
175175
printf("Total tests: %d\n", tests_passed + tests_failed);
176176

177177
if (tests_failed == 0) {
178-
printf("All tests PASSED!\n");
178+
printf("Overall: PASS\n");
179179
} else {
180-
printf("Some tests FAILED!\n");
180+
printf("Overall: FAIL\n");
181181
}
182182
}
183183

0 commit comments

Comments
 (0)