-
Notifications
You must be signed in to change notification settings - Fork 2
197 lines (164 loc) · 6.71 KB
/
ci.yml
File metadata and controls
197 lines (164 loc) · 6.71 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
# SECURITY: Restrict workflow permissions (GitHub Advanced Security recommendation)
permissions:
contents: read
actions: read
env:
# Improve pip performance
PIP_NO_CACHE_DIR: false
# SECURITY: Removed PIP_USER=1 (potential privilege escalation risk)
# uv settings
UV_SYSTEM_PYTHON: 1
UV_CACHE_DIR: /tmp/.uv-cache
jobs:
quality:
name: Code Quality & Security
runs-on: ubuntu-latest
# SECURITY: Job-level permissions for security scanning
permissions:
contents: read
actions: read
security-events: read # For security scanning tools
steps:
- name: Checkout code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.1
- name: Install uv
uses: astral-sh/setup-uv@cdfb2ee6dde255817c739680168ad81e184c4bfb # v4.0.0
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Python 3.13
run: uv python install 3.13
- name: Install dependencies
run: uv sync --locked --all-extras --dev
- name: Run ruff linting (includes security checks)
run: uv run python -c "import taskipy.cli; taskipy.cli.main()" ruff-check
- name: Check ruff formatting
run: uv run python -c "import taskipy.cli; taskipy.cli.main()" ruff-format --check
- name: Run type checking
run: uv run python -c "import taskipy.cli; taskipy.cli.main()" static-check
- name: Check for secrets
shell: bash
run: |
# SECURITY: Fail on errors, undefined variables, pipe failures
set -euo pipefail
if [[ ! -f .secrets.baseline ]]; then
echo "Creating secrets baseline..."
uv run detect-secrets scan --baseline .secrets.baseline
fi
# Check for new secrets since baseline
uv run detect-secrets scan --baseline .secrets.baseline
echo "✅ Secret scanning complete - no new secrets detected"
test:
name: Tests
runs-on: ubuntu-latest
# SECURITY: Minimal permissions for test execution
permissions:
contents: read
actions: read
strategy:
fail-fast: false
matrix:
python-version: ["3.13"]
steps:
- name: Checkout code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.1
- name: Install uv
uses: astral-sh/setup-uv@cdfb2ee6dde255817c739680168ad81e184c4bfb # v4.0.0
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --locked --all-extras --dev
- name: Run fast tests
run: uv run python -c "import taskipy.cli; taskipy.cli.main()" test-fast
- name: Run full test suite (main branch and PRs only)
if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request'
run: uv run python -c "import taskipy.cli; taskipy.cli.main()" test
- name: Upload coverage reports
if: matrix.python-version == '3.13' && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request')
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: coverage-reports
path: |
docs/coverage/
docs/tests/
retention-days: 30
- name: Upload coverage to Codecov (optional)
if: matrix.python-version == '3.13' && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request')
uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.2
with:
files: ./coverage.xml
fail_ci_if_error: false
verbose: true
build:
name: Build & Documentation
runs-on: ubuntu-latest
needs: [quality, test]
# SECURITY: Minimal permissions for build and artifact upload
permissions:
contents: read
actions: read
steps:
- name: Checkout code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.1
- name: Install uv
uses: astral-sh/setup-uv@cdfb2ee6dde255817c739680168ad81e184c4bfb # v4.0.0
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Python 3.13
run: uv python install 3.13
- name: Install dependencies
run: uv sync --locked --all-extras --dev
- name: Build documentation
run: uv run python -c "import taskipy.cli; taskipy.cli.main()" doc-build
- name: Build package
run: uv build
- name: Verify package installation (wheel)
run: |
uv run --isolated --no-project --with dist/*.whl python -c "import app; print('✓ Wheel install successful')"
- name: Verify package installation (sdist)
run: |
uv run --isolated --no-project --with dist/*.tar.gz python -c "import app; print('✓ Source dist install successful')"
- name: Upload build artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: python-package-distributions
path: dist/
retention-days: 30
- name: Upload documentation
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: documentation
path: docs/api/
retention-days: 30
# Security summary job
security-summary:
name: Security Summary
runs-on: ubuntu-latest
needs: [quality]
if: always()
# SECURITY: Minimal permissions for summary generation
permissions:
contents: read
actions: read
steps:
- name: Security Summary
run: |
echo "## 🔒 Security Scan Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ✅ Ruff Security Analysis" >> $GITHUB_STEP_SUMMARY
echo "Security rules (S001-S701) checked during linting phase." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Additional Security Features" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Secret scanning (detect-secrets)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Dependency vulnerability scanning (safety + dependabot)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ CodeQL security analysis (weekly + on pushes)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Comprehensive security rules via Ruff (flake8-bandit S001-S701)" >> $GITHUB_STEP_SUMMARY