Skip to content

add ci#1

Open
damnthonyy wants to merge 5 commits intomainfrom
test/violation-pr
Open

add ci#1
damnthonyy wants to merge 5 commits intomainfrom
test/violation-pr

Conversation

@damnthonyy
Copy link
Copy Markdown
Member

No description provided.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add CI and PR analysis GitHub Actions workflows

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add CI workflow for Python build and dependency verification
• Add PR analysis workflow with struct-ia clean architecture checks
• Configure struct-ia provider to use OpenAI for analysis
Diagram
flowchart LR
  A["GitHub Pull Request"] -->|"triggers"| B["CI Workflow"]
  A -->|"triggers"| C["PR Analysis Workflow"]
  B --> D["Python Setup & Verification"]
  C --> E["struct-ia Analysis"]
  E --> F["Architecture Violations Check"]
  F --> G["PR Comment with Results"]
Loading

Grey Divider

File Changes

1. .github/workflows/ci.yml ⚙️ Configuration changes +32/-0

Add CI workflow for build verification

• New CI workflow triggered on pull requests to main and develop branches
• Checks out code, sets up Python 3.12, and installs dependencies
• Installs struct-ai package from GitHub feature branch
• Verifies Python source code compilation

.github/workflows/ci.yml


2. .github/workflows/pr_analysis.yml ⚙️ Configuration changes +55/-0

Add PR analysis workflow with struct-ia

• New PR analysis workflow triggered on pull request events (opened, synchronize, reopened)
• Runs struct-ia clean architecture analysis on PR changes
• Configures minimal permissions for code reading and PR commenting
• Supports multiple LLM providers (OpenAI, Anthropic, Google, Mistral, Ollama)
• Includes configurable violation handling with STRUCT_IA_FAIL_ON_VIOLATION flag

.github/workflows/pr_analysis.yml


3. .struct-ia.yaml ⚙️ Configuration changes +1/-0

Configure OpenAI provider for struct-ia

• Add OpenAI as the configured provider for struct-ia analysis

.struct-ia.yaml


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Apr 5, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider


Action required

1. Editable install breaks workflow🐞 Bug ≡ Correctness
Description
pr_analysis.yml runs pip install -e ., but this repository is intended to be run via
PYTHONPATH=src (not as an installable package), so the editable install is likely to fail and
block the job before analysis starts.
Code

.github/workflows/pr_analysis.yml[R34-39]

+      - name: Install dependencies
+        run: |
+          pip install --upgrade pip
+          pip install -r requirements.txt
+          pip install -e .
+
Evidence
The repo’s own instructions show running from source via PYTHONPATH=src and explicitly say
struct-ia is not installed from requirements.txt, indicating this repo isn’t set up as a
pip-installable project. Keeping pip install -e . in the workflow therefore risks immediate
workflow failure.

.github/workflows/pr_analysis.yml[34-39]
requirements.txt[1-10]
Best Practice: pip documentation (editable installs)

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`pip install -e .` is used in the PR Analysis workflow even though the repository appears to be intended to run from source (via `PYTHONPATH=src`), not installed as a package.
### Issue Context
This step can fail (and even if it succeeds in some environments, it’s unnecessary for running an external analyzer against the repo contents).
### Fix Focus Areas
- .github/workflows/pr_analysis.yml[34-39]
- requirements.txt[1-10]
### Suggested change
Either:
1) Remove `pip install -e .` entirely, or
2) Add proper packaging metadata (pyproject.toml / setup.py) if you truly intend to install this repo in CI.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unpinned git install 🐞 Bug ⛨ Security
Description
CI installs struct-ia from a moving Git branch ref, making builds non-reproducible and exposing CI
to supply-chain risk if that branch changes. This can cause unexpected CI failures or run unintended
code.
Code

.github/workflows/ci.yml[R27-30]

+      - name: Install struct-ia
+        run: |
+          pip install git+https://github.com/struct-ai/struct-ai.git@feat/20-github-action-analyse-pr
+
Evidence
The dependency is installed from GitHub using a branch name (feat/...) rather than a tag or commit
SHA, so the installed code can change over time without changes in this repo.

.github/workflows/ci.yml[27-30]
Best Practice: GitHub Actions security hardening

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`pip install git+https://...@feat/...` uses a mutable branch ref.
### Issue Context
Mutable refs can change without notice, breaking CI reproducibility and increasing supply-chain risk.
### Fix Focus Areas
- .github/workflows/ci.yml[27-30]
### Suggested change
Replace the branch ref with an immutable tag or commit SHA, e.g.:
- `pip install git+https://github.com/struct-ai/struct-ai.git@<commit_sha>`
(or a released version if available).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Fork PRs lack secrets 🐞 Bug ☼ Reliability
Description
pr_analysis.yml requires OPENAI_API_KEY but is triggered on pull_request; for PRs from forks,
GitHub does not expose repository secrets, so the job will fail or be skipped for external
contributors. This makes the PR analysis check unreliable depending on your contribution model.
Code

.github/workflows/pr_analysis.yml[R3-10]

+on:
+  pull_request:
+    branches:
+      - main
+    types:
+      - opened
+      - synchronize
+      - reopened
Evidence
The workflow is triggered by pull_request and references secrets.OPENAI_API_KEY. GitHub Actions
does not provide repository secrets to workflows triggered by forked PRs using pull_request.

.github/workflows/pr_analysis.yml[3-10]
.github/workflows/pr_analysis.yml[40-48]
Best Practice: GitHub Actions secrets model

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
PR Analysis depends on a secret (`OPENAI_API_KEY`) but runs on `pull_request`, which won’t have secrets for fork PRs.
### Issue Context
If you expect fork-based contributions, the check will frequently fail.
### Fix Focus Areas
- .github/workflows/pr_analysis.yml[3-10]
- .github/workflows/pr_analysis.yml[40-48]
### Suggested change
Choose one:
- Accept/document: analysis runs only for same-repo PRs.
- Add a safe maintainer-triggered path (`workflow_dispatch`) for fork PRs.
- Use `pull_request_target` only if you also avoid executing untrusted PR code (e.g., analyze via GitHub API/diff rather than checking out and running PR content).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread .github/workflows/pr_analysis.yml
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

struct-ia — Analyse architecturale

ℹ️ Aucun fichier Python modifié dans cette PR. Rien à analyser.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

struct-ia — Analyse architecturale

3 violation(s) détectée(s) sur 3 fichier(s) analysé(s).


/home/runner/work/struct-ai-test-app/struct-ai-test-app/src/app/domain/ports.py — ligne 4

Règle violée : layer_violation
Concept : Layer Isolation

In Clean Architecture, the domain layer should be independent of any infrastructure details. This ensures that the core business logic remains unaffected by changes in the infrastructure layer. By importing SqlUserRepository directly into the domain, we create a tight coupling between the domain and infrastructure layers, violating the principle of layer isolation. Instead, the domain should depend on abstractions, such as interfaces or ports, which can be implemented by the infrastructure layer. This allows the infrastructure to be swapped or modified without impacting the domain logic.

Voir l'exemple de refactoring

Avant :

from app.infrastructure.repository import SqlUserRepository

def make_repository() -> SqlUserRepository:

Après :

from app.domain.ports import UserRepository

def make_repository() -> UserRepository:

Ressources :


/home/runner/work/struct-ai-test-app/struct-ai-test-app/src/app/domain/settings_mirror.py — ligne 4

Règle violée : layer_violation
Concept : Layer Isolation

In Clean Architecture, the domain layer should be independent of outer layers like entrypoints or adapters. This ensures that the core business logic remains unaffected by changes in how the application interacts with the outside world. By importing from an entrypoint, the domain layer becomes tightly coupled to the application's configuration details, which violates the principle of layer isolation. Instead, the domain should depend on abstractions or interfaces that can be implemented by the outer layers.

Voir l'exemple de refactoring

Avant :

from app.entrypoints.main import APP_CONFIG

Après :

from app.core.config import Config

# Assume Config is an abstraction that can be implemented by outer layers

def get_configured_db_path(config: Config) -> str:

Ressources :


/home/runner/work/struct-ai-test-app/struct-ai-test-app/src/app/infrastructure/cli_bridge.py — ligne 6

Règle violée : layer_violation
Concept : Layer Isolation

In Clean Architecture, each layer should be independent and should not import from layers above it. The domain layer should not depend on the entrypoints or infrastructure layers. This ensures that the core logic remains unaffected by changes in how the application is delivered or how external systems are integrated. In this case, importing create_user_from_http_payload from entrypoints into an infrastructure module violates this principle. Instead, consider defining an abstraction in the domain layer that can be implemented by the entrypoints layer, thus inverting the dependency.

Voir l'exemple de refactoring

Avant :

from app.entrypoints.main import create_user_from_http_payload

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

Après :

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

Ressources :

@qodo-code-review
Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: struct-ia — Clean Architecture Analysis

Failed stage: Run struct-ia PR analysis [❌]

Failed test name: ""

Failure summary:

The action failed because the struct_ai.entrypoints.github_action.main analysis detected
architecture rule violations and STRUCT_IA_FAIL_ON_VIOLATION is set to true, causing the job to exit
with code 1.
- 3 modified Python files were analyzed and each reported 1 violation:
-
src/app/domain/ports.py — 1 violation (Layer Isolation [layer_violation])
-
src/app/domain/settings_mirror.py — 1 violation (Layer Isolation [layer_violation])
-
src/app/infrastructure/cli_bridge.py — 1 violation (Layer Isolation [layer_violation])
- The tool
posted a PR comment, then terminated with: 3 violation(s) détectée(s) — CI en échec. (logged from
main.py:97), resulting in Process completed with exit code 1.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

249:  ##[group]Run python -m struct_ai.entrypoints.github_action.main
250:  �[36;1mpython -m struct_ai.entrypoints.github_action.main�[0m
251:  shell: /usr/bin/bash -e {0}
252:  env:
253:  pythonLocation: /opt/hostedtoolcache/Python/3.12.13/x64
254:  PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.12.13/x64/lib/pkgconfig
255:  Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.13/x64
256:  Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.13/x64
257:  Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.13/x64
258:  LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.12.13/x64/lib
259:  GITHUB_TOKEN: ***
260:  GITHUB_REPOSITORY: struct-ai/struct-ai-test-app
261:  PR_NUMBER: 1
262:  GITHUB_WORKSPACE: /home/runner/work/struct-ai-test-app/struct-ai-test-app
263:  OPENAI_API_KEY: ***
264:  STRUCT_IA_FAIL_ON_VIOLATION: true
265:  ##[endgroup]
266:  �[32m2026-04-05 22:50:25.207�[0m | �[1mINFO    �[0m | �[36m__main__�[0m:�[36m_get_changed_python_files�[0m:�[36m133�[0m - �[1m3 fichier(s) .py modifié(s) détecté(s).�[0m
267:  �[32m2026-04-05 22:50:25.209�[0m | �[1mINFO    �[0m | �[36m__main__�[0m:�[36m_load_config�[0m:�[36m155�[0m - �[1mConfiguration chargée depuis /home/runner/work/struct-ai-test-app/struct-ai-test-app/.struct-ia.yaml�[0m
268:  �[32m2026-04-05 22:50:29.356�[0m | �[1mINFO    �[0m | �[36m__main__�[0m:�[36m_run_analysis�[0m:�[36m220�[0m - �[1msrc/app/domain/ports.py — 1 violation(s).�[0m
269:  �[32m2026-04-05 22:50:31.780�[0m | �[1mINFO    �[0m | �[36m__main__�[0m:�[36m_run_analysis�[0m:�[36m220�[0m - �[1msrc/app/domain/settings_mirror.py — 1 violation(s).�[0m
270:  �[32m2026-04-05 22:50:34.866�[0m | �[1mINFO    �[0m | �[36m__main__�[0m:�[36m_run_analysis�[0m:�[36m220�[0m - �[1msrc/app/infrastructure/cli_bridge.py — 1 violation(s).�[0m
271:  �[32m2026-04-05 22:50:35.488�[0m | �[1mINFO    �[0m | �[36m__main__�[0m:�[36m_post_pr_comment�[0m:�[36m321�[0m - �[1mCommentaire publié sur la PR #1.�[0m
272:  �[32m2026-04-05 22:50:35.489�[0m | �[31m�[1mERROR   �[0m | �[36m__main__�[0m:�[36mmain�[0m:�[36m97�[0m - �[31m�[1m3 violation(s) détectée(s) — CI en échec.�[0m
273:  ##[error]Layer Isolation [layer_violation]
274:  ##[error]Layer Isolation [layer_violation]
275:  ##[error]Layer Isolation [layer_violation]
276:  ##[error]Process completed with exit code 1.
277:  Post job cleanup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant