Skip to content

Commit 8486a7f

Browse files
ci: add release workflow automation (#1)
- Add tag-and-release workflow for automatic tagging and PyPI publishing - Add create-release workflow for manual release creation with version bump PR
1 parent e78b9f5 commit 8486a7f

File tree

2 files changed

+171
-0
lines changed

2 files changed

+171
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Create Release
2+
3+
4+
on:
5+
workflow_dispatch:
6+
inputs:
7+
version:
8+
description: "Tag to be created, in the form X.Y.Z"
9+
required: true
10+
type: string
11+
12+
permissions:
13+
contents: write
14+
packages: read
15+
pull-requests: write
16+
17+
jobs:
18+
build-and-release:
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
# Check if the user is a member of the Giskard-AI organization
23+
- name: Check if organization member
24+
uses: JamesSingleton/is-organization-member@311430b0670cdec4036e721029b78018236a0b74 # 1.1.0
25+
id: is_organization_member
26+
with:
27+
organization: Giskard-AI
28+
username: ${{ github.actor }}
29+
token: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Interrupt job if user is not a member of Giskard-AI organization
32+
if: ${{ steps.is_organization_member.outputs.result == 'false' }}
33+
shell: bash
34+
run: |
35+
echo "Job failed due to user not being a member of Giskard-AI organization and the 'safe for build' label not being set on the PR"
36+
exit 1
37+
38+
- name: Validate version format
39+
env:
40+
VERSION_INPUT: ${{ inputs.version }}
41+
run: |
42+
if [[ ! "$VERSION_INPUT" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
43+
echo "Invalid version format. Use X.Y.Z"
44+
exit 1
45+
fi
46+
# Checkout the repository
47+
- name: Checkout repository
48+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
49+
with:
50+
fetch-tags: true
51+
ref: main
52+
token: ${{ secrets.GITHUB_TOKEN }}
53+
54+
# Write release version env vars
55+
- name: Write release version env vars
56+
env:
57+
VERSION_INPUT: ${{ inputs.version }}
58+
run: |
59+
VERSION_NAME="v${VERSION_INPUT}"
60+
VERSION_NUMBER="${VERSION_NAME:1}"
61+
echo "VERSION_NUMBER=${VERSION_NUMBER}" >> $GITHUB_ENV
62+
echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV
63+
64+
# Install uv
65+
- name: Install uv
66+
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7
67+
68+
# Install toml-cli
69+
- name: Install toml-cli
70+
run: uv tool install toml-cli
71+
72+
# Update project version
73+
- name: Update project version
74+
run: toml set --toml-path pyproject.toml project.version "${{ env.VERSION_NUMBER }}"
75+
76+
- name: Commit changes and create PR
77+
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7
78+
with:
79+
token: ${{ secrets.GITHUB_TOKEN }}
80+
branch: release/${{ env.VERSION_NAME }}
81+
commit-message: "Release ${{ env.VERSION_NAME }}: Bump version to ${{ env.VERSION_NUMBER }}"
82+
title: "Release ${{ env.VERSION_NAME }}"
83+
body: |
84+
This PR bumps the version to `${{ env.VERSION_NUMBER }}` for release.
85+
labels: release
86+
draft: false
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Tag and Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
packages: read
11+
id-token: write
12+
13+
jobs:
14+
tag-and-release:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
20+
with:
21+
fetch-tags: true
22+
token: ${{ secrets.GITHUB_TOKEN }}
23+
24+
- name: Read version from pyproject.toml
25+
id: get_version
26+
run: |
27+
VERSION_NUMBER=$(grep '^version\s*=' pyproject.toml | head -1 | cut -d '"' -f2)
28+
VERSION_NAME="v${VERSION_NUMBER}"
29+
printf 'version_number=%s\n' "$VERSION_NUMBER" >> "$GITHUB_OUTPUT"
30+
printf 'version_name=%s\n' "$VERSION_NAME" >> "$GITHUB_OUTPUT"
31+
32+
- name: Check if tag exists
33+
env:
34+
VERSION_NAME: ${{ steps.get_version.outputs.version_name }}
35+
run: |
36+
if git rev-parse "refs/tags/$VERSION_NAME" >/dev/null 2>&1; then
37+
echo "Tag $VERSION_NAME already exists. Skipping."
38+
exit 0
39+
fi
40+
41+
- name: Configure git
42+
run: |
43+
git config --global user.name 'BotReleaser'
44+
git config --global user.email 'bot.releaser@users.noreply.github.com'
45+
46+
- name: Create and push tag
47+
env:
48+
VERSION_NAME: ${{ steps.get_version.outputs.version_name }}
49+
run: |
50+
git tag "$VERSION_NAME"
51+
git push origin "$VERSION_NAME"
52+
53+
- name: Install uv
54+
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7
55+
56+
- name: Install dependencies
57+
run: uv sync --frozen --all-extras --dev
58+
59+
- name: Build package
60+
run: uv build
61+
62+
- name: Verify artifacts exist
63+
run: |
64+
ls -l dist
65+
shopt -s nullglob
66+
files=(dist/*.tar.gz dist/*.whl)
67+
if [ ${#files[@]} -eq 0 ]; then
68+
echo "No distribution files found in dist/"
69+
exit 1
70+
fi
71+
72+
- name: Publish to PyPI
73+
uses: pypa/gh-action-pypi-publish@release/v1
74+
75+
- name: Create GitHub Release
76+
env:
77+
VERSION_NAME: ${{ steps.get_version.outputs.version_name }}
78+
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2
79+
with:
80+
tag_name: ${{ env.VERSION_NAME }}
81+
fail_on_unmatched_files: true
82+
generate_release_notes: true
83+
files: |
84+
dist/*.tar.gz
85+
dist/*.whl

0 commit comments

Comments
 (0)