swadhinbiswas WIP save-point: production hardening, H3 removal, fmt gate, and accumulated phase work · 7/15/2026
2080d40
221 lines · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
name: CI

on:
  push:
    branches: [main]
    tags: ["v*"]
  pull_request:
    branches: [main]

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-D warnings"

jobs:
  check:
    name: Build & Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Install Python (for PyO3)
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

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

      - name: Format check
        run: cargo fmt --check

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

      - name: Build
        run: cargo build --workspace

      - name: Test
        run: cargo test --workspace

  miri:
    name: Miri (justapi-core)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust nightly + Miri
        uses: dtolnay/rust-toolchain@nightly
        with:
          components: miri

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

      - name: Run Miri on justapi-core
        run: cargo +nightly miri test -p justapi-core
        env:
          MIRIFLAGS: "-Zmiri-disable-isolation"
  pytest:
    name: Pytest (justapi-py)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install pytest httpx pydantic typing_extensions uv maturin

      - name: Build and install justapi
        run: |
          maturin develop -m crates/justapi-py/Cargo.toml

      - name: Run pytest
        run: |
          PYTHONPATH=./crates/justapi-py/python pytest

  pytest-freethreaded:
    name: Pytest (free-threaded / no GIL)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v5

      - name: Install free-threaded CPython
        run: uv python install cpython-3.14+freethreaded

      - name: Create venv and install deps
        run: |
          uv venv --python cpython-3.14+freethreaded .venv-ft
          uv pip install --python .venv-ft pytest pytest_asyncio pydantic jinja2 httpx maturin

      - name: Build and install justapi (free-threaded)
        run: |
          . .venv-ft/bin/activate
          maturin develop -m crates/justapi-py/Cargo.toml

      - name: Run pytest with the GIL disabled
        run: |
          . .venv-ft/bin/activate
          PYTHON_GIL=0 PYTHONPATH=./crates/justapi-py/python pytest

  verify-rust-first:
    name: Verify Rust-first mandate (AGENTS.md §2)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Ensure scheduling/concurrency is not re-implemented in Python
        run: |
          echo "Rust-first mandate (AGENTS.md §2): scheduling, worker/thread pools,"
          echo "and concurrency primitives must live in Rust, not in the Python package."
          matches=$(grep -rnE "^\s*class\s+\w*(Pool|Scheduler|Worker|Executor|Thread)\w*" \
                     crates/justapi-py/python/justapi/ --include="*.py" \
                     | grep -v "/test_")
          if [ -n "$matches" ]; then
            echo "::error::Framework Python re-implements a Rust-owned subsystem (scheduling/thread pool):"
            echo "$matches"
            echo "Move this into justapi-core / justapi-py Rust. See AGENTS.md §2."
            exit 1
          fi
          echo "OK: no Python-side scheduling/thread-pool classes found."

  audit:
    name: Security Audit (cargo-audit)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install cargo-audit
        run: cargo install cargo-audit --locked

      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
          key: ${{ runner.os }}-audit-${{ hashFiles('**/Cargo.lock') }}

      - name: Run audit
        run: cargo audit

  deny:
    name: License & Dependency Check (cargo-deny)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install cargo-deny
        uses: EmbarkStudios/cargo-deny-action@v2
        with:
          command: check
          arguments: --all-features

  docker:
    name: Build & Push Docker Image
    runs-on: ubuntu-latest
    needs: [check]
    if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,format=long

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max