posthog-rs 0.13.2

The official Rust client for Posthog (https://posthog.com/).
Documentation
name: CI

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  fmt:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Rust
        run: |
          rustup update stable
          rustup default stable
          rustup component add rustfmt

      - name: Check formatting
        run: cargo fmt -- --check

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Rust
        run: |
          rustup update stable
          rustup default stable
          rustup component add clippy

      - name: Cache cargo
        uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-clippy-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-

      - name: Clippy
        run: cargo clippy -- -D warnings

  public-api:
    name: Public API
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install public API tooling
        run: |
          rustup toolchain install nightly-2026-06-12 --profile minimal
          cargo install cargo-public-api --version 0.52.0 --locked

      - name: Check public API snapshot
        run: scripts/check-public-api.sh

  build:
    name: Build (${{ matrix.name }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: default features
            toolchain: stable
            cache-key: default-features
            command: cargo build --verbose
          - name: capture-v1
            toolchain: stable
            cache-key: capture-v1
            command: cargo build --verbose --features capture-v1
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Rust ${{ matrix.toolchain }}
        run: |
          rustup toolchain install ${{ matrix.toolchain }} --profile minimal
          rustup default ${{ matrix.toolchain }}

      - name: Print Rust version
        run: rustc --version

      - name: Cache cargo
        uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-build-${{ matrix.toolchain }}-${{ matrix.cache-key }}-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-${{ matrix.toolchain }}-
            ${{ runner.os }}-cargo-

      - name: Build
        run: ${{ matrix.command }}

  package:
    name: Cargo publish dry run
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Rust
        run: |
          rustup update stable
          rustup default stable

      - name: Cache cargo
        uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-publish-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-

      - name: Publish dry run
        run: cargo publish --dry-run --locked

  test:
    name: ${{ matrix.name }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: Unit test (default features)
            cache-key: default-features
            command: cargo test --verbose
          - name: Unit test (workspace)
            cache-key: workspace
            command: cargo test --workspace --verbose
          - name: Unit test (capture-v1, async client)
            cache-key: capture-v1-async-client
            command: cargo test --verbose --features capture-v1
          - name: Unit test (capture-v1, blocking client)
            cache-key: capture-v1-blocking-client
            command: cargo test --verbose --no-default-features --features capture-v1
          - name: Unit test (error-tracking, blocking client)
            cache-key: error-tracking-blocking-client
            command: cargo test --verbose --no-default-features --features error-tracking
          - name: Unit test (error-tracking + capture-v1, blocking client)
            cache-key: error-tracking-capture-v1-blocking-client
            command: cargo test --verbose --no-default-features --features error-tracking,capture-v1
          - name: E2E test
            cache-key: e2e
            command: cargo test --verbose --features e2e-test --no-default-features
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Rust
        run: |
          rustup update stable
          rustup default stable

      - name: Cache cargo
        uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-test-${{ matrix.cache-key }}-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-test-
            ${{ runner.os }}-cargo-

      - name: Run tests
        if: matrix.cache-key != 'e2e'
        run: ${{ matrix.command }}

      - name: Run E2E tests
        if: matrix.cache-key == 'e2e'
        run: ${{ matrix.command }}
        env:
          POSTHOG_RS_E2E_TEST_API_KEY: ${{ secrets.POSTHOG_RS_E2E_TEST_API_KEY }}