Skip to content

Commit 7ffe77e

Browse files
committed
Added release workflow
1 parent 4e54dda commit 7ffe77e

1 file changed

Lines changed: 172 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
name: Release to PyPI and Docker
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
bump:
7+
description: 'Version bump type'
8+
required: true
9+
type: choice
10+
options:
11+
- patch
12+
- minor
13+
- major
14+
- custom
15+
default: 'patch'
16+
custom_version:
17+
description: 'Custom version (only if bump=custom, e.g., 0.2.0)'
18+
required: false
19+
type: string
20+
21+
env:
22+
REGISTRY: ghcr.io
23+
IMAGE_NAME: ${{ github.repository }}
24+
25+
jobs:
26+
publish-pypi:
27+
runs-on: ubuntu-latest
28+
permissions:
29+
contents: write
30+
outputs:
31+
version: ${{ steps.new.outputs.version }}
32+
33+
steps:
34+
- uses: actions/checkout@v4
35+
with:
36+
fetch-depth: 0
37+
38+
- name: Install uv
39+
uses: astral-sh/setup-uv@v5
40+
41+
- name: Set up Python
42+
run: uv python install 3.8
43+
44+
- name: Get current version
45+
id: current
46+
run: |
47+
CURRENT=$(grep '^__version__ = ' python/src/bioscript/__init__.py | cut -d'"' -f2)
48+
echo "version=${CURRENT}" >> $GITHUB_OUTPUT
49+
echo "Current version: ${CURRENT}"
50+
51+
- name: Calculate new version
52+
id: new
53+
run: |
54+
CURRENT="${{ steps.current.outputs.version }}"
55+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
56+
57+
case "${{ inputs.bump }}" in
58+
major)
59+
NEW_VERSION="$((MAJOR + 1)).0.0"
60+
;;
61+
minor)
62+
NEW_VERSION="${MAJOR}.$((MINOR + 1)).0"
63+
;;
64+
patch)
65+
NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
66+
;;
67+
custom)
68+
NEW_VERSION="${{ inputs.custom_version }}"
69+
;;
70+
esac
71+
72+
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
73+
echo "New version: ${NEW_VERSION}"
74+
75+
- name: Update version in __init__.py
76+
run: |
77+
cd python
78+
sed -i 's/__version__ = ".*"/__version__ = "${{ steps.new.outputs.version }}"/' src/bioscript/__init__.py
79+
grep '__version__' src/bioscript/__init__.py
80+
81+
- name: Install dependencies
82+
run: |
83+
cd python
84+
uv sync --all-extras
85+
86+
- name: Run tests
87+
run: |
88+
cd python
89+
uv run pytest
90+
91+
- name: Build package
92+
run: |
93+
cd python
94+
uv build
95+
96+
- name: Publish to PyPI
97+
uses: pypa/gh-action-pypi-publish@release/v1
98+
with:
99+
packages-dir: python/dist/
100+
password: ${{ secrets.PYPI_API_TOKEN }}
101+
102+
- name: Commit version bump and tag
103+
run: |
104+
git config user.name "github-actions[bot]"
105+
git config user.email "github-actions[bot]@users.noreply.github.com"
106+
git add python/src/bioscript/__init__.py
107+
git commit -m "Bump version to ${{ steps.new.outputs.version }}"
108+
git tag "v${{ steps.new.outputs.version }}"
109+
git push origin main --tags
110+
111+
build-docker:
112+
needs: publish-pypi
113+
runs-on: ubuntu-latest
114+
permissions:
115+
contents: read
116+
packages: write
117+
attestations: write
118+
id-token: write
119+
120+
steps:
121+
- name: Checkout repository
122+
uses: actions/checkout@v4
123+
with:
124+
ref: main # Get the latest main with version bump
125+
126+
- name: Set up Docker Buildx
127+
uses: docker/setup-buildx-action@v3
128+
129+
- name: Log in to GitHub Container Registry
130+
uses: docker/login-action@v3
131+
with:
132+
registry: ${{ env.REGISTRY }}
133+
username: ${{ github.actor }}
134+
password: ${{ secrets.GITHUB_TOKEN }}
135+
136+
- name: Extract version from __init__.py
137+
id: version
138+
run: |
139+
VERSION="${{ needs.publish-pypi.outputs.version }}"
140+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
141+
echo "Using version: ${VERSION}"
142+
143+
- name: Extract metadata for Docker
144+
id: meta
145+
uses: docker/metadata-action@v5
146+
with:
147+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
148+
tags: |
149+
type=semver,pattern={{version}},value=v${{ steps.version.outputs.version }}
150+
type=semver,pattern={{major}}.{{minor}},value=v${{ steps.version.outputs.version }}
151+
type=semver,pattern={{major}},value=v${{ steps.version.outputs.version }}
152+
type=raw,value=${{ steps.version.outputs.version }}
153+
type=raw,value=latest
154+
155+
- name: Build and push Docker image
156+
id: build
157+
uses: docker/build-push-action@v5
158+
with:
159+
context: .
160+
file: ./docker/Dockerfile
161+
push: true
162+
tags: ${{ steps.meta.outputs.tags }}
163+
labels: ${{ steps.meta.outputs.labels }}
164+
cache-from: type=gha
165+
cache-to: type=gha,mode=max
166+
167+
- name: Generate artifact attestation
168+
uses: actions/attest-build-provenance@v1
169+
with:
170+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
171+
subject-digest: ${{ steps.build.outputs.digest }}
172+
push-to-registry: true

0 commit comments

Comments
 (0)