1
- name : Release
2
-
1
+ name : Tag and Release
3
2
on :
4
3
push :
5
- tags :
6
- - ' v*.*.*'
7
- create :
8
- tags :
9
- - ' v*.*.*'
4
+ branches :
5
+ - main
10
6
workflow_dispatch :
11
7
inputs :
12
8
tag :
13
9
description : ' Tag to create release from (e.g. v1.2.3)'
14
- required : true
10
+ required : false
15
11
type : string
16
12
17
13
jobs :
18
- debug :
19
- runs-on : ubuntu-latest
20
- steps :
21
- - name : Debug trigger
22
- run : |
23
- echo "Event name: ${{ github.event_name }}"
24
- echo "Ref: ${{ github.ref }}"
25
- echo "Tag: ${{ github.ref_name }}"
26
- echo "Manual tag: ${{ inputs.tag }}"
27
-
28
- release :
14
+ tag-and-release :
29
15
runs-on : ubuntu-latest
30
- needs : debug
31
16
permissions :
32
- contents : write
17
+ contents : write
33
18
steps :
34
19
- uses : actions/checkout@v3
35
20
with :
36
- fetch-depth : 0 # Need full history for changelog
37
-
38
- - name : Set up Python
39
- uses : actions/setup-python@v3
40
- with :
41
- python-version : ' 3.8'
42
-
43
- - name : Get version changelog
44
- id : changelog
21
+ fetch-depth : 0
22
+
23
+ # Get version from pyproject.toml on push
24
+ - name : Get version from pyproject.toml
25
+ if : github.event_name == 'push'
26
+ id : auto_version
27
+ run : |
28
+ VERSION=$(grep '^version = ' pyproject.toml | cut -d'"' -f2)
29
+ echo "VERSION=$VERSION"
30
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
31
+
32
+ # Get version from manual input
33
+ - name : Get version from input
34
+ if : github.event_name == 'workflow_dispatch' && inputs.tag != ''
35
+ id : manual_version
45
36
run : |
46
- # Use manual tag input if workflow_dispatch, otherwise use git tag
47
- if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
48
- VERSION="${{ github.event.inputs.tag }}"
49
- VERSION=${VERSION#v} # Remove v prefix if present
37
+ VERSION=${{ inputs.tag }}
38
+ VERSION=${VERSION#v}
39
+ echo "VERSION=$VERSION"
40
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
41
+
42
+ # Combine versions and verify
43
+ - name : Set final version
44
+ id : version
45
+ run : |
46
+ VERSION="${{ steps.auto_version.outputs.version || steps.manual_version.outputs.version }}"
47
+ if [ -z "$VERSION" ]; then
48
+ echo "Error: No version found"
49
+ exit 1
50
+ fi
51
+ echo "VERSION=$VERSION"
52
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
53
+
54
+ # Check if tag exists
55
+ - name : Check for existing tag
56
+ id : check_tag
57
+ run : |
58
+ if git tag -l "v${{ steps.version.outputs.version }}" | grep -q .; then
59
+ echo "exists=true" >> $GITHUB_OUTPUT
60
+ echo "Tag v${{ steps.version.outputs.version }} already exists. Skipping release."
61
+ exit 0
50
62
else
51
- VERSION=${GITHUB_REF#refs/tags/v}
63
+ echo "exists=false" >> $GITHUB_OUTPUT
52
64
fi
53
- # Extract the section for this version from CHANGELOG.md
54
- sed -n "/## \\\[$VERSION\\\]/,/## \\\[/p" @CHANGELOG.md | sed '$d' > release_notes.md
55
- # Debug output
56
- echo "Tag version: $VERSION"
57
- echo "CHANGELOG.md contents:"
58
- cat CHANGELOG.md
59
- echo "Generated release notes:"
60
- cat release_notes.md
61
-
62
- - name : Install dependencies
65
+
66
+ # Create new tag if it doesn't exist
67
+ - name : Create tag
68
+ if : steps.check_tag.outputs.exists != 'true'
69
+ run : |
70
+ git config --global user.name 'github-actions[bot]'
71
+ git config --global user.email 'github-actions[bot]@users.noreply.github.com'
72
+ git tag -a "v${{ steps.version.outputs.version }}" -m "Release v${{ steps.version.outputs.version }}"
73
+ git push origin "v${{ steps.version.outputs.version }}"
74
+
75
+ # Setup Python for build
76
+ - name : Set up Python
77
+ if : steps.check_tag.outputs.exists != 'true'
78
+ uses : actions/setup-python@v4
79
+ with :
80
+ python-version : ' 3.8'
81
+
82
+ # Install build tools
83
+ - name : Install build tools
84
+ if : steps.check_tag.outputs.exists != 'true'
63
85
run : |
64
86
python -m pip install --upgrade pip
65
- pip install build twine hatchling
66
-
87
+ pip install build twine
88
+
89
+ # Build package
67
90
- name : Build package
91
+ if : steps.check_tag.outputs.exists != 'true'
68
92
run : python -m build
69
-
93
+
94
+ # Get release notes
95
+ - name : Get release notes
96
+ if : steps.check_tag.outputs.exists != 'true'
97
+ run : |
98
+ VERSION=${{ steps.version.outputs.version }}
99
+ echo "# Release v$VERSION" > release_notes.md
100
+ if [ -f CHANGELOG.md ]; then
101
+ echo "" >> release_notes.md
102
+ sed -n "/## \[${VERSION}\]/,/## \[/p" CHANGELOG.md | sed '$d' >> release_notes.md || true
103
+ fi
104
+
105
+ # Create GitHub Release
70
106
- name : Create GitHub Release
107
+ if : steps.check_tag.outputs.exists != 'true'
71
108
uses : softprops/action-gh-release@v1
72
109
with :
73
- tag_name : ${{ github.event.inputs.tag }}
110
+ tag_name : v ${{ steps.version.outputs.version }}
74
111
body_path : release_notes.md
75
112
files : dist/*
76
-
113
+
114
+ # Publish to PyPI
77
115
- name : Publish to PyPI
116
+ if : steps.check_tag.outputs.exists != 'true'
78
117
env :
79
118
TWINE_USERNAME : __token__
80
119
TWINE_PASSWORD : ${{ secrets.PYPI_TOKEN }}
81
- run : twine upload dist/*
120
+ run : twine upload dist/*
0 commit comments