diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..58084aa --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,227 @@ +name: Multi-Distro Build + +on: + push: + branches: ["master", "main"] + pull_request: + branches: ["master", "main"] + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + build-ubuntu: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - features: "default" + args: "" + - features: "no-default-features" + args: "--no-default-features" + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + llvm clang libclang-dev \ + pkg-config \ + libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \ + libpam0g-dev libdbus-1-dev \ + libwayland-dev libxkbcommon-dev + - name: Build (${{ matrix.features }}) + run: cargo build --verbose ${{ matrix.args }} + - name: Run tests + run: cargo test --verbose ${{ matrix.args }} + - name: Build release for size check + run: cargo build --release ${{ matrix.args }} + - name: Check binary size + run: | + size=$(wc -c < target/release/rustlock) + echo "Binary size (${{ matrix.features }}): $size bytes" + if [ "${{ matrix.features }}" = "no-default-features" ] && [ $size -gt 3000000 ]; then + echo "❌ Binary size exceeds 3MB threshold for no-networking build" + exit 1 + elif [ "${{ matrix.features }}" = "default" ] && [ $size -gt 5000000 ]; then + echo "❌ Binary size exceeds 5MB threshold for networking build" + exit 1 + fi + echo "✅ Binary size within limits" + + build-debian: + runs-on: ubuntu-latest + container: debian:stable-slim + strategy: + fail-fast: false + matrix: + include: + - features: "default" + args: "" + - features: "no-default-features" + args: "--no-default-features" + steps: + - uses: actions/checkout@v4 + - name: Install system dependencies + run: | + apt-get update + apt-get install -y \ + curl \ + llvm clang libclang-dev \ + pkg-config \ + libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \ + libgdk-pixbuf-2.0-dev libpam0g-dev libdbus-1-dev \ + libwayland-dev libxkbcommon-dev + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Build (${{ matrix.features }}) + run: cargo build --verbose ${{ matrix.args }} + - name: Run tests + run: cargo test --verbose ${{ matrix.args }} + - name: Build release for size check + run: cargo build --release ${{ matrix.args }} + - name: Check binary size + run: | + size=$(wc -c < target/release/rustlock) + echo "Binary size (${{ matrix.features }}): $size bytes" + if [ "${{ matrix.features }}" = "no-default-features" ] && [ $size -gt 3000000 ]; then + echo "❌ Binary size exceeds 3MB threshold for no-networking build" + exit 1 + elif [ "${{ matrix.features }}" = "default" ] && [ $size -gt 5000000 ]; then + echo "❌ Binary size exceeds 5MB threshold for networking build" + exit 1 + fi + echo "✅ Binary size within limits" + + build-fedora: + runs-on: ubuntu-latest + container: fedora:latest + strategy: + fail-fast: false + matrix: + include: + - features: "default" + args: "" + - features: "no-default-features" + args: "--no-default-features" + steps: + - uses: actions/checkout@v4 + - name: Install system dependencies + run: | + dnf install -y \ + curl \ + llvm clang clang-devel \ + pkgconfig \ + glib2-devel cairo-devel cairo-gobject-devel pango-devel atk-devel \ + gdk-pixbuf2-devel pam-devel dbus-devel \ + wayland-devel libxkbcommon-devel + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Build (${{ matrix.features }}) + run: cargo build --verbose ${{ matrix.args }} + - name: Run tests + run: cargo test --verbose ${{ matrix.args }} + - name: Build release for size check + run: cargo build --release ${{ matrix.args }} + - name: Check binary size + run: | + size=$(wc -c < target/release/rustlock) + echo "Binary size (${{ matrix.features }}): $size bytes" + if [ "${{ matrix.features }}" = "no-default-features" ] && [ $size -gt 3000000 ]; then + echo "❌ Binary size exceeds 3MB threshold for no-networking build" + exit 1 + elif [ "${{ matrix.features }}" = "default" ] && [ $size -gt 5000000 ]; then + echo "❌ Binary size exceeds 5MB threshold for networking build" + exit 1 + fi + echo "✅ Binary size within limits" + + build-arch: + runs-on: ubuntu-latest + container: archlinux:latest + strategy: + fail-fast: false + matrix: + include: + - features: "default" + args: "" + - features: "no-default-features" + args: "--no-default-features" + steps: + - uses: actions/checkout@v4 + - name: Install system dependencies + run: | + pacman -Sy --noconfirm \ + base-devel \ + llvm clang pkgconf \ + glib2 cairo pango atk gdk-pixbuf2 \ + pam dbus \ + wayland libxkbcommon + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Build (${{ matrix.features }}) + run: cargo build --verbose ${{ matrix.args }} + - name: Run tests + run: cargo test --verbose ${{ matrix.args }} + - name: Build release for size check + run: cargo build --release ${{ matrix.args }} + - name: Check binary size + run: | + size=$(wc -c < target/release/rustlock) + echo "Binary size (${{ matrix.features }}): $size bytes" + if [ "${{ matrix.features }}" = "no-default-features" ] && [ $size -gt 3000000 ]; then + echo "❌ Binary size exceeds 3MB threshold for no-networking build" + exit 1 + elif [ "${{ matrix.features }}" = "default" ] && [ $size -gt 5000000 ]; then + echo "❌ Binary size exceeds 5MB threshold for networking build" + exit 1 + fi + echo "✅ Binary size within limits" + + build-opensuse: + runs-on: ubuntu-latest + container: opensuse/tumbleweed:latest + strategy: + fail-fast: false + matrix: + include: + - features: "default" + args: "" + - features: "no-default-features" + args: "--no-default-features" + steps: + - uses: actions/checkout@v4 + - name: Install system dependencies + run: | + zypper install -y \ + curl \ + llvm clang-devel \ + pkgconfig \ + glib2-devel cairo-devel pango-devel atk-devel \ + gdk-pixbuf-devel pam-devel dbus-1-devel \ + wayland-devel libxkbcommon-devel + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Build (${{ matrix.features }}) + run: cargo build --verbose ${{ matrix.args }} + - name: Run tests + run: cargo test --verbose ${{ matrix.args }} + - name: Build release for size check + run: cargo build --release ${{ matrix.args }} + - name: Check binary size + run: | + size=$(wc -c < target/release/rustlock) + echo "Binary size (${{ matrix.features }}): $size bytes" + if [ "${{ matrix.features }}" = "no-default-features" ] && [ $size -gt 3000000 ]; then + echo "❌ Binary size exceeds 3MB threshold for no-networking build" + exit 1 + elif [ "${{ matrix.features }}" = "default" ] && [ $size -gt 5000000 ]; then + echo "❌ Binary size exceeds 5MB threshold for networking build" + exit 1 + fi + echo "✅ Binary size within limits" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 0f8bcd6..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,113 +0,0 @@ -name: CI - -on: - push: - branches: ["master", "main"] - pull_request: - branches: ["master", "main"] - -env: - CARGO_TERM_COLOR: always - -jobs: - build-ubuntu: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - features: "default" - args: "" - - features: "networking" - args: "--features networking" - - features: "no-default-features" - args: "--no-default-features" - steps: - - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - llvm clang libclang-dev \ - pkg-config \ - libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \ - libpam0g-dev libdbus-1-dev \ - libwayland-dev libxkbcommon-dev - - name: Build (${{ matrix.features }}) - run: cargo build --verbose ${{ matrix.args }} - - name: Run tests - run: cargo test --verbose - - build-debian: - runs-on: ubuntu-latest - container: debian:stable-slim - steps: - - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - name: Install system dependencies - run: | - apt-get update - apt-get install -y \ - llvm clang libclang-dev \ - pkg-config \ - libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \ - libpam0g-dev libdbus-1-dev \ - libwayland-dev libxkbcommon-dev \ - cargo rustc - - name: Build - run: cargo build --verbose - - build-fedora: - runs-on: ubuntu-latest - container: fedora:latest - steps: - - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - name: Install system dependencies - run: | - dnf install -y \ - llvm clang libclang-devel \ - pkg-config \ - glib2-devel cairo-devel pango-devel atk-devel \ - pam-devel dbus-devel \ - wayland-devel libxkbcommon-devel \ - cargo rust - - name: Build - run: cargo build --verbose - - build-arch: - runs-on: ubuntu-latest - container: archlinux:latest - steps: - - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - name: Install system dependencies - run: | - pacman -Sy --noconfirm \ - llvm clang pkgconf \ - glib2 cairo pango atk \ - pam dbus \ - wayland libxkbcommon \ - rust cargo - - name: Build - run: cargo build --verbose - - build-opensuse: - runs-on: ubuntu-latest - container: opensuse/tumbleweed:latest - steps: - - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - name: Install system dependencies - run: | - zypper install -y \ - llvm clang \ - pkg-config \ - glib2-devel cairo-devel pango-devel atk-devel \ - pam-devel dbus-1-devel \ - wayland-devel libxkbcommon-devel \ - rust cargo - - name: Build - run: cargo build --verbose - diff --git a/.github/workflows/metrics.yml b/.github/workflows/metrics.yml new file mode 100644 index 0000000..d521f18 --- /dev/null +++ b/.github/workflows/metrics.yml @@ -0,0 +1,97 @@ +name: Metrics Collection + +on: + schedule: + - cron: '0 0 * * 1' # Weekly on Monday at midnight + workflow_dispatch: + push: + branches: [main, master] + paths: + - 'src/**' + - 'Cargo.toml' + - '.github/workflows/metrics.yml' + +env: + CARGO_TERM_COLOR: always + +jobs: + collect-metrics: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + + - name: Install Rust with tools + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + + + - name: Generate test coverage + run: | + cargo install cargo-tarpaulin + cargo tarpaulin --out Html --out Lcov --output-dir ./coverage + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: ./coverage + retention-days: 30 + + - name: Count lines of code + run: | + cargo install tokei + tokei --output json > loc.json + echo "Lines of code:" + tokei --type=Rust + + - name: Upload LOC metrics + uses: actions/upload-artifact@v4 + with: + name: loc-metrics + path: loc.json + retention-days: 30 + + - name: Check compile times + run: | + echo "=== Compilation Metrics ===" + echo "Note: For accurate compile times, run: cargo clean && cargo build --timings" + echo "" + echo "To optimize compile times:" + echo "1. Check for large dependencies with: cargo tree --depth 1" + echo "2. Consider feature flag optimization" + echo "3. Review workspace structure" + + - name: Dependency analysis + run: | + cargo install cargo-depgraph + cargo depgraph --all-features --dedup-transitive --format dot > deps.dot + echo "Dependency graph generated: deps.dot" + echo "Total dependencies: $(cargo tree --depth 0 | wc -l)" + + - name: Upload dependency graph + uses: actions/upload-artifact@v4 + with: + name: dependency-graph + path: deps.dot + retention-days: 30 + + - name: Metrics summary + run: | + echo "=== Build Metrics Summary ===" + echo "" + echo "📊 Coverage: HTML and Lcov reports generated" + echo "📈 LOC: Lines of code counted and saved" + echo "🔗 Dependencies: Graph visualization available" + echo "" + echo "Artifacts available for 30 days:" + echo " - coverage-report/" + echo " - loc-metrics/loc.json" + echo " - dependency-graph/deps.dot" + echo "" + echo "Next steps:" + echo "1. Review coverage reports to identify untested code" + echo "2. Monitor LOC growth over time" + echo "3. Analyze dependency graph for optimization opportunities" \ No newline at end of file diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..0e321c5 --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,51 @@ +name: Code Quality + +on: + push: + branches: ["master", "main"] + pull_request: + branches: ["master", "main"] + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + quality-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + llvm clang libclang-dev \ + pkg-config \ + libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \ + libpam0g-dev libdbus-1-dev \ + libwayland-dev libxkbcommon-dev + + - name: Install Rust with tools + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Check formatting + run: cargo fmt -- --check + + - name: Run clippy + run: cargo clippy -- -D warnings + + - name: Install cargo-deny + run: cargo install cargo-deny + + - name: Check dependencies with cargo-deny + run: cargo deny check + + - name: Run unit tests + run: cargo test --quiet + + - name: Check documentation + run: cargo doc --no-deps --document-private-items \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 336730c..206f2b9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,126 +4,85 @@ on: push: tags: - 'v*' - workflow_dispatch: + +env: + CARGO_TERM_COLOR: always jobs: - build-ubuntu: + release-build: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - variant: "default" + args: "" + distro: "ubuntu" + - variant: "no-networking" args: "--no-default-features" - - variant: "networking" - args: "--features networking" + distro: "ubuntu" + - variant: "default" + args: "" + distro: "debian" + - variant: "default" + args: "" + distro: "fedora" + - variant: "default" + args: "" + distro: "arch" + container: ${{ matrix.distro == 'ubuntu' && 'ubuntu:latest' || matrix.distro == 'debian' && 'debian:stable-slim' || matrix.distro == 'fedora' && 'fedora:latest' || 'archlinux:latest' }} steps: - name: Checkout uses: actions/checkout@v4 - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - - - name: Install system dependencies + - name: Install system dependencies (Ubuntu/Debian) + if: matrix.distro == 'ubuntu' || matrix.distro == 'debian' run: | - sudo apt-get update - sudo apt-get install -y \ + apt-get update + apt-get install -y \ + curl \ llvm clang libclang-dev \ pkg-config \ libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \ - libpam0g-dev \ + libgdk-pixbuf-2.0-dev libpam0g-dev libdbus-1-dev \ libwayland-dev libxkbcommon-dev - - name: Build ${{ matrix.variant }} + - name: Install system dependencies (Fedora) + if: matrix.distro == 'fedora' + run: | + dnf install -y \ + curl \ + llvm clang clang-devel \ + pkgconfig \ + glib2-devel cairo-devel cairo-gobject-devel pango-devel atk-devel \ + gdk-pixbuf2-devel pam-devel dbus-devel \ + wayland-devel libxkbcommon-devel + + - name: Install system dependencies (Arch) + if: matrix.distro == 'arch' + run: | + pacman -Sy --noconfirm \ + base-devel \ + llvm clang pkgconf \ + glib2 cairo pango atk gdk-pixbuf2 \ + pam dbus \ + wayland libxkbcommon + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Build ${{ matrix.variant }} (${{ matrix.distro }}) run: cargo build --release ${{ matrix.args }} - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: rustlock-${{ matrix.variant }}-ubuntu - path: target/release/rustlock - - build-debian: - runs-on: ubuntu-latest - container: debian:stable-slim - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install system dependencies - run: | - apt-get update - apt-get install -y \ - llvm clang libclang-dev \ - pkg-config \ - libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \ - libpam0g-dev \ - libwayland-dev libxkbcommon-dev \ - cargo rust - - - name: Build - run: cargo build --release - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: rustlock-default-debian - path: target/release/rustlock - - build-fedora: - runs-on: ubuntu-latest - container: fedora:latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install system dependencies - run: | - dnf install -y \ - llvm clang libclang-devel \ - pkg-config \ - glib2-devel cairo-devel pango-devel atk-devel \ - pam-devel \ - wayland-devel libxkbcommon-devel \ - rust cargo - - - name: Build - run: cargo build --release - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: rustlock-default-fedora - path: target/release/rustlock - - build-arch: - runs-on: ubuntu-latest - container: archlinux:latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install system dependencies - run: | - pacman -Sy --noconfirm \ - llvm clang pkgconf \ - glib2 cairo pango atk \ - pam \ - wayland libxkbcommon \ - rust cargo - - - name: Build - run: cargo build --release - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: rustlock-default-arch + name: rustlock-${{ matrix.variant }}-${{ matrix.distro }} path: target/release/rustlock release: runs-on: ubuntu-latest - needs: [build-ubuntu, build-debian, build-fedora, build-arch] + needs: [release-build] permissions: contents: write steps: @@ -135,6 +94,9 @@ jobs: with: path: artifacts + - name: List artifacts + run: ls -la artifacts/ + - name: Determine tag id: tag run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT @@ -148,9 +110,9 @@ jobs: prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') }} files: | artifacts/rustlock-default-ubuntu/rustlock - artifacts/rustlock-networking-ubuntu/rustlock + artifacts/rustlock-no-networking-ubuntu/rustlock artifacts/rustlock-default-debian/rustlock artifacts/rustlock-default-fedora/rustlock artifacts/rustlock-default-arch/rustlock env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..5782c8c --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,68 @@ +name: Security Scan + +on: + schedule: + - cron: '0 0 * * 0' # Weekly on Sunday at midnight + workflow_dispatch: # Manual trigger + push: + branches: [main, master] + paths: + - 'Cargo.toml' + - 'Cargo.lock' + - 'deny.toml' + - '.github/workflows/security.yml' + +env: + CARGO_TERM_COLOR: always + +jobs: + security-audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Install security tools + run: | + cargo install cargo-audit + cargo install cargo-deny + + - name: Run cargo audit + run: cargo audit + + - name: Run cargo deny (advisories only) + run: cargo deny check advisories + + - name: Run cargo deny (full check) + run: cargo deny check + + - name: Generate Software Bill of Materials (SBOM) + run: | + cargo install cargo-cyclonedx + cargo cyclonedx --format json --output bom.json + + - name: Upload SBOM + uses: actions/upload-artifact@v4 + with: + name: sbom + path: bom.json + retention-days: 90 + + - name: Check for outdated dependencies + run: | + cargo install cargo-outdated + cargo outdated --exit-code 1 || echo "Some dependencies are outdated" + + - name: Security summary + run: | + echo "=== Security Scan Complete ===" + echo "✅ cargo audit - Vulnerability scanning" + echo "✅ cargo deny - Advisory and license checking" + echo "✅ SBOM generated - Software Bill of Materials" + echo "✅ Outdated dependencies checked" + echo "" + echo "Next scheduled scan: Weekly (Sunday 00:00 UTC)" + echo "Manual trigger: Click 'Run workflow' in GitHub Actions" \ No newline at end of file diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..083ca57 --- /dev/null +++ b/deny.toml @@ -0,0 +1,70 @@ +# Cargo-deny configuration for RustLock +# See: https://embarkstudios.github.io/cargo-deny/ + +[advisories] +# Check for security vulnerabilities +vulnerability = "deny" +# Check for unmaintained crates +unmaintained = "warn" +# Check for unsound crates +unsound = "deny" +# Check for yanked crates +yanked = "deny" +# Ignore specific advisories +ignore = [ + # Add specific advisory IDs to ignore here if needed +] + +# Sources for advisory database +[advisories.db] +# Use GitHub advisory database +github-data = "https://github.com/rustsec/advisory-db" +# Update frequency (daily) +update-frequency = "daily" + +[bans] +# Multiple versions of the same crate +multiple-versions = "allow" +# Wildcard dependencies (e.g., "1.*") +wildcards = "deny" + +# Skip specific crates from checks +skip = [ + # Add crate names to skip here if needed +] + +[licenses] +# Default license policy +default = "deny" +# Allow these licenses +allow = [ + "MIT", + "Apache-2.0", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "Zlib", + "Unlicense", + "CC0-1.0", + "MPL-2.0", + "AGPL-3.0-or-later", # Our own license +] +# Copyleft licenses that require special attention +copyleft = "warn" +# Unknown licenses +unlicensed = "deny" + +# Skip specific crates from license checks +skip = [ + # Add crate names to skip here if needed +] + +[sources] +# Allow only these registries +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# Deny git repositories (except for specific cases) +allow-git = [] + +[metadata] +# Minimum severity level to display +severity-threshold = "low" \ No newline at end of file