-
Notifications
You must be signed in to change notification settings - Fork 0
149 lines (141 loc) · 7.39 KB
/
python-ci.yml
File metadata and controls
149 lines (141 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Python CI (uv)
#
# Reusable workflow that wires together the full Python / uv CI pipeline:
#
# security — gitleaks + pip-audit + guarddog (gates everything below)
# lint — ruff check + ruff format + hadolint ┐
# test — uv sync + pytest ├─ parallel after security
# docker-build — Dockerfile validation (opt-in) ┘
# vulnerability-scan — Syft + Grype (after all above pass or are skipped)
#
# The consuming repo controls WHEN this runs. This workflow controls HOW.
#
# Usage in a consuming repository:
#
# on: [push, pull_request, workflow_dispatch]
#
# jobs:
# ci:
# uses: orangitfi/platform-tooling/.github/workflows/python-ci.yml@<sha>
# with:
# image-name: my-api
#
# See python-ci.md for full documentation and all parameter options.
#
# ─── SHA pinning ─────────────────────────────────────────────────────────────
# The `uses:` lines below reference platform-tooling workflows at a specific
# SHA. After committing this file, run the SHA bump process documented in the
# root README to replace a4ca46b0de8eda2f61573cfbd4164e538a7775a1 with the new commit SHA.
# ─────────────────────────────────────────────────────────────────────────────
name: CI
on:
workflow_call:
inputs:
working-directory:
description: "Directory containing pyproject.toml and uv.lock"
required: false
default: "."
type: string
test-command:
description: "Command to run tests via uv run (e.g. pytest, pytest tests/ -v)"
required: false
default: "pytest"
type: string
uv-sync-args:
description: "Extra arguments passed to uv sync (e.g. --extra test)"
required: false
default: ""
type: string
run-ruff-lint:
description: "Run ruff check (linting)"
required: false
default: true
type: boolean
run-ruff-format:
description: "Run ruff format --check (formatting)"
required: false
default: true
type: boolean
dockerfile-path:
description: "Path to the Dockerfile relative to the repo root (used by lint, docker-build, and vulnerability scan)"
required: false
default: "Dockerfile"
type: string
run-docker-build:
description: "Validate that the Dockerfile builds successfully as an early quality gate (opt-in)"
required: false
default: false
type: boolean
image-name:
description: "Docker image name — required when run-docker-build is true; also used by vulnerability scan"
required: false
default: ""
type: string
fail-on-severity:
description: "Minimum Grype severity for the vulnerability scan: critical, high, medium, low, negligible"
required: false
default: "high"
type: string
run-docker-scan:
description: "Build and scan the Docker image in the vulnerability scan (set false for repos without a Dockerfile)"
required: false
default: true
type: boolean
permissions:
contents: read
jobs:
# ───────────────────────────────────────────────────────────────────────────
# 1. Security audit — runs first, gates everything else
# ───────────────────────────────────────────────────────────────────────────
security:
name: Security Scan
uses: orangitfi/platform-tooling/.github/workflows/python-security-scan.yml@a4ca46b0de8eda2f61573cfbd4164e538a7775a1 # pt-sha
with:
working-directory: ${{ inputs.working-directory }}
# ───────────────────────────────────────────────────────────────────────────
# 2. Lint + Test + optional Docker build — parallel after security passes
# ───────────────────────────────────────────────────────────────────────────
lint:
name: Lint
needs: security
uses: orangitfi/platform-tooling/.github/workflows/python-lint.yml@a4ca46b0de8eda2f61573cfbd4164e538a7775a1 # pt-sha
with:
working-directory: ${{ inputs.working-directory }}
run-ruff-lint: ${{ inputs.run-ruff-lint }}
run-ruff-format: ${{ inputs.run-ruff-format }}
dockerfile-path: ${{ inputs.dockerfile-path }}
test:
name: Test
needs: security
uses: orangitfi/platform-tooling/.github/workflows/python-test.yml@a4ca46b0de8eda2f61573cfbd4164e538a7775a1 # pt-sha
with:
working-directory: ${{ inputs.working-directory }}
test-command: ${{ inputs.test-command }}
uv-sync-args: ${{ inputs.uv-sync-args }}
# ───────────────────────────────────────────────────────────────────────────
# 3. Optional Docker build — validates the Dockerfile compiles cleanly
# Skipped when disabled; vulnerability-scan still runs after the skip
# ───────────────────────────────────────────────────────────────────────────
docker-build:
name: Docker Build
if: ${{ inputs.run-docker-build }}
needs: security
uses: orangitfi/platform-tooling/.github/workflows/python-build-and-publish-docker.yml@a4ca46b0de8eda2f61573cfbd4164e538a7775a1 # pt-sha
with:
working-directory: ${{ inputs.working-directory }}
dockerfile-path: ${{ inputs.dockerfile-path }}
image-name: ${{ inputs.image-name }}
publish: false
# ───────────────────────────────────────────────────────────────────────────
# 4. Vulnerability scan — runs after all quality gates pass or are skipped
# ───────────────────────────────────────────────────────────────────────────
vulnerability-scan:
name: Vulnerability Scan
needs: [lint, test, docker-build]
uses: orangitfi/platform-tooling/.github/workflows/python-vulnerability-scan.yml@a4ca46b0de8eda2f61573cfbd4164e538a7775a1 # pt-sha
with:
working-directory: ${{ inputs.working-directory }}
fail-on-severity: ${{ inputs.fail-on-severity }}
run-docker-scan: ${{ inputs.run-docker-scan }}
dockerfile-path: ${{ inputs.dockerfile-path }}
image-name: ${{ inputs.image-name }}