name: Rust CI on: workflow_dispatch: push: branches: [master, main] pull_request: env: CARGO_TERM_COLOR: always jobs: # Job to decide if we should run rust ci # See https://github.com/dorny/paths-filter#conditional-execution for more details changes: runs-on: ubuntu-latest timeout-minutes: 5 if: github.repository == 'PostHog/posthog' name: Determine need to run Rust checks # Set job outputs to values from filter step outputs: rust: ${{ steps.filter.outputs.rust }} steps: # For pull requests it's not necessary to checkout the code, but we # also want this to run on master so we need to checkout - uses: actions/checkout@v3 - uses: dorny/paths-filter@v2 id: filter with: filters: | rust: # Avoid running rust tests for irrelevant changes - 'rust/**' - '.github/workflows/rust.yml' - '.github/workflows/rust-docker-build.yml' - '.github/workflows/rust-hook-migrator-docker.yml' - '.github/workflows/rust-cyclotron-migrator-docker.yml' - 'posthog/management/commands/setup_test_environment.py' - 'posthog/migrations/**' - 'ee/migrations/**' build: name: Build Rust services needs: changes runs-on: depot-ubuntu-22.04-4 defaults: run: working-directory: rust steps: # Checkout project code # Use sparse checkout to only select files in rust directory # Turning off cone mode ensures that files in the project root are not included during checkout - uses: actions/checkout@v3 if: needs.changes.outputs.rust == 'true' with: sparse-checkout: 'rust/' sparse-checkout-cone-mode: false - name: Install rust if: needs.changes.outputs.rust == 'true' uses: dtolnay/rust-toolchain@1.82 - uses: actions/cache@v4 if: needs.changes.outputs.rust == 'true' with: path: | ~/.cargo/registry ~/.cargo/git rust/target key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }} - name: Run cargo build if: needs.changes.outputs.rust == 'true' run: cargo build --all --locked --release && find target/release/ -maxdepth 1 -executable -type f | xargs strip test: name: Test Rust services strategy: matrix: package: - feature-flags - others needs: changes runs-on: depot-ubuntu-22.04-4 timeout-minutes: 10 defaults: run: working-directory: rust steps: # Checkout project code # Use sparse checkout to only select files in rust directory # Turning off cone mode ensures that files in the project root are not included during checkout - uses: actions/checkout@v3 if: needs.changes.outputs.rust == 'true' && matrix.package == 'others' with: sparse-checkout: 'rust/' sparse-checkout-cone-mode: false # For flags checkout entire repository - uses: actions/checkout@v3 if: needs.changes.outputs.rust == 'true' && matrix.package == 'feature-flags' - name: Setup main repo dependencies for flags if: needs.changes.outputs.rust == 'true' && matrix.package == 'feature-flags' run: | docker compose -f ../docker-compose.dev.yml down docker compose -f ../docker-compose.dev.yml up -d echo "127.0.0.1 kafka" | sudo tee -a /etc/hosts - name: Setup dependencies if: needs.changes.outputs.rust == 'true' && matrix.package == 'others' run: | docker compose up kafka redis db echo_server -d --wait docker compose up setup_test_db echo "127.0.0.1 kafka" | sudo tee -a /etc/hosts - name: Install rust if: needs.changes.outputs.rust == 'true' uses: dtolnay/rust-toolchain@1.82 - uses: actions/cache@v4 if: needs.changes.outputs.rust == 'true' with: path: | ~/.cargo/registry ~/.cargo/git rust/target key: ${ runner.os }-cargo-debug-${{ hashFiles('**/Cargo.lock') }} - name: Set up Python if: needs.changes.outputs.rust == 'true' && matrix.package == 'feature-flags' uses: actions/setup-python@v5 with: python-version: 3.11.9 cache: 'pip' cache-dependency-path: '**/requirements*.txt' token: ${{ secrets.POSTHOG_BOT_GITHUB_TOKEN }} # uv is a fast pip alternative: https://github.com/astral-sh/uv/ - run: pip install uv if: needs.changes.outputs.rust == 'true' && matrix.package == 'feature-flags' - name: Install SAML (python3-saml) dependencies if: needs.changes.outputs.rust == 'true' && matrix.package == 'feature-flags' run: | sudo apt-get update sudo apt-get install libxml2-dev libxmlsec1-dev libxmlsec1-openssl - name: Install python dependencies if: needs.changes.outputs.rust == 'true' && matrix.package == 'feature-flags' run: | uv pip install --system -r ../requirements-dev.txt uv pip install --system -r ../requirements.txt - name: Set up databases if: needs.changes.outputs.rust == 'true' && matrix.package == 'feature-flags' env: DEBUG: 'true' TEST: 'true' SECRET_KEY: 'abcdef' # unsafe - for testing only DATABASE_URL: 'postgres://posthog:posthog@localhost:5432/posthog' run: cd ../ && python manage.py setup_test_environment --only-postgres - name: Download MaxMind Database if: needs.changes.outputs.rust == 'true' run: | mkdir -p ../share curl -L "https://mmdbcdn.posthog.net/" --http1.1 | brotli --decompress --output=../share/GeoLite2-City.mmdb - name: Run cargo test if: needs.changes.outputs.rust == 'true' run: | echo "Starting cargo test" RUST_BACKTRACE=1 cargo test --all-features ${{ matrix.package == 'feature-flags' && '--package feature-flags' || '--workspace --exclude feature-flags' }} echo "Cargo test completed" linting: name: Lint Rust services needs: changes runs-on: depot-ubuntu-22.04-4 defaults: run: working-directory: rust steps: # Checkout project code # Use sparse checkout to only select files in rust directory # Turning off cone mode ensures that files in the project root are not included during checkout - uses: actions/checkout@v3 if: needs.changes.outputs.rust == 'true' with: sparse-checkout: 'rust/' sparse-checkout-cone-mode: false - name: Install rust if: needs.changes.outputs.rust == 'true' uses: dtolnay/rust-toolchain@1.82 with: components: clippy,rustfmt - uses: actions/cache@v4 if: needs.changes.outputs.rust == 'true' with: path: | ~/.cargo/registry ~/.cargo/git rust/target key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} - name: Check format if: needs.changes.outputs.rust == 'true' run: cargo fmt -- --check - name: Run clippy if: needs.changes.outputs.rust == 'true' run: cargo clippy --all-targets --all-features -- -D warnings - name: Run cargo check if: needs.changes.outputs.rust == 'true' run: cargo check --all-features shear: name: Shear Rust services needs: changes runs-on: depot-ubuntu-22.04-4 defaults: run: working-directory: rust steps: # Checkout project code # Use sparse checkout to only select files in rust directory # Turning off cone mode ensures that files in the project root are not included during checkout - uses: actions/checkout@v3 if: needs.changes.outputs.rust == 'true' with: sparse-checkout: 'rust/' sparse-checkout-cone-mode: false - name: Install cargo-binstall if: needs.changes.outputs.rust == 'true' uses: cargo-bins/cargo-binstall@main - name: Install cargo-shear if: needs.changes.outputs.rust == 'true' run: cargo binstall --no-confirm cargo-shear - run: cargo shear if: needs.changes.outputs.rust == 'true'