-
-
Notifications
You must be signed in to change notification settings - Fork 4
223 lines (210 loc) · 8.65 KB
/
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
name: Release
on:
workflow_dispatch:
inputs:
branch:
type: string
description: Branch name to release
required: true
default: main
section:
type: choice
description: Version section to increment
options:
- PATCH
- MINOR
- MAJOR
required: true
default: PATCH
version:
type: string
description: |
...or manually define version like 1.2.3, 1.2.3-suffix
required: false
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Setup bot token
uses: actions/create-github-app-token@v1
id: bot
with:
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
- name: Configure bot git account
id: get-user-id
env:
GH_TOKEN: ${{ steps.bot.outputs.token }}
run: |
USER_ID="$(gh api "/users/${{ steps.bot.outputs.app-slug }}[bot]" --jq .id)"
USER_EMAIL="$USER_ID+${{ steps.bot.outputs.app-slug }}[bot]@users.noreply.github.com"
USER_NAME="${{ steps.bot.outputs.app-slug }}[bot]"
git config --global user.name "$USER_NAME"
git config --global user.email "$USER_EMAIL"
- name: Checkout
uses: actions/checkout@v4
with:
ref: "refs/heads/${{ inputs.branch }}"
token: ${{ steps.bot.outputs.token }}
# Required to deduce version from git tags
fetch-depth: 0
- name: Validate build succeeded
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if git tag --points-at HEAD | grep -Eq "^v[0-9]+.[0-9]+.[0-9]+$"; then
echo "Last commit is a release commit."
exit 0
fi
declare -r SHA="$(git rev-parse HEAD)"
declare -r RUNS="$(gh api \
-H "Accept: application/vnd.github+json" \
/repos/${{ github.repository }}/actions/runs?head_sha=$SHA)"
declare -r BUILD_SUCCESS="$(echo "$RUNS" | jq -r 'limit(1; .workflow_runs[] | select(.name == "Build" and .conclusion == "success")) | .conclusion')"
if [ -z "$BUILD_SUCCESS" ]; then
echo "Commit did not pass Build. Stopping release!"
exit 1
fi
echo "Last commit passed build."
exit 0
- name: Get versions
id: versions
env:
BRANCH: ${{ inputs.branch }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
MANUAL_VERSION: ${{ inputs.version }}
INCREMENT_SECTION: ${{ inputs.section }}
run: |
declare -r GIT_VERSION="$(git tag -l 'v[0-9]*' --merged HEAD --sort=-v:refname | grep -E "^v[0-9]+.[0-9]+.[0-9]+$" | head -n 1 | cut -c2-)"
declare -r VERSION=${GIT_VERSION:-0.0.0}
declare -r MAJOR="$(echo "$VERSION" | cut -d. -f1)"
declare -r MINOR="$(echo "$VERSION" | cut -d. -f2)"
declare -r PATCH="$(echo "$VERSION" | cut -d. -f3)"
declare NEXT_VERSION=""
if [ -n "$MANUAL_VERSION" ]; then
if [[ "$MANUAL_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
NEXT_VERSION="$MANUAL_VERSION"
else
echo "Invalid manual version: $MANUAL_VERSION" >&2
echo "Expected versions format: 1.2.3" >&2
exit 1
fi
elif [ "$INCREMENT_SECTION" == "PATCH" ]; then
NEXT_VERSION="$MAJOR.$MINOR.$(( PATCH + 1 ))"
elif [ "$INCREMENT_SECTION" == "MINOR" ]; then
NEXT_VERSION="$MAJOR.$(( MINOR + 1 )).0"
elif [ "$INCREMENT_SECTION" == "MAJOR" ]; then
NEXT_VERSION="$(( MAJOR + 1 )).0.0"
else
echo "Unrecognized option: $INCREMENT_SECTION" >&2
exit 1
fi
if [ "$BRANCH" != "$DEFAULT_BRANCH" ] && [ "$(echo "$NEXT_VERSION" | cut -d. -f1)" != "$MAJOR" ]; then
echo "New major version can be created only from the $DEFAULT_BRANCH branch" >&2
exit 1
fi
echo -e "VERSION: $VERSION\nNEXT_VERSION: $NEXT_VERSION"
echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Update version in files
id: commit
env:
PREV_VERSION: ${{ steps.versions.outputs.version }}
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
run: |
declare -r ESC_PREV_VERSION="${PREV_VERSION//./\\.}"
echo "Changing: $PREV_VERSION -> $NEXT_VERSION"
sed -i "s|${ESC_PREV_VERSION}|${NEXT_VERSION}|" README.md
sed -i "s|^version=${ESC_PREV_VERSION}|version=${NEXT_VERSION}|" gradle.properties
if [ "$NEXT_VERSION" == "${NEXT_VERSION%%-SNAPSHOT}" ]; then
if [ -n "$(git status --porcelain)" ]; then
git add -A
git commit -a -m "Update version $PREV_VERSION -> $NEXT_VERSION" -m "[ci skip]"
git push
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
else
echo "Nothing changed. Skipping commit."
fi
else
echo "Skipping committing updated version in config files for SNAPSHOT version."
fi
- name: Publish Release to Gradle Plugin Portal
id: publish
env:
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
run: |
./gradlew publishPlugins \
-Pgradle.publish.key=$GRADLE_PUBLISH_KEY \
-Pgradle.publish.secret=$GRADLE_PUBLISH_SECRET \
-Pversion=$NEXT_VERSION
echo "### Published release version $NEXT_VERSION 🚀" | tee -a $GITHUB_STEP_SUMMARY
- name: Revert version commit on failure
if: failure() && steps.publish.conclusion == 'failure'
env:
COMMIT_SHA: ${{ steps.commit.outputs.sha }}
run: |
if [ -n "$COMMIT_SHA" ]; then
git revert "$COMMIT_SHA"
git push
echo "Reverted version commit: $COMMIT_SHA"
fi
- name: Create release tag
env:
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
run: |
declare -r TAG_NAME="v$NEXT_VERSION"
git tag "$TAG_NAME"
git push origin "$TAG_NAME"
echo "name=$TAG_NAME" >> $GITHUB_OUTPUT
- name: Create major branch
id: tag
env:
BRANCH: ${{ inputs.branch }}
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
PREV_VERSION: ${{ steps.versions.outputs.version }}
run: |
declare -r NEXT_MAJOR="$(echo "$NEXT_VERSION" | cut -d. -f1)"
declare -r PREV_MAJOR="$(echo "$PREV_VERSION" | cut -d. -f1)"
if [ "$NEXT_MAJOR" != "$PREV_MAJOR" ]; then
NEW_BRANCH="v${PREV_MAJOR}.x.x"
if git rev-parse --verify "$NEW_BRANCH" &>/dev/null; then
echo "Repository already contains branch for previous major version: $NEW_BRANCH"
else
git checkout -b "$NEW_BRANCH"
git push origin "$NEW_BRANCH"
git checkout "$BRANCH"
echo "Created branch for new major version: $NEW_BRANCH"
echo "### Created branch for previous major version $NEW_BRANCH 🚀" | tee -a $GITHUB_STEP_SUMMARY
fi
else
echo "Next and prev major versions are the same: $NEXT_MAJOR"
fi
- name: Generate release notes
id: notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PREV_VERSION: ${{ steps.versions.outputs.version }}
NEXT_VERSION: ${{ steps.versions.outputs.next_version }}
run: |
declare -r PREV_TAG_NAME="$([ "$PREV_VERSION" == "0.0.0" ] && echo "" || echo "v$PREV_VERSION")"
declare -r NOTES="$(gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
/repos/${{ github.repository }}/releases/generate-notes \
-f tag_name="v$NEXT_VERSION" \
-f previous_tag_name="$PREV_TAG_NAME" \
| jq -r '.body')"
echo 'notes<<EOF' >> $GITHUB_OUTPUT
echo "$NOTES" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- name: Create github release
if: steps.notes.conclusion == 'success'
uses: ncipollo/release-action@v1
with:
allowUpdates: true
body: ${{ steps.notes.outputs.notes }}
draft: ${{ inputs.publish == 'SKIP' }}
tag: v${{ steps.versions.outputs.next_version }}
token: ${{ secrets.GITHUB_TOKEN }}