Skip to content

feat: quiet live boot to reduce framebuffer log flashes #1330

feat: quiet live boot to reduce framebuffer log flashes

feat: quiet live boot to reduce framebuffer log flashes #1330

Workflow file for this run

name: CI/CD
on:
push:
branches: [main, develop]
tags:
- "v*"
pull_request:
branches: [main, develop]
workflow_dispatch:
permissions:
contents: write
concurrency:
group: cicd-${{ github.ref }}
cancel-in-progress: true
env:
ARCHLINUX_IMAGE: ghcr.io/archlinux/archlinux:latest
jobs:
# ================================================================
# Stage 1: Tests (run in parallel)
# ================================================================
code-quality:
name: "Code Quality"
runs-on: ubuntu-latest
if: github.event_name != 'workflow_dispatch'
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
cache: 'pip'
- name: Install dependencies
run: pip install pytest shellcheck-py
- name: Run ShellCheck
run: |
find airootfs/usr/local/bin -type f -executable | while read -r script; do
if head -1 "$script" | grep -qE "(bash|sh)$"; then
shellcheck -s bash --severity=error "$script"
fi
done
if [ -d airootfs/usr/local/lib/mados-hw-quirks.d ]; then
find airootfs/usr/local/lib/mados-hw-quirks.d -type f -name "*.sh" | while read -r script; do
shellcheck -s bash --severity=error "$script"
done
fi
if [ -d airootfs/usr/local/lib/mados_installer/scripts ]; then
find airootfs/usr/local/lib/mados_installer/scripts -type f -name "*.sh" | while read -r script; do
shellcheck -s bash --severity=error "$script"
done
fi
- name: Validate Python syntax
run: |
find airootfs -name "*.py" -type f | while read -r script; do
python3 -m py_compile "$script"
done
- name: Install ruff
run: pip install ruff
- name: Run ruff check
run: ruff check airootfs tests
- name: Run ruff format check
run: ruff format --check airootfs tests
test-unit:
name: "Unit: ${{ matrix.category }}"
runs-on: ubuntu-latest
needs: code-quality
if: github.event_name != 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
include:
- category: "Core & OTA"
files: "tests/test_boot_scripts.py tests/test_wifi_quirks.py tests/test_mados_chwd.py tests/test_profiledef_permissions.py"
- category: "Desktop Config"
files: "tests/test_gamepad_wm.py tests/test_squeekboard.py tests/test_timezone_detect.py tests/test_vbox_guest.py"
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
cache: 'pip'
- name: Install pytest
run: pip install pytest
- name: Run tests
run: |
executed=0
for file in ${{ matrix.files }}; do
if [ ! -f "$file" ]; then
echo "Skipping missing test file: $file"
continue
fi
python3 -m pytest "$file" -v
executed=$((executed + 1))
done
if [ "$executed" -eq 0 ]; then
echo "No test files executed for matrix category: ${{ matrix.category }}"
exit 1
fi
test-integration:
name: "Integration"
runs-on: ubuntu-latest
needs: code-quality
if: github.event_name != 'workflow_dispatch'
steps:
- name: Skip (installer in external repo)
run: echo "Skipping integration test - installer is now tested in mados-installer repo"
# ================================================================
# Stage 2: Validation (only on push to main/develop or tags)
# ================================================================
validate:
name: "Validate: ${{ matrix.component }}"
runs-on: ubuntu-latest
needs: [test-unit, test-integration]
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))
steps:
- name: Skip (installer in external repo)
run: echo "Skipping validation - installer is now tested in mados-installer repo"
# ================================================================
# Stage 3: Build ISO + Release (only on tag push)
# ================================================================
build-and-release:
name: "Build & Release"
runs-on: ubuntu-latest
needs: validate
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Build ISO
id: build
run: |
WORKSPACE="${{ github.workspace }}"
rm -rf out/ 2>/dev/null || true
mkdir -p out
chmod 777 out
docker run --privileged --rm \
--network host \
-v "$WORKSPACE:/build" \
${{ env.ARCHLINUX_IMAGE }} bash -c "
set -e
pacman-key --init && pacman-key --populate
pacman -Syu --noconfirm archiso
cd /build
rm -rf out/*
mkarchiso -v -w /tmp/work -o out .
"
ISO_FILE=$(ls out/*.iso 2>/dev/null | head -1)
if [ -z "$ISO_FILE" ]; then
echo "ERROR: No ISO file found"
exit 1
fi
sha256sum out/*.iso > out/SHA256SUMS || true
VERSION="${GITHUB_REF_NAME#v}"
[ -n "$VERSION" ] || VERSION="dev-$(date +%Y%m%d)"
ISO_FILE=$(ls out/*.iso | head -1)
NEW_ISO_NAME="madOS-${VERSION}-x86_64.iso"
mv "$ISO_FILE" "out/${NEW_ISO_NAME}"
sed -i "s/$(basename "$ISO_FILE")/${NEW_ISO_NAME}/g" out/SHA256SUMS
ISO_NAME="$NEW_ISO_NAME"
BUILD_DATE=$(date +%Y.%m.%d)
ISO_SIZE=$(stat --format=%s "out/${ISO_NAME}" 2>/dev/null || echo 0)
ISO_SIZE_MB=$((ISO_SIZE / 1024 / 1024))
SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-7)
echo "iso_name=$ISO_NAME" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "build_date=$BUILD_DATE" >> $GITHUB_OUTPUT
echo "iso_size_mb=$ISO_SIZE_MB" >> $GITHUB_OUTPUT
echo "short_sha=$SHORT_SHA" >> $GITHUB_OUTPUT
echo "Build successful!"
- name: Upload to Internet Archive
id: ia-upload
env:
IA_ACCESS_KEY: ${{ secrets.IA_ACCESS_KEY }}
IA_SECRET_KEY: ${{ secrets.IA_SECRET_KEY }}
run: |
pip install --user internetarchive
export PATH="$HOME/.local/bin:$PATH"
ISO_NAME="${{ steps.build.outputs.iso_name }}"
VERSION="${{ steps.build.outputs.version }}"
BUILD_DATE="${{ steps.build.outputs.build_date }}"
export IA_ACCESS_KEY IA_SECRET_KEY ISO_NAME VERSION BUILD_DATE
IA_URL=$(python3 "${{ github.workspace }}/.github/scripts/ia_upload.py" 2>&1 | grep "^URL:" | cut -d' ' -f2)
if [ -z "$IA_URL" ]; then
echo "ERROR: Failed to get Internet Archive URL"
exit 1
fi
echo "ia_url=$IA_URL" >> $GITHUB_OUTPUT
- name: Get tag
id: get_tag
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
with:
tag_name: ${{ steps.get_tag.outputs.TAG }}
name: ${{ steps.get_tag.outputs.TAG }}
draft: false
prerelease: false
body: |
## madOS ${{ steps.get_tag.outputs.TAG }}
**Download:** [Internet Archive](${{ steps.ia-upload.outputs.ia_url }})
---
Built from: `${{ github.sha }}`
files: |
out/${{ steps.build.outputs.iso_name }}
out/SHA256SUMS