Skip to content

Commit ac3d356

Browse files
authored
Merge pull request #565 from nanotaboada/ci/normalize-cd-pipeline
ci(cd): normalize and align CD pipeline (#564)
2 parents 52902c8 + 53ed786 commit ac3d356

File tree

2 files changed

+51
-26
lines changed

2 files changed

+51
-26
lines changed

.github/workflows/python-cd.yml

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,42 @@ env:
1313
PACKAGE_NAME: nanotaboada/python-samples-fastapi-restful
1414

1515
jobs:
16+
test:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v6
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v6.2.0
26+
with:
27+
python-version-file: ${{ env.PYTHON_VERSION_FILE }}
28+
29+
- name: Set up uv
30+
uses: astral-sh/setup-uv@v8.0.0
31+
with:
32+
version: "latest"
33+
enable-cache: true
34+
35+
- name: Install test dependencies
36+
run: |
37+
uv venv
38+
uv pip install --group dev
39+
40+
- name: Run tests with pytest
41+
run: |
42+
uv run pytest -v
43+
1644
release:
45+
needs: test
1746
runs-on: ubuntu-latest
1847
permissions:
1948
contents: write
2049
packages: write
50+
id-token: write
51+
attestations: write
2152
steps:
2253
- name: Checkout repository
2354
uses: actions/checkout@v6
@@ -74,25 +105,6 @@ jobs:
74105
echo "📦 Release version: $SEMVER"
75106
echo "♟️ Coach name: $COACH"
76107
77-
- name: Set up Python
78-
uses: actions/setup-python@v6.2.0
79-
with:
80-
python-version-file: ${{ env.PYTHON_VERSION_FILE }}
81-
82-
- name: Set up uv
83-
uses: astral-sh/setup-uv@v8.0.0
84-
with:
85-
version: "latest"
86-
87-
- name: Install test dependencies
88-
run: |
89-
uv venv
90-
uv pip install --group dev
91-
92-
- name: Run tests with pytest
93-
run: |
94-
uv run pytest --cov=./ --cov-report=xml --cov-report=term -v
95-
96108
- name: Log in to GitHub Container Registry
97109
uses: docker/login-action@v4.1.0
98110
with:
@@ -104,19 +116,27 @@ jobs:
104116
uses: docker/setup-buildx-action@v4.0.0
105117

106118
- name: Build and push Docker image to GitHub Container Registry
119+
id: push
107120
uses: docker/build-push-action@v7.0.0
108121
with:
109122
context: .
110123
push: true
111124
platforms: linux/amd64,linux/arm64
112-
provenance: false
125+
provenance: mode=max
113126
cache-from: type=gha
114127
cache-to: type=gha,mode=max
115128
tags: |
116129
ghcr.io/${{ env.PACKAGE_NAME }}:${{ steps.version.outputs.semver }}
117130
ghcr.io/${{ env.PACKAGE_NAME }}:${{ steps.version.outputs.coach }}
118131
ghcr.io/${{ env.PACKAGE_NAME }}:latest
119132
133+
- name: Attest build provenance
134+
uses: actions/attest-build-provenance@v4.1.0
135+
with:
136+
subject-name: ghcr.io/${{ env.PACKAGE_NAME }}
137+
subject-digest: ${{ steps.push.outputs.digest }}
138+
push-to-registry: true
139+
120140
- name: Generate changelog
121141
id: changelog
122142
run: |
@@ -125,21 +145,17 @@ jobs:
125145
126146
if [ -z "$PREVIOUS_TAG" ]; then
127147
echo "📝 First release - no previous tag found"
128-
CHANGELOG="Initial release"
148+
CHANGELOG="No changes (first release)"
129149
else
130150
echo "📝 Generating changelog from $PREVIOUS_TAG to ${{ steps.version.outputs.tag_name }}"
131-
CHANGELOG=$(git log --pretty=format:"- %s (%h)" ${PREVIOUS_TAG}..${{ steps.version.outputs.tag_name }})
151+
CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges ${PREVIOUS_TAG}..${{ steps.version.outputs.tag_name }})
132152
133153
# Guard against empty changelog (e.g., re-tagging same commit)
134154
if [ -z "$CHANGELOG" ]; then
135155
CHANGELOG="No new changes since $PREVIOUS_TAG"
136156
fi
137157
fi
138158
139-
# Write changelog to file
140-
echo "$CHANGELOG" > changelog.txt
141-
cat changelog.txt
142-
143159
# Set output for use in release body
144160
{
145161
echo "changelog<<EOF"

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ This project uses famous football coaches as release codenames, following an A-Z
4444

4545
### Added
4646

47+
- Extract `test` job from `release` in CD pipeline so tests run in isolation
48+
before any publish step; run `pytest -v` only (no coverage — CI owns that);
49+
add `enable-cache: true` to `astral-sh/setup-uv` for faster dependency
50+
installs; add `id-token: write` and `attestations: write` permissions to
51+
`release`; set `provenance: mode=max` and attest the image digest with
52+
`actions/attest-build-provenance@v4.1.0` (`push-to-registry: true`); add
53+
`--no-merges` to the changelog `git log` command; normalize first-release
54+
message to `"No changes (first release)"` (#564)
55+
4756
- `alembic/`: Alembic migration support for async SQLAlchemy — `env.py`
4857
configured for async execution with `render_as_batch=True` (SQLite/PostgreSQL
4958
compatible); three migrations: `001` creates the `players` table, `002` seeds

0 commit comments

Comments
 (0)