-
Notifications
You must be signed in to change notification settings - Fork 10
189 lines (174 loc) · 6.94 KB
/
Copy pathci.yml
File metadata and controls
189 lines (174 loc) · 6.94 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
name: ci
on: [push]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
compile:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Bootstrap poetry
run: |
curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1
- name: Install dependencies
run: poetry install
- name: Compile
run: poetry run mypy .
- name: Verify (static gates — wire coverage + helper coverage)
# Live layers (read sweep + field-drop) auto-skip without SMALLEST_API_KEY.
# Fails the build if a new endpoint has no wire test, or a helper has no test.
run: poetry run python scripts/verify.py
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Bootstrap poetry
run: |
curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1
- name: Install dependencies
run: poetry install
- name: Test
run: poetry run pytest -rP -n auto .
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install ruff
run: pip install ruff==0.16.1
- name: Ruff lint
run: ruff check .
- name: Ruff format check
run: ruff format --check .
security:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Secret scan (gitleaks)
run: |
curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz gitleaks
./gitleaks dir . --config .gitleaks.toml --redact --no-banner
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Bootstrap poetry
run: |
curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1
- name: Install dependencies
run: poetry install
- name: Dependency audit (pip-audit)
# Report-only for now: the pinned transitive deps (pytest, requests, urllib3,
# starlette, setuptools, python-dotenv) carry a pre-existing advisory backlog to
# clear in a dependency-bump PR. Flip to blocking (remove continue-on-error) after.
continue-on-error: true
run: |
poetry run pip install pip-audit
poetry run pip-audit
# Auto-publish to PyPI when the version in pyproject.toml has been bumped
# beyond the latest git tag. Only fires on pushes to main, only after
# compile+test pass. No-ops on pushes that didn't change the version.
#
# Workflow for a release:
# 1. Open a PR that bumps `[tool.poetry] version` in pyproject.toml AND
# adds a matching `## <version> - YYYY-MM-DD` entry to changelog.md.
# 2. Merge to main.
# 3. This job auto-publishes to PyPI and creates the v<version> tag.
#
# Required repo secret: PYPI_API_TOKEN (a PyPI API token with upload scope
# for the `smallestai` project).
publish:
needs: [compile, test, lint, security]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: write # to push the tag
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Read version from pyproject.toml
id: pyproject
run: |
# Only the [tool.poetry] version line uses the `version = "..."` form
# in this repo. The [project] section just declares `dynamic = ["version"]`
# and doesn't match the quoted-value pattern, so grep -m 1 is safe.
VERSION=$(grep -m 1 '^version[[:space:]]*=[[:space:]]*"' pyproject.toml \
| sed -E 's/^version[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/')
if [ -z "${VERSION}" ]; then
echo "::error::Could not read [tool.poetry] version from pyproject.toml"
exit 1
fi
echo "Detected pyproject version: ${VERSION}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Check if version is new (tag does not yet exist)
id: should_publish
run: |
VERSION="${{ steps.pyproject.outputs.version }}"
if git rev-parse "v${VERSION}" >/dev/null 2>&1; then
echo "Tag v${VERSION} already exists — nothing to publish on this push."
echo "release=false" >> "$GITHUB_OUTPUT"
else
echo "Tag v${VERSION} does not exist — will release."
echo "release=true" >> "$GITHUB_OUTPUT"
fi
- name: Validate changelog entry exists
if: steps.should_publish.outputs.release == 'true'
run: |
VERSION="${{ steps.pyproject.outputs.version }}"
if ! grep -Fq "## ${VERSION} -" changelog.md; then
echo "::error::changelog.md has no entry for ${VERSION}. Add a '## ${VERSION} - YYYY-MM-DD' section to changelog.md and push again."
exit 1
fi
- name: Set up python
if: steps.should_publish.outputs.release == 'true'
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Bootstrap poetry
if: steps.should_publish.outputs.release == 'true'
run: |
curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1
- name: Build wheel + sdist
if: steps.should_publish.outputs.release == 'true'
run: poetry build
- name: Publish to PyPI
if: steps.should_publish.outputs.release == 'true'
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
run: |
if [ -z "${POETRY_PYPI_TOKEN_PYPI}" ]; then
echo "::error::PYPI_API_TOKEN secret is not set on this repo. Add it under Settings → Secrets and variables → Actions before this job can publish."
exit 1
fi
poetry publish --no-interaction
- name: Tag and push
if: steps.should_publish.outputs.release == 'true'
run: |
VERSION="${{ steps.pyproject.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "v${VERSION}" -m "Release v${VERSION}"
git push origin "v${VERSION}"
- name: Summary
if: steps.should_publish.outputs.release == 'true'
run: |
VERSION="${{ steps.pyproject.outputs.version }}"
echo "::notice::Published smallestai ${VERSION} to PyPI and tagged v${VERSION}."