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

on:
pull_request:
branches:
- main
- develop

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

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

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Install struct-ia
run: |
pip install git+https://github.com/struct-ai/struct-ai.git@feat/20-github-action-analyse-pr

- name: Verify Python sources
run: python -m compileall -q src
52 changes: 52 additions & 0 deletions .github/workflows/pr_analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: PR Analysis

on:
pull_request:
branches:
- main
types:
- opened
- synchronize
- reopened

# Minimal permissions: read code, write PR comments.
permissions:
contents: read
pull-requests: write

jobs:
struct-ia-review:
name: struct-ia — Clean Architecture Analysis
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# Full history required for git diff against origin/main
fetch-depth: 0

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

- name: Install dependencies
run: pip install "git+https://github.com/struct-ai/struct-ai.git@feat/20-github-action-analyse-pr"

Comment thread
qodo-code-review[bot] marked this conversation as resolved.
- name: Run struct-ia PR analysis
run: python -m struct_ai.entrypoints.github_action.main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.number }}
GITHUB_WORKSPACE: ${{ github.workspace }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
# Uncomment the provider you want to use instead of OpenAI:
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
# MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
# OLLAMA_BASE_URL: ${{ secrets.OLLAMA_BASE_URL }}
#
# Set to "false" to make violations warnings-only (CI won't fail).
STRUCT_IA_FAIL_ON_VIOLATION: "true"
7 changes: 7 additions & 0 deletions .struct-ia.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ layers:
- name: entrypoints
paths:
- entrypoints

# Démonstration struct-ia : fichiers avec layer_violation volontaire (imports inter-couches).
# - domain/model.py, domain/ports.py → import infrastructure
# - domain/settings_mirror.py → import entrypoints
# - infrastructure/repository.py, infrastructure/cli_bridge.py → import entrypoints

provider: openai
8 changes: 8 additions & 0 deletions src/app/domain/ports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Intentional violation: domain re-declares infrastructure coupling."""

# struct-ia: expect layer_violation — domain imports infrastructure.
from app.infrastructure.repository import SqlUserRepository

Check failure on line 4 in src/app/domain/ports.py

View workflow job for this annotation

GitHub Actions / struct-ia — Clean Architecture Analysis

Clean Architecture violation

Layer Isolation [layer_violation]


def make_repository() -> SqlUserRepository:
return SqlUserRepository()
8 changes: 8 additions & 0 deletions src/app/domain/settings_mirror.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Intentional violation: domain must not depend on entrypoints (outer layer)."""

# struct-ia: expect layer_violation — domain imports entrypoints.
from app.entrypoints.main import APP_CONFIG

Check failure on line 4 in src/app/domain/settings_mirror.py

View workflow job for this annotation

GitHub Actions / struct-ia — Clean Architecture Analysis

Clean Architecture violation

Layer Isolation [layer_violation]


def get_configured_db_path() -> str:
return str(APP_CONFIG.get("db_path", "db/users.json"))
10 changes: 10 additions & 0 deletions src/app/infrastructure/cli_bridge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Intentional violation: infrastructure must not depend on entrypoints."""

from typing import Any, Dict

# struct-ia: expect layer_violation — infrastructure imports entrypoints.
from app.entrypoints.main import create_user_from_http_payload

Check failure on line 6 in src/app/infrastructure/cli_bridge.py

View workflow job for this annotation

GitHub Actions / struct-ia — Clean Architecture Analysis

Clean Architecture violation

Layer Isolation [layer_violation]


def bootstrap_user_from_cli_payload(payload: Dict[str, Any]) -> None:
create_user_from_http_payload(payload)
Loading