Merge branch 'local-desktop-installation-support' into main #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Installer CI | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'install.sh' | |
| - 'scripts/**' | |
| - 'acfs.manifest.yaml' | |
| - 'checksums.yaml' | |
| - 'packages/manifest/**' | |
| - '.github/workflows/*.yml' | |
| - '.shellcheckrc' | |
| - 'tests/**/*.sh' | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'install.sh' | |
| - 'scripts/**' | |
| - 'acfs.manifest.yaml' | |
| - 'checksums.yaml' | |
| - 'packages/manifest/**' | |
| - '.github/workflows/*.yml' | |
| - '.shellcheckrc' | |
| - 'tests/**/*.sh' | |
| jobs: | |
| yaml-lint: | |
| name: Workflow YAML Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install yamllint | |
| run: pip install yamllint | |
| - name: Lint workflow YAML files | |
| run: | | |
| # Create minimal config that catches critical YAML syntax errors | |
| cat > /tmp/yamllint.yml << 'EOF' | |
| extends: default | |
| rules: | |
| line-length: | |
| max: 200 | |
| key-ordering: disable | |
| comments: | |
| min-spaces-from-content: 1 | |
| document-start: disable | |
| document-end: disable | |
| indentation: | |
| spaces: 2 | |
| indent-sequences: whatever | |
| truthy: | |
| allowed-values: ['true', 'false', 'on', 'off'] | |
| EOF | |
| echo "Validating YAML syntax for all workflow files..." | |
| yamllint -c /tmp/yamllint.yml .github/workflows/*.yml | |
| echo "✅ All workflow YAML files have valid syntax" | |
| shellcheck: | |
| name: ShellCheck | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install ShellCheck | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y shellcheck | |
| - name: Run ShellCheck | |
| shell: bash | |
| run: | | |
| mapfile -t files < <(git ls-files '*.sh') | |
| shellcheck "${files[@]}" | |
| - name: Run declare scoping linter | |
| run: bash scripts/tests/lint_declare_scoping.sh | |
| - name: Run pipefail safety linter | |
| run: bash scripts/tests/lint_pipefail_safety.sh | |
| - name: Run TTY safety linter | |
| run: bash scripts/tests/lint_tty_safety.sh | |
| - name: Run library globals integration test | |
| run: bash tests/unit/test_lib_globals.sh | |
| - name: Run macOS bootstrap mock test | |
| run: bash tests/vm/test_macos_bootstrap.sh | |
| manifest-drift: | |
| name: Manifest Drift Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: bun install | |
| working-directory: packages/manifest | |
| - name: Check manifest drift | |
| run: bun run generate --diff | |
| working-directory: packages/manifest | |
| - name: Install ShellCheck | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y shellcheck | |
| - name: Validate generated scripts (syntax + shellcheck) | |
| run: | | |
| EXIT_CODE=0 | |
| echo "Checking generated scripts for syntax errors..." | |
| for f in scripts/generated/*.sh; do | |
| [ -f "$f" ] || continue | |
| if ! bash -n "$f" 2>&1; then | |
| echo "FAIL: $f has syntax errors" | |
| EXIT_CODE=1 | |
| fi | |
| done | |
| echo "Running ShellCheck on generated scripts..." | |
| for f in scripts/generated/*.sh; do | |
| [ -f "$f" ] || continue | |
| if ! shellcheck "$f"; then | |
| echo "FAIL: $f has ShellCheck warnings" | |
| EXIT_CODE=1 | |
| fi | |
| done | |
| if [ "$EXIT_CODE" -eq 0 ]; then | |
| echo "All generated scripts pass syntax and ShellCheck validation" | |
| fi | |
| exit $EXIT_CODE | |
| checksum-verification: | |
| name: Verify Upstream Checksums | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Verify all checksums match upstream | |
| id: verify | |
| run: | | |
| chmod +x ./scripts/lib/security.sh | |
| echo "Verifying checksums against upstream installer scripts..." | |
| # Run verification and capture result (stderr separate to avoid corrupting JSON) | |
| if ./scripts/lib/security.sh --verify --json > result.json 2>verify-errors.log; then | |
| echo "✅ All checksums match upstream" | |
| echo "status=ok" >> $GITHUB_OUTPUT | |
| else | |
| echo "❌ Checksum mismatches detected!" | |
| echo "status=mismatch" >> $GITHUB_OUTPUT | |
| # Show what's wrong | |
| echo "" | |
| echo "=== Mismatched checksums ===" | |
| jq -r '.mismatches[] | " \(.name): expected \(.expected), got \(.actual)"' result.json 2>/dev/null || true | |
| echo "" | |
| echo "=== To fix locally ===" | |
| echo " ./scripts/lib/security.sh --update-checksums > checksums.yaml" | |
| echo " git add checksums.yaml && git commit -m 'chore: update checksums'" | |
| # Fail the job | |
| exit 1 | |
| fi | |
| - name: Upload verification result | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: checksum-verification | |
| path: result.json | |
| pinned-ref-smoke: | |
| name: Pinned Ref Smoke (checksums from main) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| container: | |
| image: ubuntu:24.04 | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| steps: | |
| - name: Install container prerequisites | |
| working-directory: / | |
| run: | | |
| apt-get update | |
| apt-get install -y sudo curl git ca-certificates jq unzip tar xz-utils gnupg | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Configure CI sudo | |
| run: | | |
| echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-ci-ubuntu | |
| chmod 440 /etc/sudoers.d/90-ci-ubuntu | |
| - name: Run pinned-ref install (checksums from main) | |
| run: | | |
| ACFS_REF="$(cat VERSION)" \ | |
| ACFS_CHECKSUMS_REF=main \ | |
| bash install.sh --yes --skip-preflight --skip-ubuntu-upgrade --mode safe --only lang.uv | |
| selection-tests: | |
| name: Selection & Contract Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Run selection tests | |
| run: bash scripts/lib/test_selection.sh | |
| - name: Run contract tests | |
| run: bash scripts/lib/test_contract.sh | |
| - name: Run security tests | |
| run: bash scripts/lib/test_security.sh | |
| - name: Run install helpers tests | |
| run: bash scripts/lib/test_install_helpers.sh | |
| - name: Run RU integration tests | |
| run: | | |
| bash scripts/tests/test_ru_update.sh | |
| bash scripts/tests/test_ru_doctor.sh | |
| test-installer: | |
| name: Test installer (Ubuntu ${{ matrix.ubuntu }}, mode ${{ matrix.mode }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - ubuntu: '24.04' | |
| mode: vibe | |
| - ubuntu: '25.04' | |
| mode: vibe | |
| - ubuntu: '24.04' | |
| mode: safe | |
| container: | |
| image: ubuntu:${{ matrix.ubuntu }} | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| steps: | |
| - name: Install container prerequisites | |
| working-directory: / | |
| run: | | |
| apt-get update | |
| apt-get install -y sudo curl git ca-certificates jq unzip tar xz-utils gnupg | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Offline bootstrap simulation | |
| run: | | |
| bash tests/vm/bootstrap_offline_checks.sh | |
| - name: Configure CI sudo | |
| run: | | |
| # CI needs passwordless sudo for upstream scripts that use sudo internally | |
| # This is needed for safe mode since it doesn't configure NOPASSWD | |
| # The ubuntu user is created by install.sh, so we pre-configure sudoers | |
| echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-ci-ubuntu | |
| chmod 440 /etc/sudoers.d/90-ci-ubuntu | |
| - name: Run installer | |
| run: | | |
| # Skip preflight in CI - GitHub Actions containers have limited disk (17GB < 20GB required) | |
| # Skip Ubuntu upgrade in CI - containers can't reboot during workflow | |
| ACFS_CI=true bash install.sh --yes --skip-preflight --skip-ubuntu-upgrade --mode ${{ matrix.mode }} | |
| - name: Run doctor | |
| run: | | |
| su - ubuntu -c "ACFS_DOCTOR_CI=true zsh -ic 'acfs doctor'" | |
| - name: Verify key tools | |
| run: | | |
| su - ubuntu -c "zsh -ic 'test -f ~/.acfs/VERSION'" | |
| su - ubuntu -c "zsh -ic 'gh --version'" | |
| su - ubuntu -c "zsh -ic 'jq --version'" | |
| su - ubuntu -c "zsh -ic 'sg --version'" | |
| su - ubuntu -c "zsh -ic 'git-lfs version'" | |
| su - ubuntu -c "zsh -ic 'rsync --version'" | |
| su - ubuntu -c "zsh -ic 'strace --version'" | |
| su - ubuntu -c "zsh -ic 'command -v lsof >/dev/null'" | |
| su - ubuntu -c "zsh -ic 'command -v dig >/dev/null'" | |
| su - ubuntu -c "zsh -ic 'command -v nc >/dev/null'" | |
| su - ubuntu -c "zsh -ic 'ntm --help'" | |
| su - ubuntu -c "zsh -ic 'ubs --help'" | |
| su - ubuntu -c "zsh -ic 'bv --help'" | |
| su - ubuntu -c "zsh -ic 'cass --help'" | |
| su - ubuntu -c "zsh -ic 'cm --help'" | |
| su - ubuntu -c "zsh -ic 'caam --help'" | |
| su - ubuntu -c "zsh -ic 'slb --help'" | |
| su - ubuntu -c "zsh -ic 'dcg --version'" | |
| su - ubuntu -c "zsh -ic 'dcg doctor'" | |
| su - ubuntu -c "zsh -ic 'ru --version'" | |
| su - ubuntu -c "zsh -ic 'onboard --help'" | |
| # beads_rust (required) - issue tracking | |
| su - ubuntu -c "zsh -ic 'br --version'" | |
| # New stack tools (bd-1ega) | |
| su - ubuntu -c "zsh -ic 'ms --version'" | |
| su - ubuntu -c "zsh -ic 'apr --help || true'" | |
| su - ubuntu -c "zsh -ic 'jfp --version || true'" | |
| su - ubuntu -c "zsh -ic 'pt --help || true'" | |
| su - ubuntu -c "zsh -ic 'brenner --version || brenner --help || true'" | |
| su - ubuntu -c "zsh -ic 'rch --version || rch --help || true'" | |
| su - ubuntu -c "zsh -ic 'wa --version || wa --help || true'" | |
| su - ubuntu -c "zsh -ic 'sysmoni --version || sysmoni --help || true'" | |
| # Agents | |
| su - ubuntu -c "zsh -ic 'claude --version'" | |
| su - ubuntu -c "zsh -ic 'codex --version'" | |
| su - ubuntu -c "zsh -ic 'gemini --version'" | |
| e2e-curlbash-bootstrap: | |
| name: E2E curl|bash Bootstrap | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| container: | |
| image: ubuntu:24.04 | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| steps: | |
| - name: Install container prerequisites | |
| working-directory: / | |
| run: | | |
| apt-get update | |
| apt-get install -y sudo curl git ca-certificates jq python3 tar gzip bash | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Configure CI sudo | |
| run: | | |
| echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-ci-ubuntu | |
| chmod 440 /etc/sudoers.d/90-ci-ubuntu | |
| - name: Run curl|bash bootstrap E2E test | |
| run: bash tests/e2e/test_curlbash_bootstrap.sh | |
| e2e-resume-after-failure: | |
| name: E2E Resume After Failure | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| container: | |
| image: ubuntu:24.04 | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| steps: | |
| - name: Install container prerequisites | |
| working-directory: / | |
| run: | | |
| apt-get update | |
| apt-get install -y sudo curl git ca-certificates jq unzip tar xz-utils gnupg | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Configure CI sudo | |
| run: | | |
| echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-ci-ubuntu | |
| chmod 440 /etc/sudoers.d/90-ci-ubuntu | |
| - name: Run resume-after-failure E2E test | |
| run: bash tests/e2e/test_resume_after_failure.sh |