This repository was archived by the owner on Aug 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaction.yml
195 lines (184 loc) · 8.64 KB
/
action.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
name: Gauge release
description: Gauge if should do a patch release
inputs:
latest_local_sha:
description: The latest local sha
required: true
type: string
outputs:
do_release:
description: Whether to do a release
value: ${{ steps.gauge-release.outputs.do_release }}
next_tag:
description: The patch tag to release
value: ${{ steps.gauge-release.outputs.next_tag }}
runs:
using: composite
steps:
- name: Gauge release
id: gauge-release
shell: bash
env:
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_SHA: ${{ github.sha }}
LATEST_LOCAL_SHA: ${{ inputs.latest_local_sha }}
run: |
DO_RELEASE=1
# Double check that LATEST_LOCAL_SHA matches GITHUB_SHA
echo "LATEST_LOCAL_SHA is $LATEST_LOCAL_SHA"
echo "GITHUB_SHA is $GITHUB_SHA"
if [[ $LATEST_LOCAL_SHA != $GITHUB_SHA ]]; then
echo "Not patch releasing because GITHUB_SHA is not equal to latest local sha"
DO_RELEASE=0
fi
# Must be on a minor branch to do a patch release
if [[ $DO_RELEASE == "1" ]]; then
if ! [[ $GITHUB_REF_NAME =~ ^[0-9]+\.[0-9]+$ ]]; then
echo "Not patch releasing because not on a minor branch"
DO_RELEASE=0
fi
fi
# Validate that this commit is that latest commit for the branch using GitHub API
# We need to check this in case re-rerunning an old job and there have been new commits since
if [[ $DO_RELEASE == "1" ]]; then
# https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28
RESP_CODE=$(curl -w %{http_code} -s -o __response.json \
-X GET "https://api.github.com/repos/${GITHUB_REPOSITORY}/commits?sha=${GITHUB_REF_NAME}&per_page=1" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ github.token }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
)
if [[ $RESP_CODE != "200" ]]; then
echo "Unable to read list of commits - HTTP response code was $RESP_CODE"
exit 1
fi
LATEST_REMOTE_SHA=$(jq -r '.[0].sha' __response.json)
echo "LATEST_REMOTE_SHA is $LATEST_REMOTE_SHA"
echo "LATEST_LOCAL_SHA is $LATEST_LOCAL_SHA"
if [[ $LATEST_REMOTE_SHA != $LATEST_LOCAL_SHA ]]; then
echo "Not patch releasing because latest remote sha is not equal to latest local sha"
DO_RELEASE=0
fi
# Also validate the sha matches GITHUB_SHA, which is what gha-tag-release will use
if [[ $GITHUB_SHA != $LATEST_LOCAL_SHA ]]; then
echo "Not patch releasing because GITHUB_SHA is not equal to latest local sha"
DO_RELEASE=0
fi
fi
# Check is there is an existing tag on the branch using GitHub API
# Note cannot use local `git tag` because actions/checkout by default will not checkout tags
# and you need to checkout full history in order to get them
LATEST_TAG=""
NEXT_TAG=""
if [[ $DO_RELEASE == "1" ]]; then
# https://docs.github.com/en/rest/git/refs?apiVersion=2022-11-28#list-matching-references
RESP_CODE=$(curl -w %{http_code} -s -o __response.json \
-X GET https://api.github.com/repos/${GITHUB_REPOSITORY}/git/matching-refs/tags/${GITHUB_REF_NAME} \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ github.token }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
)
if [[ $RESP_CODE != "200" ]]; then
echo "Unable to read list of tags - HTTP response code was $RESP_CODE"
exit 1
fi
# Get the latest tag
LATEST_TAG=$(jq -r '.[].ref' __response.json | grep -Po '(?<=^refs\/tags\/)[0-9]+\.[0-9]+\.[0-9]+$' | sort -V -r | head -n 1) || true
echo "LATEST_TAG is $LATEST_TAG"
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
if ! [[ $LATEST_TAG =~ ([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
echo "Not patch releasing because cannot find a matching semver tag on the branch"
DO_RELEASE=0
else
MAJOR=${BASH_REMATCH[1]}
MINOR=${BASH_REMATCH[2]}
PATCH=${BASH_REMATCH[3]}
NEXT_TAG="$MAJOR.$MINOR.$((PATCH+1))"
echo "NEXT_TAG is $NEXT_TAG"
echo "next_tag=$NEXT_TAG" >> $GITHUB_OUTPUT
fi
fi
# Check if there is anything relevant commits to release using GitHub API using the tripe-dot compoare endpoint
# which will show things that are in the next-patch branch that are not in the latest tag
# Note: unlike CLI, the API endpoint results include all merged pull-requests, not commits
# Pull-requests prefixed with MNT or DOC will not be considered relevant for releasing
if [[ $DO_RELEASE == "1" ]]; then
# Check on github release notes api if there's anything worth releasing
# Compare commits between current sha with latest tag to see if there is anything worth releasing
# https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#compare-two-commits
RESP_CODE=$(curl -w %{http_code} -s -o __response.json \
-X GET https://api.github.com/repos/$GITHUB_REPOSITORY/compare/$LATEST_TAG...$GITHUB_SHA?per_page=100 \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ github.token }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
)
if [[ $RESP_CODE != "200" ]]; then
echo "Unable to fetch compare two commits - HTTP response code was $RESP_CODE"
exit 1
fi
# Get commits for text parsing
jq -r '.commits[].commit.message' __response.json > __commits.json
# Parse comits one line at a time
HAS_THINGS_TO_RELEASE=0
while IFS="" read -r line || [[ -n $line ]]; do
# Remove any leading bullet points
line="${line#\* }"
line="${line#\-}"
line="${line# }"
if ! [[ "$line" =~ ^(Merge|MNT|DOC) ]] && ! [[ $line =~ ^[[:space:]]*$ ]]; then
HAS_THINGS_TO_RELEASE=1
break
fi
done < __commits.json
if [[ $HAS_THINGS_TO_RELEASE == "0" ]]; then
echo "Not patch releasing because there is nothing relevant to release"
DO_RELEASE=0
fi
fi
# Check again, this time using the double-dot syntax which will show the raw diff between the latest tag
# and the next-patch branch
# This isn't available via the github api, so screen scrape this instead. Screen scraping isn't
# great because it's brittle, however if this fails then all that happens is we tag a release that
# has no actual changes, which isn't the end of the world.
# Here we are only detecting if there are no actual changes to release, which can happen in a couple of scenarios:
# a) A change is made and tagged, and then backported to an older branch and then merged-up
# b) A change made in a previous major that we don't want to keep in current major, so
# it's reverted during the merge-up
if [[ $DO_RELEASE == "1" ]]; then
RESP_CODE=$(curl -w %{http_code} -s -o __compare.html \
-X GET https://github.com/$GITHUB_REPOSITORY/compare/$LATEST_TAG..$GITHUB_SHA
)
if [[ $RESP_CODE != "200" ]]; then
echo "Unable to fetch compare html - HTTP response code was $RESP_CODE"
exit 1
fi
PARSED=$(php -r '
$s = file_get_contents("__compare.html");
$s = strip_tags($s);
$s = str_replace("[\r\n]", " ", $s);
$s = preg_replace("# {2,}#", " ", $s);
echo $s;
')
# `|| true` needs to be suffixed otherwise an error code of 1 will be omitted when there is no grep match
IDENTICAL=$(echo $PARSED | grep "$LATEST_TAG and $GITHUB_SHA are identical") || true
if [[ $IDENTICAL != "" ]]; then
echo "Not patch releasing because there are no actual changes to release"
DO_RELEASE=0
fi
fi
echo "do_release output is $DO_RELEASE"
echo "do_release=$DO_RELEASE" >> $GITHUB_OUTPUT
- name: Delete temporary files
if: always()
shell: bash
run: |
if [[ -f __response.json ]]; then
rm __response.json
fi
if [[ -f __commits.json ]]; then
rm __commits.json
fi
if [[ -f __compare.html ]]; then
rm __compare.html
fi