name: CI/CD Pipeline on: push: branches: [main, develop] tags: ["v*"] pull_request: branches: [main, develop] env: CARGO_TERM_COLOR: always RUST_BACKTRACE: 1 jobs: # Frontend checks frontend-lint: name: Frontend Check & Build runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - name: Install dependencies run: npm install - name: Run frontend checks run: npm run typecheck && npm run format:check && npx eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0 - name: Build frontend run: npm run build - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: dist path: dist/ retention-days: 7 # Rust backend checks rust-check: name: Rust Check & Test runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: toolchain: stable components: clippy, rustfmt - name: Cache Cargo dependencies uses: Swatinem/rust-cache@v2 with: workspaces: src-tauri - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libwebkit2gtk-4.0-dev \ build-essential \ libssl-dev \ libgtk-3-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ libxdo-dev \ libsoup2.4-dev \ libjavascriptcoregtk-4.0-dev \ libgdk-pixbuf-2.0-dev \ libpango1.0-dev \ libatk1.0-dev \ libcairo2-dev - name: Check Rust formatting working-directory: src-tauri run: cargo fmt --all -- --check - name: Create dist directory for Tauri context run: mkdir -p dist - name: Run Clippy linter working-directory: src-tauri run: cargo clippy -- -D warnings - name: Run Rust tests working-directory: src-tauri run: cargo test --all - name: Check Rust code working-directory: src-tauri run: cargo check --all-targets # Build Tauri application build-tauri: name: Build Tauri App runs-on: ubuntu-22.04 needs: [frontend-lint, rust-check, verify-csp] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: toolchain: stable - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libwebkit2gtk-4.0-dev \ build-essential \ libssl-dev \ libgtk-3-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ libxdo-dev \ libsoup2.4-dev \ libjavascriptcoregtk-4.0-dev \ libgdk-pixbuf-2.0-dev \ libpango1.0-dev \ libatk1.0-dev \ libcairo2-dev - name: Install Rust dependencies run: npm install - name: Build frontend run: npm run build - name: Build Tauri app run: npm run tauri build - name: Install Ruby and fpm for RPM conversion run: | sudo apt-get install -y ruby ruby-dev rpm sudo gem install --no-document fpm # Ensure system gems are in PATH (fixes user gem path precedence issue) export PATH="$(gem env | grep 'EXECUTABLE DIRECTORY' | awk '{print $4}'):$PATH" fpm --version - name: Build RPM package run: | export PATH="$(gem env | grep 'EXECUTABLE DIRECTORY' | awk '{print $4}'):$PATH" ./scripts/build-rpm.sh - name: Upload DEB artifact uses: actions/upload-artifact@v4 if: github.event_name == 'pull_request' with: name: linuxy-deb path: src-tauri/target/release/bundle/deb/*.deb retention-days: 7 # Security audit security-audit: name: Security Audit runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Rust uses: dtolnay/rust-toolchain@stable - name: Install cargo-audit run: cargo install cargo-audit - name: Create dist directory for Tauri context run: mkdir -p dist - name: Run security audit working-directory: src-tauri run: cargo audit - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" - name: Install dependencies run: npm install - name: Run npm audit run: npm audit --audit-level=high # Production CSP verification verify-csp: name: Verify CSP Configuration runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Verify CSP allows required domains run: | CSP=$(grep -o '"csp": *"[^"]*"' src-tauri/tauri.conf.json | sed 's/"csp": "//' | sed 's/"//') echo "Checking CSP: $CSP" # Check required domains are allowed if ! echo "$CSP" | grep -q "appimage.github.io"; then echo "ERROR: appimage.github.io not in CSP" exit 1 fi if ! echo "$CSP" | grep -q "api.github.com"; then echo "ERROR: api.github.com not in CSP" exit 1 fi if ! echo "$CSP" | grep -q "avatars.githubusercontent.com"; then echo "ERROR: avatars.githubusercontent.com not in CSP" exit 1 fi echo "CSP verification passed!" # Integration tests on clean environment integration-test: name: Integration Tests runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Rust uses: dtolnay/rust-toolchain@stable - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libwebkit2gtk-4.0-dev \ build-essential \ libssl-dev \ libgtk-3-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ libxdo-dev \ libsoup2.4-dev \ libjavascriptcoregtk-4.0-dev \ libgdk-pixbuf-2.0-dev \ libpango1.0-dev \ libatk1.0-dev \ libcairo2-dev \ firejail - name: Install dependencies run: npm install - name: Build frontend run: npm run build - name: Build Tauri app run: npm run tauri build - name: Install Ruby and fpm for RPM conversion run: | sudo apt-get install -y ruby ruby-dev rpm sudo gem install --no-document fpm # Ensure system gems are in PATH (fixes user gem path precedence issue) export PATH="$(gem env | grep 'EXECUTABLE DIRECTORY' | awk '{print $4}'):$PATH" fpm --version - name: Build RPM package run: | export PATH="$(gem env | grep 'EXECUTABLE DIRECTORY' | awk '{print $4}'):$PATH" ./scripts/build-rpm.sh - name: Test binary exists run: | echo "Verifying binary..." ls -la src-tauri/target/release/linuxy file src-tauri/target/release/linuxy - name: Verify bundle outputs run: | echo "Checking bundle outputs..." ls -la src-tauri/target/release/bundle/ [ -d "src-tauri/target/release/bundle/deb" ] && echo "DEB: OK" [ -d "src-tauri/target/release/bundle/rpm" ] && echo "RPM: OK" [ -f "src-tauri/target/release/bundle/deb/"*.deb ] && echo "DEB package: OK" [ -f "src-tauri/target/release/bundle/rpm/"*.rpm ] && echo "RPM package: OK" - name: Verify desktop file template run: | if [ -f "src-tauri/debian/desktop-template.desktop" ]; then echo "Desktop template: OK" else echo "ERROR: Desktop template not found" exit 1 fi