ci: add GitHub Actions workflows for phase-1 readiness#3
Conversation
Add four new workflows: - schema-validation.yml: migration drift detection and cycle testing - dependency-check.yml: weekly pip-audit vulnerability scanning - phase-snapshot.yml: audit snapshots for phase-* branches - cd-release.yml: automated releases with release-please Add release-please configuration files for semantic versioning. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reviewer's GuideAdds a set of GitHub Actions workflows to support phase-branch audit snapshots, schema validation with migration drift detection, weekly dependency vulnerability scanning, and automated semantic-release-style CD via release-please, wired around a uv-based Python toolchain and Postgres test DBs. Sequence diagram for CD release creation and packagingsequenceDiagram
actor Dev
participant GitHub
participant ReleaseWorkflow as Release_please_workflow
participant BuildWorkflow as Build_package_workflow
participant ReleasePlease as release_please_action
participant GHReleases as GitHub_Releases
Dev->>GitHub: Push commit to main
GitHub->>ReleaseWorkflow: Trigger CD Release workflow
ReleaseWorkflow->>ReleasePlease: Run release-please-action with config/manifest
ReleasePlease-->>ReleaseWorkflow: Outputs release_created, tag_name, version
alt Release created
ReleaseWorkflow-->>BuildWorkflow: needs release-please with release_created == true
GitHub->>BuildWorkflow: Start build-package job
BuildWorkflow->>GitHub: Checkout repository at tag_name
BuildWorkflow->>BuildWorkflow: Install uv, Python, build dependency
BuildWorkflow->>BuildWorkflow: Build distribution artifacts (dist/*)
BuildWorkflow->>GHReleases: Upload dist/* to release tag
BuildWorkflow->>GitHub: Upload dist/ as workflow artifact
else No release created
ReleaseWorkflow-->>Dev: No new release (no changes or already released)
end
Flow diagram for Phase Snapshot workflow jobsflowchart TD
Trigger["Push to phase-* branch"] --> ValidateJob
subgraph ValidateJob["Job: validate (Full Validation)"]
V1["Checkout code"] --> V2["Start Postgres pgvector service"]
V2 --> V3["Install uv and Python 3.12"]
V3 --> V4["uv sync dependencies (dev + extras)"]
V4 --> V5["Lint: ruff check + format --check"]
V5 --> V6["Type check: mypy app/ and pyright app/"]
V6 --> V7["Run migrations: alembic upgrade head"]
V7 --> V8["Run tests: pytest -v"]
V5 -->|lint_status| ValidateOutputs
V6 -->|typecheck_status| ValidateOutputs
V7 -->|migration_status| ValidateOutputs
V8 -->|test_status| ValidateOutputs
end
ValidateOutputs["Expose job outputs: lint/typecheck/test/migration statuses"] --> SnapshotJob
subgraph SnapshotJob["Job: create-snapshot (Audit Snapshot)"]
S1["Checkout code with full history"] --> S2["Install uv and Python 3.12"]
S2 --> S3["Extract phase number from branch name"]
S3 --> S4["Generate snapshot metadata (timestamp, SHAs, tag name)"]
S4 --> S5["Collect audit data: audit-data.json and requirements-frozen.txt"]
S5 --> S6["Generate SNAPSHOT-REPORT.md"]
S6 --> S7["Upload audit artifact (1 year retention)"]
S7 --> S8["Create annotated git tag and push"]
S8 --> S9["Write GitHub Actions summary"]
end
ValidateJob -->|needs validate| SnapshotJob
Flow diagram for Schema Validation workflowflowchart TD
TriggerPush["Push affecting alembic/models/database"] --> SchemaJob
TriggerPR["PR affecting alembic/models/database"] --> SchemaJob
subgraph SchemaJob["Job: schema-validation (Validate Database Schema)"]
S1["Checkout code"] --> S2["Start Postgres pgvector schema DB"]
S2 --> S3["Install uv and Python 3.12"]
S3 --> S4["uv sync dependencies (dev + extras)"]
S4 --> S5["Fresh DB migration test: alembic upgrade head"]
S5 --> S6["Check migration chain: alembic heads single head enforcement"]
S6 --> S7["Schema drift detection: alembic check"]
S7 --> S8["Downgrade/upgrade cycle: downgrade -1 then upgrade head and compare revisions"]
S8 --> S9["Generate schema report in GitHub summary (history + current)"]
end
Flow diagram for Dependency Security Check workflowflowchart TD
TriggerCron["Weekly schedule (Sun 00:00 UTC)"] --> ScanJob
TriggerManual["workflow_dispatch with fail_on_severity"] --> ScanJob
subgraph ScanJob["Job: vulnerability-scan (Python Vulnerability Scan)"]
D1["Checkout code"] --> D2["Install uv and Python 3.12"]
D2 --> D3["uv sync dependencies (dev + extras)"]
D3 --> D4["Install pip-audit via uv pip"]
D4 --> D5["Export requirements from uv lock to requirements-audit.txt"]
D5 --> D6["Run pip-audit JSON, write audit-results.json (non-failing)"]
D6 --> D7["Run pip-audit SARIF, write audit-results.sarif (non-failing)"]
D7 --> D8["Upload SARIF to GitHub Security tab"]
D6 --> D9["Upload JSON audit artifact and requirements-audit.txt"]
D9 --> D10["Analyze vulnerabilities using jq, write summary and has_vulnerabilities output"]
D10 --> D11["Fail job if has_vulnerabilities true and threshold met"]
end
Flow diagram for CD Release workflowflowchart TD
TriggerMain["Push to main"] --> ReleaseJob
subgraph ReleaseJob["Job: release-please"]
R1["Run googleapis/release-please-action"] --> R2["Read release-please-config.json and .release-please-manifest.json"]
R2 --> R3["Create or update Release PR and Git tag"]
R3 --> R4["Set outputs: release_created, tag_name, version, upload_url"]
end
ReleaseJob -->|release_created == 'true'| BuildJob
subgraph BuildJob["Job: build-package"]
B1["Checkout code at released tag"] --> B2["Install uv and Python 3.12"]
B2 --> B3["Install build dependency via uv pip"]
B3 --> B4["Build Python package: python -m build (dist/*)"]
B4 --> B5["Upload artifacts to GitHub Release using gh release upload"]
B5 --> B6["Upload dist/ as Actions artifact"]
B6 --> B7["Generate GitHub summary with tag, version, and artifact listing"]
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughThis pull request introduces a comprehensive CI/CD infrastructure layer consisting of four new GitHub Actions workflows for release automation, dependency vulnerability scanning, phase-based snapshot auditing, and database schema validation. It also adds release-please configuration for version management and accompanying documentation with workflow diagrams. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
dependency-check.yml, thefail_on_severityinput and severity-threshold logic don’t actually vary behavior by severity (pip-audit has no severity data and the job fails on any vulnerability forhigh/critical), so consider either simplifying the interface or explicitly encoding the intended mapping (e.g., fail on any vuln vs. only those with fixes) to avoid a misleading configuration knob. - In
dependency-check.yml’s Analyze vulnerabilities step, theCRITICAL_COUNTvariable is computed but never used, and the jq filter is more complex than needed given the current logic—either wire this into the decision to fail the job or remove it to keep the script minimal and easier to maintain.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `dependency-check.yml`, the `fail_on_severity` input and severity-threshold logic don’t actually vary behavior by severity (pip-audit has no severity data and the job fails on any vulnerability for `high`/`critical`), so consider either simplifying the interface or explicitly encoding the intended mapping (e.g., fail on any vuln vs. only those with fixes) to avoid a misleading configuration knob.
- In `dependency-check.yml`’s Analyze vulnerabilities step, the `CRITICAL_COUNT` variable is computed but never used, and the jq filter is more complex than needed given the current logic—either wire this into the decision to fail the job or remove it to keep the script minimal and easier to maintain.
## Individual Comments
### Comment 1
<location> `.github/workflows/dependency-check.yml:105-114` </location>
<code_context>
+ SEVERITY_THRESHOLD="${{ github.event.inputs.fail_on_severity || 'high' }}"
</code_context>
<issue_to_address>
**issue (bug_risk):** The `fail_on_severity` input is effectively ignored for `low` and `medium` and only applied for `high`/`critical`.
Because `has_vulnerabilities` is only set when `SEVERITY_THRESHOLD` is `high` or `critical`, `low` and `medium` are effectively no-ops: the job will never fail for those values regardless of `TOTAL_VULNS`, which contradicts the idea of a minimum severity threshold.
Since pip-audit only exposes `TOTAL_VULNS`, consider treating any nonzero count as exceeding the configured threshold:
- If `fail_on_severity` is `low`, fail when `TOTAL_VULNS > 0`.
- Apply the same behavior for `medium`, `high`, and `critical`, or at least explicitly handle `low`/`medium` so they’re not silently ignored.
</issue_to_address>
### Comment 2
<location> `.github/workflows/dependency-check.yml:62-67` </location>
<code_context>
+ - name: Install pip-audit
+ run: uv pip install pip-audit
+
+ - name: Run pip-audit (JSON output)
+ id: audit_json
+ continue-on-error: true
+ run: |
+ # Export requirements from uv lock file
+ uv export --format requirements-txt --all-extras > requirements-audit.txt
+
+ # Run pip-audit with JSON output for artifact
+ uv run pip-audit \
+ --requirement requirements-audit.txt \
+ --format json \
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Running pip-audit with `|| true` and `continue-on-error: true` makes failures indistinguishable from a clean run.
Using both `continue-on-error: true` and `|| true` prevents you from telling “no vulnerabilities” apart from “pip-audit never ran” via exit codes.
Since the next step checks for `audit-results.json`, consider keeping only one mechanism. For example, drop `|| true` but keep `continue-on-error: true` so the workflow continues while still exposing a failed audit in the step outcome and via the missing results file.
```suggestion
uv run pip-audit \
--requirement requirements-audit.txt \
--format json \
--output audit-results.json \
--desc on
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Replace misleading fail_on_severity input with fail_on_vulnerabilities boolean (pip-audit doesn't provide severity data) - Remove unused CRITICAL_COUNT variable and simplify jq logic - Remove redundant || true from pip-audit commands (continue-on-error already handles failures while preserving exit code visibility) - Add explicit error when audit-results.json is missing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Thanks for the thorough review @sourcery-ai! I've addressed all comments in commit 3cdc593: Changes made:
|
Extract and save sourcery-ai generated diagrams: - cd-release-sequence.md: actor interactions during release - cd-release-flow.md: release workflow job flow - phase-snapshot-flow.md: phase-* branch snapshot flow - schema-validation-flow.md: migration/drift check flow - dependency-check-flow.md: pip-audit scan flow (updated) - README.md: index with workflow summary Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/phase-snapshot.yml:
- Around line 170-172: Replace the placeholder echo (echo "" >>
audit-output/audit-data.json) with real file-statistics collection: either
remove the placeholder line, or implement commands to compute and store stats
(e.g., count files by type, total file count, total size) and write them to a
proper output (e.g., audit-output/file-stats.txt or append a JSON object into
audit-output/audit-data.json); update the step in phase-snapshot.yml so the
command producing stats runs in the same workspace and ensures output file(s)
are created and committed to the audit-output directory.
🧹 Nitpick comments (3)
.github/workflows/schema-validation.yml (1)
69-76: Consider refining head count logic.The
grep -c "^[a-f0-9]"counts lines matching the pattern, butalembic headsoutput format may vary. If Alembic outputs heads on separate lines, this works correctly. However, usingwc -lafter filtering might be more explicit.♻️ Optional refinement
- HEAD_COUNT=$(echo "$HEADS" | grep -c "^[a-f0-9]" || true) + HEAD_COUNT=$(echo "$HEADS" | grep -E "^[a-f0-9]+" | wc -l).github/workflows/cd-release.yml (1)
63-66: Consider usinguv runfor consistency.Other steps use
uv runto execute Python commands, but herepython -m buildis called directly. While this should work afteruv python install, usinguv runensures the correct Python environment is used.♻️ Suggested refinement
- name: Build package run: | - python -m build + uv run python -m build ls -la dist/docs/github/diagrams/README.md (1)
17-38: Add language identifier to fenced code block.The markdownlint tool flagged the missing language specifier. Adding
textorplaintextimproves accessibility and silences the linter.Suggested fix
-``` +```text ┌─────────────────────────────────────────────────────────────────┐
|
|
||
| # File statistics | ||
| echo "" >> audit-output/audit-data.json |
There was a problem hiding this comment.
Incomplete "File statistics" section.
The comment suggests file statistics should be collected, but the implementation only appends an empty line. This appears to be an incomplete placeholder.
Suggested fix: Either remove the placeholder or implement file statistics
- # File statistics
- echo "" >> audit-output/audit-data.jsonOr implement actual file statistics collection if intended:
# File statistics (append to a separate file to keep JSON valid)
echo "Total files: $(find . -type f -name '*.py' | wc -l)" > audit-output/file-stats.txt📝 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.
| # File statistics | |
| echo "" >> audit-output/audit-data.json |
🤖 Prompt for AI Agents
In @.github/workflows/phase-snapshot.yml around lines 170 - 172, Replace the
placeholder echo (echo "" >> audit-output/audit-data.json) with real
file-statistics collection: either remove the placeholder line, or implement
commands to compute and store stats (e.g., count files by type, total file
count, total size) and write them to a proper output (e.g.,
audit-output/file-stats.txt or append a JSON object into
audit-output/audit-data.json); update the step in phase-snapshot.yml so the
command producing stats runs in the same workspace and ensures output file(s)
are created and committed to the audit-output directory.
Summary
schema-validation.ymlfor migration drift detection and downgrade/upgrade cycle testingdependency-check.ymlfor weekly pip-audit vulnerability scanning with SARIF outputphase-snapshot.ymlfor audit snapshots on phase-* branches with annotated tagscd-release.ymlfor automated semantic versioning releases via release-pleaseTest plan
🤖 Generated with Claude Code
Summary by Sourcery
Add CI workflows for schema validation, security scanning, phase snapshotting, and automated releases.
Build:
CI:
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.