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
157 changes: 157 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
name: CI

on:
push:
branches:
- main
- 'feat/**'
- 'fix/**'
- 'chore/**'
paths:
- '.github/workflows/ci.yml'
- 'rust/**'
- 'agents/**'
- 'tools/**'
- 'scripts/**'
pull_request:
branches:
- main
paths:
- '.github/workflows/ci.yml'
- 'rust/**'
- 'agents/**'
- 'tools/**'
- 'scripts/**'
workflow_dispatch:

concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

defaults:
run:
working-directory: rust

# ── Job: validate agents ─────────────────────────────────────────────────────
jobs:
validate-agents:
name: Validate agent files
runs-on: ubuntu-latest
defaults:
run:
working-directory: .
steps:
- uses: actions/checkout@v4

- name: Check agent MD files
run: bash scripts/validate-agents.sh

# ── Job: rustfmt ─────────────────────────────────────────────────────────────
fmt:
name: cargo fmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

- uses: Swatinem/rust-cache@v2
with:
workspaces: rust -> target

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

# ── Job: clippy ──────────────────────────────────────────────────────────────
clippy:
name: cargo clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- uses: Swatinem/rust-cache@v2
with:
workspaces: rust -> target

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

# ── Job: test ────────────────────────────────────────────────────────────────
test:
name: cargo test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2
with:
workspaces: rust -> target

- name: Run workspace tests
run: cargo test --workspace

# ── Job: Windows smoke build ─────────────────────────────────────────────────
windows-smoke:
name: Windows build smoke
runs-on: windows-latest
defaults:
run:
working-directory: rust
shell: pwsh
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2
with:
workspaces: rust -> target

- name: Build (debug)
run: cargo build --workspace

- name: Smoke test binary
run: |
$bin = "target\debug\claude-tools.exe"
if (Test-Path $bin) {
& $bin --version
Write-Host "claude-tools binary OK"
} else {
Write-Host "No claude-tools binary found (workspace may not include binary crate yet)"
}
Comment on lines +126 to +133

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Windows 스모크 테스트가 바이너리 누락 시 실패하지 않습니다.

PowerShell 스크립트는 claude-tools.exe가 없을 때 메시지만 출력하고 정상 종료됩니다. 이는 빌드가 바이너리를 생성하지 못해도 테스트가 통과하는 것을 의미하며, 빌드 실패를 감지하지 못할 수 있습니다.

주석에 "workspace may not include binary crate yet"라고 명시되어 있지만, PR 목표에 따르면 바이너리 크레이트가 존재해야 합니다. 바이너리가 누락되면 테스트가 실패해야 합니다.

제안하는 수정
       - name: Smoke test binary
         run: |
           $bin = "target\debug\claude-tools.exe"
           if (Test-Path $bin) {
             & $bin --version
             Write-Host "claude-tools binary OK"
           } else {
-            Write-Host "No claude-tools binary found (workspace may not include binary crate yet)"
+            Write-Error "claude-tools binary not found at $bin"
+            exit 1
           }
📝 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
run: |
$bin = "target\debug\claude-tools.exe"
if (Test-Path $bin) {
& $bin --version
Write-Host "claude-tools binary OK"
} else {
Write-Host "No claude-tools binary found (workspace may not include binary crate yet)"
}
run: |
$bin = "target\debug\claude-tools.exe"
if (Test-Path $bin) {
& $bin --version
Write-Host "claude-tools binary OK"
} else {
Write-Error "claude-tools binary not found at $bin"
exit 1
}
🤖 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 126 - 133, The Windows smoke test
script currently prints a message and exits successfully when the
claude-tools.exe binary is not found, which allows the test to pass even if the
build fails to generate the binary. Change the else block in the PowerShell
script to exit with a failure code instead of just printing a message. When
Test-Path returns false for the $bin variable, use exit 1 or throw to cause the
workflow step to fail, ensuring that missing binaries are properly detected as
build failures rather than allowed to silently pass.


# ── Job: dogfood build ───────────────────────────────────────────────────────
dogfood:
name: Dogfood build (Linux)
runs-on: ubuntu-latest
needs: [fmt, clippy, test]
defaults:
run:
working-directory: .
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2
with:
workspaces: rust -> target

- name: Build via dogfood script
run: |
bash scripts/dogfood-build.sh

- name: Validate agents with built binary
run: bash scripts/validate-agents.sh
26 changes: 26 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM rust:bookworm

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
git \
libssl-dev \
pkg-config \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*

ENV CARGO_TERM_COLOR=always
WORKDIR /workspace

# Pre-fetch dependencies so layer is cached
COPY rust/Cargo.toml rust/Cargo.lock ./rust/
RUN cd rust && cargo fetch --locked 2>/dev/null || true

# Copy full source
COPY . .

RUN cd rust && cargo build --workspace --release \
&& cp target/release/claude-tools /usr/local/bin/claude-tools

CMD ["bash"]
25 changes: 18 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,32 @@ test-agents: ## Verify agent files exist and are non-empty
echo "Agents: $$ok OK, $$fail empty"

# ─── lint / format ─────────────────────────────────────────────────────────
.PHONY: lint fmt
.PHONY: lint fmt fmt-check
lint: ## Clippy lint (Rust)
cd $(RUST_DIR) && $(CARGO) clippy -- -D warnings

fmt: ## rustfmt + check Python style
cd $(RUST_DIR) && $(CARGO) fmt
@command -v ruff >/dev/null 2>&1 \
&& ruff format $(TOOLS_DIR)/ \
|| echo "ruff not found, skipping Python format"
fmt: ## Format all code (Rust + Python)
bash scripts/fmt.sh

fmt-check: ## Check formatting without modifying (CI mode)
bash scripts/fmt.sh --check

# ─── dev helpers ───────────────────────────────────────────────────────────
.PHONY: watch-cost env status
.PHONY: watch-cost env status dogfood container validate
watch-cost: ## Live cost monitor (requires claude-tools build)
@$(RUST_DIR)/target/release/claude-tools watch --interval 2

dogfood: ## Build from source with provenance check (like claw-code)
@bash scripts/dogfood-build.sh

container: ## Build Containerfile (requires Docker / Podman)
@command -v docker >/dev/null 2>&1 && docker build -f Containerfile -t claude-agents:dev . \
|| command -v podman >/dev/null 2>&1 && podman build -f Containerfile -t claude-agents:dev . \
|| { echo "docker or podman required"; exit 1; }

validate: ## Validate agent MD files
@bash scripts/validate-agents.sh

env: ## Show Claude environment status
@$(RUST_DIR)/target/release/claude-tools env

Expand Down
Loading
Loading