-
Notifications
You must be signed in to change notification settings - Fork 0
140 lines (119 loc) · 5.75 KB
/
draft-release.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
name: draft-release
on:
workflow_dispatch:
inputs:
version_tag:
description: Semantic version tag for next release. If not provided, it will be determined based on conventional commmit history.
required: false
type: string
default: ''
push:
branches:
- release-draft
jobs:
draft-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required to include tags
- uses: actions/setup-python@v4
with:
python-version: '3.11'
cache: 'pip'
- run: pip install cffconvert>=2.0.0
- name: Get Date
run: |
echo "DATE=$(date +"%Y-%m-%d")" >> "$GITHUB_ENV"
- name: Get current and next versions
id: semver
uses: ietf-tools/semver-action@v1
with:
token: ${{ github.token }}
branch: ${{ github.ref_name }}
- name: Set version variables
shell: python {0}
run: |
import os
import re
import warnings
convco_version = "${{ steps.semver.outputs.next }}"
if "${{ github.event_name }}" == 'workflow_dispatch' and "${{ github.event.inputs.version_tag }}":
next_version = "${{ github.event.inputs.version_tag }}"
if next_version != convco_version:
warnings.warn("Manual version ({next_version}) not equal to version determined by conventional commit history ({convco_version})")
else:
next_version = convco_version
with open(os.getenv("GITHUB_ENV"), 'a') as out_env:
out_env.write(f"NEXT_VERSION={next_version}")
current_version = "${{ steps.semver.outputs.current }}"
# assert semantic version pattern
semver_pattern = 'v(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?'
next_semver = re.match(semver_pattern, next_version)
if not next_semver:
raise ValueError(f"Tag {next_version} does not match semantic versioning guidelines")
# assert next version is only 1 greater than current
current_semver = re.match(semver_pattern, current_version)
groups = ['major', 'minor', 'patch']
greater = sum([next_semver.group(grp) > current_semver.group(grp) for grp in groups])
equal = sum([next_semver.group(grp) == current_semver.group(grp) for grp in groups])
if not (greater == 1 and equal == 2):
raise ValueError(f"Next version must only increment one number at a time. Current version: {current_version}. Proposed next version: {next_version}")
- name: Get release notes & update changelog
shell: python {0}
run: |
import os
latest_version = "${{ steps.semver.outputs.current }}".strip('v')
next_version = "${{ env.NEXT_VERSION }}".strip('v')
changelog_lines = list()
next_release_lines = list()
for_next = True
with open("CHANGELOG.md", "r") as infile:
for line in infile:
if line.startswith('#') and 'development version' in line:
line = line.replace('development version', next_version)
elif latest_version in line:
for_next = False
changelog_lines.append(line)
if for_next:
next_release_lines.append(line)
with open(".github/latest-release.md", "w") as outfile:
outfile.write(''.join(next_release_lines))
with open('CHANGELOG.md', 'w') as outfile:
outfile.write(''.join(changelog_lines))
- name: Update citation & version files
shell: python {0}
run: |
from cffconvert.cli.create_citation import create_citation
from cffconvert.cli.validate_or_write_output import validate_or_write_output
citation = create_citation('CITATION.cff', None)
citation._implementation.cffobj['version'] = "${{ env.NEXT_VERSION }}"
citation._implementation.cffobj['date-released'] = "${{ env.DATE }}"
validate_or_write_output("CITATION.cff", 'cff', False, citation)
with open("VERSION", "w") as outfile:
version_strict = '${{ env.NEXT_VERSION }}'.strip('v')
outfile.write(f"{version_strict}\n")
- name: Commit & push to branch
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git push origin --delete release-draft || echo "No release-draft branch to delete"
git switch -c release-draft || git switch release-draft
git merge --ff-only ${{ github.ref_name }}
git add CITATION.cff CHANGELOG.md VERSION
git commit -m 'chore: prepare release ${{ env.NEXT_VERSION }}'
git push --set-upstream origin release-draft
echo "COMMIT_HASH=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
- name: Tag & draft release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.NEXT_VERSION }}
release_name: ${{ github.event.repository.name }} ${{ env.NEXT_VERSION }}
commitish: ${{ env.COMMIT_HASH }}
draft: true
body_path: .github/latest-release.md
- name: Next steps
run: |
echo "Next steps: Take a look at the changes in the release-draft branch and the release notes on the web. If everything is correct, publish the release. Otherwise, delete the release & tag and cut the release manually."