Skip to content

Commit 0b40e32

Browse files
Merge pull request #12 from OffendingCommit/fix/semantic-release-pipeline
feat: create unified release pipeline with semantic versioning
2 parents b618347 + 25b1edf commit 0b40e32

File tree

3 files changed

+229
-58
lines changed

3 files changed

+229
-58
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ name: CI
33
on:
44
push:
55
branches: [ main ]
6+
paths-ignore:
7+
- 'README.md'
8+
- 'CHANGELOG.md'
9+
- 'LICENSE'
10+
- 'docs/**'
611
pull_request:
712
branches: [ main ]
813

@@ -62,59 +67,4 @@ jobs:
6267
uses: codecov/codecov-action@v4
6368
with:
6469
token: ${{ secrets.CODECOV_TOKEN }}
65-
fail_ci_if_error: false
66-
67-
release:
68-
needs: test
69-
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
70-
runs-on: ubuntu-latest
71-
concurrency: release
72-
permissions:
73-
id-token: write
74-
contents: write
75-
issues: write
76-
pull-requests: write
77-
78-
steps:
79-
- uses: actions/checkout@v4
80-
with:
81-
fetch-depth: 0
82-
token: ${{ secrets.GITHUB_TOKEN }}
83-
84-
- name: Set up Python
85-
uses: actions/setup-python@v5
86-
with:
87-
python-version: "3.12"
88-
cache: 'pip'
89-
90-
- name: Install Poetry
91-
uses: snok/install-poetry@v1
92-
with:
93-
version: 1.8.3
94-
virtualenvs-create: true
95-
virtualenvs-in-project: true
96-
97-
- name: Install dependencies
98-
run: poetry install
99-
100-
- name: Python Semantic Release
101-
id: semantic-release
102-
run: |
103-
git config --global user.name "semantic-release"
104-
git config --global user.email "semantic-release@users.noreply.github.com"
105-
# Debug information
106-
echo "Current git status:"
107-
git status
108-
echo "Current branch:"
109-
git branch
110-
# Run semantic release with verbose output
111-
poetry run semantic-release --verbose version
112-
# Only publish if version command succeeded
113-
if [ $? -eq 0 ]; then
114-
poetry run semantic-release --verbose publish
115-
else
116-
echo "Version command failed, skipping publish"
117-
exit 1
118-
fi
119-
env:
120-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
70+
fail_ci_if_error: false
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
name: Release Pipeline
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.12"]
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
cache: 'pip'
24+
25+
- name: Install Poetry
26+
uses: snok/install-poetry@v1
27+
with:
28+
version: 1.8.3
29+
virtualenvs-create: true
30+
virtualenvs-in-project: true
31+
32+
- name: Cache Poetry dependencies
33+
uses: actions/cache@v4
34+
with:
35+
path: .venv
36+
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
37+
38+
- name: Install dependencies
39+
run: poetry install
40+
41+
- name: Lint with flake8
42+
run: |
43+
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=.venv,.git,__pycache__,build,dist
44+
poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics --exclude=.venv,.git,__pycache__,build,dist
45+
46+
- name: Format check with black
47+
run: poetry run black --check --exclude=\.venv --extend-exclude=main.py .
48+
49+
- name: Import sorting check with isort
50+
run: poetry run isort --check --skip .venv --skip main.py .
51+
52+
- name: Test with pytest
53+
run: |
54+
if [ -d "src" ]; then
55+
poetry run pytest --cov=src
56+
else
57+
echo "No src directory yet, skipping tests"
58+
exit 0
59+
fi
60+
61+
- name: Upload coverage to Codecov
62+
uses: codecov/codecov-action@v4
63+
with:
64+
token: ${{ secrets.CODECOV_TOKEN }}
65+
fail_ci_if_error: false
66+
67+
semantic-release:
68+
needs: test
69+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
70+
runs-on: ubuntu-latest
71+
outputs:
72+
new_release_published: ${{ steps.semantic-release.outputs.new_release_published }}
73+
new_release_version: ${{ steps.semantic-release.outputs.new_release_version }}
74+
permissions:
75+
id-token: write
76+
contents: write
77+
issues: write
78+
pull-requests: write
79+
80+
steps:
81+
- uses: actions/checkout@v4
82+
with:
83+
fetch-depth: 0
84+
token: ${{ secrets.GITHUB_TOKEN }}
85+
86+
- name: Set up Python
87+
uses: actions/setup-python@v5
88+
with:
89+
python-version: "3.12"
90+
cache: 'pip'
91+
92+
- name: Install Poetry
93+
uses: snok/install-poetry@v1
94+
with:
95+
version: 1.8.3
96+
virtualenvs-create: true
97+
virtualenvs-in-project: true
98+
99+
- name: Install dependencies
100+
run: poetry install
101+
102+
- name: Python Semantic Release
103+
id: semantic-release
104+
run: |
105+
git config --global user.name "semantic-release"
106+
git config --global user.email "semantic-release@users.noreply.github.com"
107+
# Debug information
108+
echo "Current git status:"
109+
git status
110+
echo "Current branch:"
111+
git branch
112+
113+
# Run semantic release with verbose output
114+
echo "Running semantic-release version"
115+
VERSION_OUTPUT=$(poetry run semantic-release --verbose version)
116+
echo "$VERSION_OUTPUT"
117+
118+
# Extract version information
119+
if echo "$VERSION_OUTPUT" | grep -q "Bumping version"; then
120+
NEW_VERSION=$(poetry run python -c "import toml; print(toml.load('pyproject.toml')['tool']['poetry']['version'])")
121+
echo "new_release_published=true" >> $GITHUB_OUTPUT
122+
echo "new_release_version=$NEW_VERSION" >> $GITHUB_OUTPUT
123+
echo "New version: $NEW_VERSION"
124+
125+
# Publish the release
126+
echo "Publishing release"
127+
poetry run semantic-release --verbose publish
128+
else
129+
echo "No version bump needed"
130+
echo "new_release_published=false" >> $GITHUB_OUTPUT
131+
fi
132+
env:
133+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
134+
135+
docker-build:
136+
needs: semantic-release
137+
if: needs.semantic-release.outputs.new_release_published == 'true'
138+
runs-on: ubuntu-latest
139+
permissions:
140+
contents: read
141+
packages: write
142+
143+
steps:
144+
- name: Checkout repository
145+
uses: actions/checkout@v4
146+
with:
147+
ref: main # Make sure we get the latest changes after semantic-release
148+
149+
- name: Set up Docker Buildx
150+
uses: docker/setup-buildx-action@v3
151+
152+
- name: Log in to GitHub Container Registry
153+
uses: docker/login-action@v3
154+
with:
155+
registry: ghcr.io
156+
username: ${{ github.actor }}
157+
password: ${{ secrets.GITHUB_TOKEN }}
158+
159+
- name: Build and push Docker image
160+
uses: docker/build-push-action@v5
161+
with:
162+
context: .
163+
file: ./Dockerfile
164+
push: true
165+
tags: |
166+
ghcr.io/offendingcommit/bingo:latest
167+
ghcr.io/offendingcommit/bingo:${{ needs.semantic-release.outputs.new_release_version }}
168+
build-args: BUILD_ENVIRONMENT=production
169+
170+
helm-chart:
171+
needs: [semantic-release, docker-build]
172+
if: needs.semantic-release.outputs.new_release_published == 'true'
173+
runs-on: ubuntu-latest
174+
permissions:
175+
contents: write
176+
177+
steps:
178+
- name: Checkout repository
179+
uses: actions/checkout@v4
180+
with:
181+
ref: main # Make sure we get the latest changes after semantic-release
182+
183+
- name: Set up Helm
184+
uses: azure/setup-helm@v1
185+
186+
- name: Update Helm Chart version and app version
187+
run: |
188+
VERSION="${{ needs.semantic-release.outputs.new_release_version }}"
189+
# Update version and appVersion in Chart.yaml
190+
sed -i "s/^version:.*/version: $VERSION/" helm/bingo/Chart.yaml
191+
sed -i "s/^appVersion:.*/appVersion: $VERSION/" helm/bingo/Chart.yaml
192+
# Update image tag in values.yaml
193+
sed -i "s/tag:.*/tag: $VERSION/" helm/bingo/values.yaml
194+
195+
# Show the changes
196+
echo "Updated Chart.yaml:"
197+
cat helm/bingo/Chart.yaml
198+
echo "Updated values.yaml:"
199+
cat helm/bingo/values.yaml
200+
201+
- name: Lint Helm Chart
202+
run: helm lint helm/bingo
203+
204+
- name: Package Helm Chart
205+
run: |
206+
mkdir -p dist
207+
helm package helm/bingo --destination dist
208+
209+
- name: Upload Helm Chart to Release
210+
uses: softprops/action-gh-release@v1
211+
with:
212+
tag_name: v${{ needs.semantic-release.outputs.new_release_version }}
213+
files: dist/*.tgz
214+
env:
215+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

pyproject.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,28 @@ addopts = "--cov=src"
3737
version_toml = ["pyproject.toml:tool.poetry.version"]
3838
branch = "main"
3939
changelog_file = "CHANGELOG.md"
40-
build_command = "poetry build"
41-
dist_path = "dist/"
40+
build_command = "echo 'Not building package - Docker and Helm charts will be built separately'"
4241
upload_to_pypi = false
4342
upload_to_release = true
4443
commit_message = "chore(release): {version} [skip ci]"
4544
commit_author = "semantic-release <semantic-release@users.noreply.github.com>"
4645
major_on_zero = false
4746
tag_format = "v{version}"
4847

48+
[tool.semantic_release.remote]
49+
type = "github"
50+
repository = "OffendingCommit/commit-bingo"
51+
4952
[tool.semantic_release.remote.token]
5053
env = "GH_TOKEN"
5154

5255
[tool.semantic_release.branches.main]
5356
match = "main"
5457
prerelease = false
5558

59+
[tool.semantic_release.publish]
60+
dist_glob_patterns = [] # No files to upload directly from semantic-release
61+
5662
[tool.black]
5763
line-length = 88
5864
target-version = ["py312"]

0 commit comments

Comments
 (0)