Skip to content

Commit 015bf12

Browse files
authored
ci(release): refactor release workflow to be callable (#3330)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
1 parent f2b4b87 commit 015bf12

File tree

3 files changed

+178
-92
lines changed

3 files changed

+178
-92
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Create or Promote Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
base_version:
7+
description: 'Base version for the release (e.g., 2.3.0)'
8+
required: true
9+
channel:
10+
description: 'The channel to create a release for or promote to'
11+
required: true
12+
type: choice
13+
options:
14+
- internal
15+
- closed
16+
- open
17+
- production
18+
dry_run:
19+
description: 'If true, calculates the tag but does not push it or start the release'
20+
required: true
21+
type: boolean
22+
default: false
23+
24+
permissions:
25+
contents: write
26+
27+
jobs:
28+
create-tag:
29+
runs-on: ubuntu-latest
30+
outputs:
31+
new_tag: ${{ steps.calculate_new_tag.outputs.new_tag }}
32+
steps:
33+
- name: Checkout code
34+
uses: actions/checkout@v5
35+
with:
36+
fetch-depth: 0
37+
38+
- name: Calculate new release tag
39+
id: calculate_new_tag
40+
run: |
41+
BASE_VERSION="${{ inputs.base_version }}"
42+
CHANNEL="${{ inputs.channel }}"
43+
44+
if [[ "$CHANNEL" == "production" ]]; then
45+
# Production tags are simple, without a channel or increment
46+
NEW_TAG="v${BASE_VERSION}"
47+
else
48+
# Pre-release channels get an incrementing number
49+
LATEST_TAG=$(git tag --list "v${BASE_VERSION}-${CHANNEL}.*" --sort=-v:refname | head -n 1)
50+
51+
if [ -z "$LATEST_TAG" ]; then
52+
INCREMENT=1
53+
else
54+
INCREMENT=$(echo "$LATEST_TAG" | sed -n "s/.*-${CHANNEL}\.\([0-9]*\)/\1/p" | awk '{print $1+1}')
55+
fi
56+
57+
NEW_TAG="v${BASE_VERSION}-${CHANNEL}.${INCREMENT}"
58+
fi
59+
60+
echo "Calculated new tag: $NEW_TAG"
61+
echo "new_tag=$NEW_TAG" >> $GITHUB_OUTPUT
62+
shell: bash
63+
64+
- name: Create and push new tag
65+
if: ${{ !inputs.dry_run }}
66+
run: |
67+
git tag ${{ steps.calculate_new_tag.outputs.new_tag }}
68+
git push origin ${{ steps.calculate_new_tag.outputs.new_tag }}
69+
70+
call-release-workflow:
71+
if: ${{ !inputs.dry_run }}
72+
needs: create-tag
73+
uses: ./.github/workflows/release.yml
74+
with:
75+
tag_name: ${{ needs.create-tag.outputs.new_tag }}
76+
release_type: ${{ inputs.channel == 'internal' && 'internal' || 'promotion' }}
77+
secrets: inherit

.github/workflows/release.yml

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,38 @@
11
name: Make Release
22

33
on:
4-
workflow_dispatch:
5-
push:
6-
tags:
7-
- 'v*'
4+
workflow_call:
5+
inputs:
6+
tag_name:
7+
description: 'The tag that triggered the release'
8+
required: true
9+
type: string
10+
release_type:
11+
description: 'Type of release (internal or promotion)'
12+
required: true
13+
type: string
14+
secrets:
15+
GSERVICES:
16+
required: true
17+
KEYSTORE:
18+
required: true
19+
KEYSTORE_FILENAME:
20+
required: true
21+
KEYSTORE_PROPERTIES:
22+
required: true
23+
DATADOG_APPLICATION_ID:
24+
required: true
25+
DATADOG_CLIENT_TOKEN:
26+
required: true
27+
GOOGLE_MAPS_API_KEY:
28+
required: true
29+
GOOGLE_PLAY_JSON_KEY:
30+
required: true
31+
GRADLE_ENCRYPTION_KEY:
32+
required: true
833

934
concurrency:
10-
group: ${{ github.workflow }}-${{ github.ref }}
35+
group: ${{ github.workflow }}-${{ inputs.tag_name }}
1136
cancel-in-progress: true
1237

1338
permissions:
@@ -26,6 +51,7 @@ jobs:
2651
- name: Checkout code
2752
uses: actions/checkout@v5
2853
with:
54+
ref: ${{ inputs.tag_name }}
2955
fetch-depth: 0
3056
submodules: 'recursive'
3157
- name: Set up JDK 21
@@ -43,7 +69,7 @@ jobs:
4369

4470
- name: Determine Version Name from Tag
4571
id: get_version_name
46-
run: echo "APP_VERSION_NAME=$(echo ${GITHUB_REF_NAME#v} | sed 's/-.*//')" >> $GITHUB_OUTPUT
72+
run: echo "APP_VERSION_NAME=$(echo ${{ inputs.tag_name }} | sed 's/-.*//' | sed 's/v//')" >> $GITHUB_OUTPUT
4773

4874
- name: Extract VERSION_CODE_OFFSET from config.properties
4975
id: get_version_code_offset
@@ -59,15 +85,16 @@ jobs:
5985
VERSION_CODE=$((COMMIT_COUNT + OFFSET))
6086
echo "versionCode=$VERSION_CODE" >> $GITHUB_OUTPUT
6187
shell: bash
62-
# This matches the reproducible versionCode strategy: versionCode = git commit count + offset
6388

6489
release-google:
6590
runs-on: ubuntu-latest
6691
needs: prepare-build-info
92+
environment: Release
6793
steps:
6894
- name: Checkout code
6995
uses: actions/checkout@v5
7096
with:
97+
ref: ${{ inputs.tag_name }}
7198
fetch-depth: 0
7299
submodules: 'recursive'
73100
- name: Set up JDK 21
@@ -76,7 +103,6 @@ jobs:
76103
java-version: '21'
77104
distribution: 'jetbrains'
78105
- name: Setup Gradle
79-
if: contains(github.ref_name, '-internal')
80106
uses: gradle/actions/setup-gradle@v5
81107
with:
82108
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
@@ -95,7 +121,7 @@ jobs:
95121
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
96122
GOOGLE_PLAY_JSON_KEY: ${{ secrets.GOOGLE_PLAY_JSON_KEY }}
97123
run: |
98-
rm -f ./app/google-services.json # Ensure clean state
124+
rm -f ./app/google-services.json
99125
echo $GSERVICES > ./app/google-services.json
100126
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME
101127
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
@@ -113,12 +139,11 @@ jobs:
113139
- name: Determine Fastlane Lane
114140
id: fastlane_lane
115141
run: |
116-
TAG_NAME="${{ github.ref_name }}"
117-
if [[ "$TAG_NAME" == *"-internal"* ]]; then
142+
if [[ "${{ inputs.tag_name }}" == *"-internal"* ]]; then
118143
echo "lane=internal" >> $GITHUB_OUTPUT
119-
elif [[ "$TAG_NAME" == *"-closed"* ]]; then
144+
elif [[ "${{ inputs.tag_name }}" == *"-closed"* ]]; then
120145
echo "lane=closed" >> $GITHUB_OUTPUT
121-
elif [[ "$TAG_NAME" == *"-open"* ]]; then
146+
elif [[ "${{ inputs.tag_name }}" == *"-open"* ]]; then
122147
echo "lane=open" >> $GITHUB_OUTPUT
123148
else
124149
echo "lane=production" >> $GITHUB_OUTPUT
@@ -131,37 +156,35 @@ jobs:
131156
run: bundle exec fastlane ${{ steps.fastlane_lane.outputs.lane }}
132157

133158
- name: Upload Google AAB artifact
134-
if: contains(github.ref_name, '-internal')
135159
uses: actions/upload-artifact@v4
136160
with:
137161
name: google-aab
138162
path: app/build/outputs/bundle/googleRelease/app-google-release.aab
139163
retention-days: 1
140164

141165
- name: Upload Google APK artifact
142-
if: contains(github.ref_name, '-internal')
143166
uses: actions/upload-artifact@v4
144167
with:
145168
name: google-apk
146169
path: app/build/outputs/apk/google/release/app-google-release.apk
147170
retention-days: 1
148171

149172
- name: Attest Google artifacts provenance
150-
if: contains(github.ref_name, '-internal')
151173
uses: actions/attest-build-provenance@v3
152174
with:
153175
subject-path: |
154176
app/build/outputs/bundle/googleRelease/app-google-release.aab
155177
app/build/outputs/apk/google/release/app-google-release.apk
156178
157179
release-fdroid:
158-
if: contains(github.ref_name, '-internal')
159180
runs-on: ubuntu-latest
160181
needs: prepare-build-info
182+
environment: Release
161183
steps:
162184
- name: Checkout code
163185
uses: actions/checkout@v5
164186
with:
187+
ref: ${{ inputs.tag_name }}
165188
fetch-depth: 0
166189
submodules: 'recursive'
167190
- name: Set up JDK 21
@@ -210,54 +233,39 @@ jobs:
210233
with:
211234
subject-path: app/build/outputs/apk/fdroid/release/app-fdroid-release.apk
212235

213-
create-internal-release:
236+
github-release:
214237
runs-on: ubuntu-latest
215238
needs: [prepare-build-info, release-google, release-fdroid]
216-
if: contains(github.ref_name, '-internal')
239+
environment: Release
217240
steps:
218241
- name: Download all artifacts
219242
uses: actions/download-artifact@v5
220243
with:
221244
path: ./artifacts
222245

223-
- name: Create GitHub Release
224-
uses: softprops/action-gh-release@v2
225-
with:
226-
tag_name: v${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
227-
name: ${{ github.ref_name }}
228-
generate_release_notes: true
229-
files: ./artifacts/*/*
230-
draft: true
231-
prerelease: true
232-
env:
233-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
234-
235-
promote-release:
236-
runs-on: ubuntu-latest
237-
needs: [prepare-build-info, release-google]
238-
if: "!contains(github.ref_name, '-internal')"
239-
steps:
240246
- name: Determine Release Properties
241247
id: release_properties
242248
run: |
243-
TAG_NAME="${{ github.ref_name }}"
244-
if [[ "$TAG_NAME" == *"-closed"* ]]; then
249+
if [[ "${{ inputs.release_type }}" == "internal" ]]; then
250+
echo "draft=true" >> $GITHUB_OUTPUT
251+
echo "prerelease=true" >> $GITHUB_OUTPUT
252+
elif [[ "${{ inputs.tag_name }}" == *"-closed"* ]]; then
245253
echo "draft=false" >> $GITHUB_OUTPUT
246254
echo "prerelease=true" >> $GITHUB_OUTPUT
247-
elif [[ "$TAG_NAME" == *"-open"* ]]; then
255+
elif [[ "${{ inputs.tag_name }}" == *"-open"* ]]; then
248256
echo "draft=false" >> $GITHUB_OUTPUT
249257
echo "prerelease=true" >> $GITHUB_OUTPUT
250258
else
251259
echo "draft=false" >> $GITHUB_OUTPUT
252260
echo "prerelease=false" >> $GITHUB_OUTPUT
253261
fi
254262
255-
- name: Update GitHub Release
263+
- name: Create or Update GitHub Release
256264
uses: softprops/action-gh-release@v2
257265
with:
258-
tag_name: v${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
259-
name: ${{ github.ref_name }}
266+
tag_name: ${{ inputs.tag_name }}
267+
name: ${{ inputs.tag_name }}
268+
generate_release_notes: true
269+
files: ./artifacts/*/*
260270
draft: ${{ steps.release_properties.outputs.draft }}
261271
prerelease: ${{ steps.release_properties.outputs.prerelease }}
262-
env:
263-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)