Skip to content

Add U-mode task isolation and fix self-termination #265

Add U-mode task isolation and fix self-termination

Add U-mode task isolation and fix self-termination #265

Workflow file for this run

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
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 - GNU and LLVM run in parallel after lint passes
# GNU: Full test suite (build + app tests + functional tests)
# LLVM: Build-only validation (verifies cross-toolchain compatibility)
matrix-tests:
runs-on: ubuntu-24.04
name: ${{ matrix.toolchain }} toolchain
needs: lint
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
toolchain: [GNU, LLVM]
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install QEMU
if: matrix.toolchain == 'GNU'
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends qemu-system-riscv32
- name: Set toolchain name
id: toolchain
run: echo "name=$(echo '${{ matrix.toolchain }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Cache toolchain
uses: actions/cache@v5
id: cache-toolchain
with:
path: riscv
key: riscv32-${{ steps.toolchain.outputs.name }}-${{ hashFiles('.ci/setup-toolchain.sh') }}
- name: Setup ${{ matrix.toolchain }} toolchain
if: steps.cache-toolchain.outputs.cache-hit != 'true'
run: .ci/setup-toolchain.sh ${{ steps.toolchain.outputs.name }}
- name: Configure toolchain environment
run: |
echo "$PWD/riscv/bin" >> "$GITHUB_PATH"
echo "CROSS_COMPILE=riscv32-unknown-elf-" >> "$GITHUB_ENV"
echo "TOOLCHAIN_TYPE=${{ steps.toolchain.outputs.name }}" >> "$GITHUB_ENV"
- name: Verify toolchain
run: |
if [ "${{ matrix.toolchain }}" = "GNU" ]; then
riscv32-unknown-elf-gcc --version
qemu-system-riscv32 --version
else
riscv32-unknown-elf-clang --version
fi
- name: Build kernel
run: make -j$(nproc)
- name: Run app tests
id: test
continue-on-error: true
if: matrix.toolchain == 'GNU'
run: |
output=$(.ci/run-app-tests.sh 2>&1) || true
delimiter=$(openssl rand -hex 8)
echo "TEST_OUTPUT<<$delimiter" >> $GITHUB_OUTPUT
echo "$output" >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Run functional tests
id: functional_test
continue-on-error: true
if: matrix.toolchain == 'GNU'
run: |
output=$(.ci/run-functional-tests.sh 2>&1) || true
delimiter=$(openssl rand -hex 8)
echo "FUNCTIONAL_TEST_OUTPUT<<$delimiter" >> $GITHUB_OUTPUT
echo "$output" >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- 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 "${{ steps.toolchain.outputs.name }}" > 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
for app in $(find app/ -name "*.c" -exec basename {} .c \; | sort); 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
printf '%s\n' \
"mutex:fairness=skipped" \
"mutex:mutual_exclusion=skipped" \
"mutex:data_consistency=skipped" \
"mutex:overall=skipped" \
"semaphore:overall=skipped" \
> test-results/functional_criteria_data
echo "LLVM: Build validation only (tests skipped)"
else
# GNU: Full test suite
.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 }}"
fi
- name: Upload test results
if: always()
uses: actions/upload-artifact@v6
with:
name: test-results-${{ matrix.toolchain }}
path: test-results/
retention-days: 7
if-no-files-found: warn
# Aggregate results from all toolchain builds
test-summary:
runs-on: ubuntu-24.04
needs: matrix-tests
if: always()
timeout-minutes: 10
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download test results
uses: actions/download-artifact@v7
with:
pattern: test-results-*
path: all-test-results/
- name: Generate test summary
id: summary
run: |
.ci/ci-tools.sh aggregate all-test-results test-summary.toml
if [ -f test-summary.toml ]; then
echo "generated=true" >> $GITHUB_OUTPUT
cat test-summary.toml
else
echo "generated=false" >> $GITHUB_OUTPUT
echo "Warning: test-summary.toml not generated"
fi
- name: Upload test summary
if: steps.summary.outputs.generated == 'true'
uses: actions/upload-artifact@v6
with:
name: test-summary
path: test-summary.toml
retention-days: 30
- name: Post PR comment
if: github.event_name == 'pull_request' && steps.summary.outputs.generated == 'true'
continue-on-error: true
run: .ci/ci-tools.sh post-comment test-summary.toml ${{ github.event.number }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check final status
run: |
if [ ! -f test-summary.toml ]; then
echo "Error: test-summary.toml not found"
exit 1
fi
status=$(grep -A1 '^\[summary\]' test-summary.toml | grep 'status =' | cut -d'"' -f2)
echo "Overall status: $status"
if [ "$status" = "passed" ]; then
echo "All tests passed"
else
echo "Tests failed"
grep -E '(failed|error)' test-summary.toml || true
exit 1
fi