-
Notifications
You must be signed in to change notification settings - Fork 110
/
github_release.yaml
373 lines (327 loc) · 13.4 KB
/
github_release.yaml
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# Copyright 2019 The Tekton Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: create-draft-release
spec:
params:
- name: package
description: package (and its children) under test
- name: git-revision
description: the git revision of the release
- name: release-name
description: The name of the release (e.g. Cat + Robot for pipeline)
- name: release-tag
description: Release number and git tag to be applied (e.g. v0.888.1, with 'v')
- name: previous-release-tag
description: Previous release number - for author and PR list calculation
- name: rekor-uuid
description: The Rekor UUID associated to the attestation
workspaces:
- name: shared
description: contains the cloned repo and the release files
stepTemplate:
env:
- name: GITHUB_TOKEN
valueFrom:
secretKeyRef:
name: github-token
key: GITHUB_TOKEN
- name: HOME
value: /tekton/home
- name: VERSION
value: $(params.release-tag)
- name: PROJECT
value: $(params.package)
- name: OLD_VERSION
value: $(params.previous-release-tag)
- name: RELEASE_NAME
value: $(params.release-name)
- name: GIT_REVISION
value: $(params.git-revision)
- name: REKOR_UUID
value: $(params.rekor-uuid)
steps:
- name: header
image: gcr.io/tekton-releases/dogfooding/hub
script: |
#!/bin/bash
set -ex
TEKTON_PROJECT=$(basename $PROJECT)
BQ="\`" # Backquote
cat <<EOF | tee $HOME/release.md
Tekton ${TEKTON_PROJECT^} release ${VERSION} "${RELEASE_NAME}"
<!-- For major releases, add a tag line
# 🎉 [Tag Line - to be done] 🎉
-->
-[Docs @ ${VERSION}](https://github.com/${PROJECT}/tree/${VERSION}/docs)
-[Examples @ ${VERSION}](https://github.com/${PROJECT}/tree/${VERSION}/examples)
## Installation one-liner
${BQ}${BQ}${BQ}shell
kubectl apply -f https://storage.googleapis.com/tekton-releases/${TEKTON_PROJECT}/previous/${VERSION}/release.yaml
${BQ}${BQ}${BQ}
## Attestation
The Rekor UUID for this release is \`${REKOR_UUID}\`
Obtain the attestation:
${BQ}${BQ}${BQ}shell
REKOR_UUID=${REKOR_UUID}
rekor-cli get --uuid \$REKOR_UUID --format json | jq -r .Attestation | jq .
${BQ}${BQ}${BQ}
Verify that all container images in the attestation are in the release file:
${BQ}${BQ}${BQ}shell
RELEASE_FILE=https://storage.googleapis.com/tekton-releases/${TEKTON_PROJECT}/previous/${VERSION}/release.yaml
REKOR_UUID=${REKOR_UUID}
# Obtains the list of images with sha from the attestation
REKOR_ATTESTATION_IMAGES=\$(rekor-cli get --uuid "\$REKOR_UUID" --format json | jq -r .Attestation | jq -r '.subject[]|.name + ":${VERSION}@sha256:" + .digest.sha256')
# Download the release file
curl "\$RELEASE_FILE" > release.yaml
# For each image in the attestation, match it to the release file
for image in \$REKOR_ATTESTATION_IMAGES; do
printf \$image; grep -q \$image release.yaml && echo " ===> ok" || echo " ===> no match";
done
${BQ}${BQ}${BQ}
<!-- Any special upgrade notice
## Upgrade Notices
-->
## Changes
EOF
- name: filter-data
image: gcr.io/tekton-releases/dogfooding/hub
workingDir: $(workspaces.shared.path)/repo
script: |
#!/usr/bin/env bash
set -ex
# Restore full git history
git fetch --unshallow
git fetch --tags
# UPPER_THRESHOLD is the newest sha we are interested in
UPPER_THRESHOLD=${GIT_REVISION}
# COMMON_ANCESTOR is the common ancestor between the OLD_VERSION and UPPER_THRESHOLD
COMMON_ANCESTOR=$(git merge-base ${OLD_VERSION} ${UPPER_THRESHOLD})
# OLD_RELEASE_SUBJECTS is the list of commit subjects cherry-picked (probably?) from main
OLD_RELEASE_SUBJECTS=$HOME/old_subjects.txt
echo "Cherry-picked commits:"
git log --format="%s" $COMMON_ANCESTOR..$OLD_VERSION | sort -u | tee $OLD_RELEASE_SUBJECTS
echo "OLD_VERSION: $OLD_VERSION"
echo "COMMON_ANCESTOR: $COMMON_ANCESTOR"
echo "UPPER_THRESHOLD: $UPPER_THRESHOLD"
# Save the PR data in CSV. Only consider PRs whose sha verifies the condition
# COMMON_ANCESTOR is ancestor of SHA is ancestor of UPPER_THRESHOLD
# And title no in the OLD_VERSION branch.
# Working Assumptions:
# - there are no duplicate titles in commits
# - we always cherry-pick full PRs, never commits out of a multi-commit PR
# Format of output data:
# "author;number;title"
hub pr list --state merged -L 300 -f "%sm;%au;%i;%t;%L%n" | \
while read pr; do
SHA=$(echo $pr | cut -d';' -f1)
# Skip the common ancestor has it has already been released
if [ "$SHA" == "$COMMON_ANCESTOR" ]; then
continue
fi
SUBJECT=$(git log -1 --format="%s" $SHA || echo "__NOT_FOUND__")
git merge-base --is-ancestor $SHA $UPPER_THRESHOLD && \
git merge-base --is-ancestor $COMMON_ANCESTOR $SHA && \
! $(egrep "^${SUBJECT}$" $OLD_RELEASE_SUBJECTS &> /dev/null) &&
echo $pr | cut -d';' -f2-
done > $HOME/pr.csv || true # We do not want to fail is the last of the loop is not a match
echo "$(wc -l $HOME/pr.csv | awk '{ print $1}') PRs in the new release."
cat $HOME/pr.csv
- name: release-notes
image: stedolan/jq
script: |
#!/bin/bash
set -e
# First process pull requests that have release notes
# Extract the release notes but drop lines that match an unmodified PR template
# || true in case all PRs are "release-note-none"
grep -v "release-note-none" $HOME/pr.csv > $HOME/pr-notes-tmp.csv || true
cat $HOME/pr-notes-tmp.csv | while read pr; do
PR_NUM=$(echo $pr | cut -d';' -f2)
PR_RELEASE_NOTES_B64=$(wget -O- https://api.github.com/repos/${PROJECT}/issues/${PR_NUM:1} | \
jq .body -r | grep -oPz '(?s)(?<=```release-note..)(.+?)(?=```)' | \
grep -avP '\W*(Your release note here|action required: your release note here|NONE)\W*' | base64 -w0)
echo "$pr;$PR_RELEASE_NOTES_B64" >> $HOME/pr-notes.csv
# Avoid rate limiting
sleep 0.2
done
# Copy pull requests without release notes to a dedicated file
# || true in case no PRs have "release-note-none"
grep "release-note-none" $HOME/pr.csv > $HOME/pr-no-notes.csv || true
- name: body
image: busybox
script: |
#!/bin/sh
set -e
cat <<EOF | tee -a $HOME/release.md
# Features
$(awk -F";" '/kind\/feature/{ print "echo -e \"* :sparkles: "$3" ("$2")\n\n$(echo "$5" | base64 -d)\n\"" }' $HOME/pr-notes.csv | sh)
$(awk -F";" '/kind\/feature/{ print "* :sparkles: "$3" ("$2")" }' $HOME/pr-no-notes.csv)
<!-- Fill in deprecation notices when applicable
# Deprecation Notices
* :rotating_light: [Deprecation Notice Title]
[Detailed deprecation notice description] (#Number).
[Fill list here]
-->
<!-- Fill in backward incompatible changes when applicable
# Backwards incompatible changes
In current release:
* :rotating_light: [Change Title]
[Detailed change description] (#Number).
[Fill list here]
-->
### Fixes
$(awk -F";" '/kind\/bug/{ print "echo -e \"* :bug: "$3" ("$2")\n\n$(echo "$5" | base64 -d)\n\"" }' $HOME/pr-notes.csv | sh)
$(awk -F";" '/kind\/flake/{ print "echo -e \"* :bug: "$3" ("$2")\n\n$(echo "$5" | base64 -d)\n\"" }' $HOME/pr-notes.csv | sh)
$(awk -F";" '/kind\/bug/{ print "* :bug: "$3" ("$2")" }' $HOME/pr-no-notes.csv)
$(awk -F";" '/kind\/flake/{ print "* :bug: "$3" ("$2")" }' $HOME/pr-no-notes.csv)
### Misc
$(awk -F";" '/kind\/cleanup/{ print "echo -e \"* :hammer: "$3" ("$2")\n\n$(echo "$5" | base64 -d)\n\"" }' $HOME/pr-notes.csv | sh)
$(awk -F";" '/kind\/misc/{ print "echo -e \"* :hammer: "$3" ("$2")\n\n$(echo "$5" | base64 -d)\n\"" }' $HOME/pr-notes.csv | sh)
$(awk -F";" '/kind\/cleanup/{ print "* :hammer: "$3" ("$2")" }' $HOME/pr-no-notes.csv)
$(awk -F";" '/kind\/misc/{ print "* :hammer: "$3" ("$2")" }' $HOME/pr-no-notes.csv)
### Docs
$(awk -F";" '/kind\/documentation/{ print "echo -e \"* :book: "$3" ("$2")\n\n$(echo "$5" | base64 -d)\n\"" }' $HOME/pr-notes.csv | sh)
$(awk -F";" '/kind\/documentation/{ print "* :book: "$3" ("$2")" }' $HOME/pr-no-notes.csv)
EOF
- name: authors
image: gcr.io/tekton-releases/dogfooding/hub
workingDir: $(workspaces.shared.path)/repo
script: |
#!/usr/bin/env bash
set -ex
cat <<EOF | tee -a $HOME/release.md
## Thanks
Thanks to these contributors who contributed to ${VERSION}!
$(awk -F";" '{ print "* :heart: @"$1 }' $HOME/pr.csv | sort -u)
Extra shout-out for awesome release notes:
$(awk -F";" '{ print "* :heart_eyes: @"$1 }' $HOME/pr-notes.csv | sort -u)
EOF
- name: pr-data
image: gcr.io/tekton-releases/dogfooding/hub
workingDir: $(workspaces.shared.path)/repo
script: |
#!/usr/bin/env bash
set -ex
cat <<EOF | tee -a $HOME/release.md
<!--
## Unsorted PR List
$(egrep -v 'kind/(feature|documentation|cleanup|flake|bug|misc)' $HOME/pr.csv | awk -F";" '{ print "- "$3" ("$2")" }')
To Be Done: Deprecation Notices, Backward Incompatible Changes
-->
EOF
- name: create-draft
image: gcr.io/tekton-releases/dogfooding/hub
workingDir: $(workspaces.shared.path)/repo
script: |
#!/usr/bin/env bash
set -ex
RELEASE_PATH="../release"
TEKTON_PROJECT=$(basename $PROJECT)
# List the files in the release folder
RELEASE_FILES=$(find "${RELEASE_PATH}" -type f | awk '{ print "-a "$1 }' | tr '\n' ' ')
hub release create --draft --prerelease \
--commitish ${GIT_REVISION} ${RELEASE_FILES} \
--file $HOME/release.md ${VERSION}
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: release-draft
spec:
params:
- name: package
description: package (and its children) under test
- name: git-revision
description: the git revision of the release
- name: release-name
description: The name of the release (e.g. Cat + Robot for pipeline)
- name: release-tag
description: Release number and git tag to be applied (e.g. v0.888.1, with 'v')
- name: previous-release-tag
description: Previous release number - for author and PR list calculation
- name: bucket
description: GCS bucket where to get the release files from (e.g. gs://tekton-releases/pipeline)
- name: rekor-uuid
description: The Rekor UUID associated to the attestation
workspaces:
- name: shared
description: Workspace where the git repo is prepared for testing
- name: credentials
description: GCS credentials
tasks:
- name: clone-repo
taskRef:
resolver: bundles
params:
- name: bundle
value: ghcr.io/tektoncd/catalog/upstream/tasks/git-clone:0.7
- name: name
value: git-clone
- name: kind
value: task
params:
- name: url
value: https://github.com/$(params.package)
- name: revision
value: $(params.git-revision)
workspaces:
- name: output
workspace: shared
subPath: repo
- name: clone-bucket
taskRef:
resolver: bundles
params:
- name: bundle
value: ghcr.io/tektoncd/catalog/upstream/tasks/gcs-download:0.1
- name: name
value: gcs-download
- name: kind
value: task
params:
- name: path
value: .
- name: location
value: $(params.bucket)/previous/$(params.release-tag)
- name: typeDir
value: "true"
workspaces:
- name: output
workspace: shared
subPath: release
- name: credentials
workspace: credentials
- name: create-draft-release
runAfter: ['clone-repo', 'clone-bucket']
taskRef:
name: create-draft-release
workspaces:
- name: shared
workspace: shared
params:
- name: package
value: $(params.package)
- name: git-revision
value: $(params.git-revision)
- name: release-name
value: $(params.release-name)
- name: release-tag
value: $(params.release-tag)
- name: previous-release-tag
value: $(params.previous-release-tag)
- name: rekor-uuid
value: $(params.rekor-uuid)