Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI

on:
push:
branches: [ main, ci ]
pull_request:
branches: [ main, ci ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

Comment on lines +10 to +15

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Scope the job token down and stop persisting it.

This workflow only needs repository read access, but without an explicit permissions: block GitHub derives GITHUB_TOKEN scopes from the repo/org defaults, and actions/checkout persists that token for later git commands by default. Since the job then executes repository code during cargo build and cargo test, keep the token read-only and disable persisted credentials unless a later step actually needs to push. (docs.github.com)

Suggested hardening
 jobs:
   build:
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
 
     steps:
     - uses: actions/checkout@v4
+      with:
+        persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 14-14: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 10-34: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 10 - 15, Add an explicit permissions
block to the ci workflow job so GITHUB_TOKEN is read-only, and update the
actions/checkout step to stop persisting credentials by default. The fix should
be applied in the build job around actions/checkout@v4, using the job-level
permissions setting and the checkout configuration so later cargo build/cargo
test steps can run without a persisted write-capable token unless a future step
truly needs it.

Source: Linters/SAST tools

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
Comment thread
coderabbitai[bot] marked this conversation as resolved.

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

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

- name: Build
run: cargo build --release

- name: Run tests
run: cargo test --release
104 changes: 104 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Development Commands

**Build the project:**
```bash
cargo build
```

**Run the server:**
```bash
cargo run
```
The server will start on http://127.0.0.1:3000 with endpoints:
- GET /health - returns {"status": "ok"}
- POST /echo - accepts JSON {message: string, value: i32} and returns {result: string, processed_value: i32*2}

**Run tests:**
```bash
cargo test
```

**Run a specific test:**
```bash
cargo test test_name
```
Example: `cargo test test_health_endpoint`

**Run tests in release mode (for performance measurement):**
```bash
cargo test --release
```

**Check code formatting:**
```bash
cargo fmt -- --check
```

**Fix formatting:**
```bash
cargo fmt
```

**Check for lint warnings:**
```bash
cargo clippy -- -D warnings
```

## Project Structure

This is a Rust workspace with a single Axum web server:

```
Inference/
├── Cargo.toml # Workspace configuration (members = ["server"])
├── Cargo.lock
├── server/
│ ├── Cargo.toml # Package definition (depends on axum, tokio, serde)
│ └── src/
│ └── main.rs # Server implementation and tests
└── target/ # Build artifacts (gitignored)
```

### server/src/main.rs

The server implements:
- **Health check endpoint** (`GET /health`): Returns JSON `{"status": "ok"}`
- **Echo endpoint** (`POST /echo`):
- Accepts JSON: `{"message": string, "value": i32}`
- Returns JSON: `{"result": "Received: {message}", "processed_value": value * 2}`
- **Unit tests**:
- Struct serialization/deserialization tests
- JSON serialization/deserialization tests
- HTTP endpoint tests using Tokio runtime
- Logic test verifying the value doubling behavior

### Dependencies (managed via workspace)
- **axum**: Web framework for building the API
- **tokio**: Async runtime (with full feature set)
- **serde**: Serialization framework (with derive feature)
- **serde_json**: JSON serialization/deserialization

## Development Notes

1. The server uses Tokio's async runtime (`#[tokio::main]`)
2. JSON handling is done via Serde's derive macros for automatic serialization/deserialization
3. All tests are contained in the same file as the implementation (standard for small Rust projects)
4. The server binds to 127.0.0.1:3000 by default
5. No external configuration is needed - all settings are hardcoded for simplicity

## Common Tasks

**Adding a new endpoint:**
1. Add a new async function that takes appropriate extractors (like Json<T>, Query<T>, or Path<T>)
2. Add a route to the Router in the main function using .route()
3. Implement the function logic
4. Add tests for the new endpoint

**Running a single test with more verbosity:**
```bash
cargo test test_name -- --nocapture
```
4 changes: 1 addition & 3 deletions server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ async fn main() {
.await
.expect("Failed to bind to address");

axum::serve(listener, app)
.await
.expect("Server failed");
axum::serve(listener, app).await.expect("Server failed");
}

#[cfg(test)]
Expand Down
Loading