blob: e8d1c7c22cd7e463d4c0ba3b5f36a9edba583436 [file] [log] [blame]
Zack Williams27cd3e52018-09-18 16:44:50 -07001#!/usr/bin/env bash
Joey Armstrong28eddda2023-01-10 03:09:34 -05002# -----------------------------------------------------------------------
3# Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
Zack Williams27cd3e52018-09-18 16:44:50 -07004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
Joey Armstrong28eddda2023-01-10 03:09:34 -050016#
Zack Williams27cd3e52018-09-18 16:44:50 -070017# github-release.sh
18# builds (with make) and uploads release artifacts (binaries, etc.) to github
19# given a tag also create checksums files and release notes from the commit
20# message
Joey Armstrong28eddda2023-01-10 03:09:34 -050021# -----------------------------------------------------------------------
Zack Williams27cd3e52018-09-18 16:44:50 -070022
Joey Armstrong2097d3e2023-03-26 10:32:03 -040023set -euo pipefail
24
25##-------------------##
26##---] GLOBALS [---##
27##-------------------##
28declare -g WORKSPACE
29declare -g GERRIT_PROJECT
30declare -g __githost='github.com'
31
32## -----------------------------------------------------------------------
33## Uncomment to activate
34## -----------------------------------------------------------------------
35declare -i -g draft_release=1
Joey Armstrong41923cc2023-01-30 14:38:16 -050036# declare -g TRACE=0 # uncomment to set -x
37
38# shellcheck disable=SC2015
39[[ -v TRACE ]] && { set -x; } || { set +x; } # SC2015 (shellcheck -x)
40
Joey Armstrong2097d3e2023-03-26 10:32:03 -040041declare -a -g ARGV=() # Capture args to minimize globals and arg passing
42[[ $# -gt 0 ]] && ARGV=("$@")
Joey Armstrongd99e3d22023-01-29 12:35:43 -050043
44declare -g scratch # temp workspace for downloads
45declare -g gh_cmd # path to gh command
46
Joey Armstrong2097d3e2023-03-26 10:32:03 -040047declare -g SCRIPT_VERSION='1.2' # git changeset needed
Joey Armstrong26707f02023-01-26 12:41:12 -050048
Joey Armstrong7f382ef2023-01-25 12:00:08 -050049##--------------------##
50##---] INCLUDES [---##
Joey Armstrong1962bcf2023-01-27 13:53:18 -050051##--------------------#
Joey Armstrong2097d3e2023-03-26 10:32:03 -040052
53## -----------------------------------------------------------------------
54## Intent: Register an interrupt handler to display a stack trace on error
55## -----------------------------------------------------------------------
56function errexit()
57{
58 local err=$?
59 set +o xtrace
60 local code="${1:-1}"
61
62 local prefix="${BASH_SOURCE[1]}:${BASH_LINENO[0]}"
63 echo -e "\nOFFENDER: ${prefix}"
64 if [ $# -gt 0 ] && [ "$1" == '--stacktrace-quiet' ]; then
65 code=1
66 else
67 echo "ERROR: '${BASH_COMMAND}' exited with status $err"
68 fi
69
70 # Print out the stack trace described by $function_stack
71 if [ ${#FUNCNAME[@]} -gt 2 ]
72 then
73 echo "Call tree:"
74 for ((i=1;i<${#FUNCNAME[@]}-1;i++))
75 do
76 echo " $i: ${BASH_SOURCE[$i+1]}:${BASH_LINENO[$i]} ${FUNCNAME[$i]}(...)"
77 done
78 fi
79
80 echo "Exiting with status ${code}"
81 echo
82 exit "${code}"
83 # return
84}
85
86# trap ERR to provide an error handler whenever a command exits nonzero
87# this is a more verbose version of set -o errexit
88trap errexit ERR
89
90# setting errtrace allows our ERR trap handler to be propagated to functions,
91# expansions and subshells
92set -o errtrace
Joey Armstrong7f382ef2023-01-25 12:00:08 -050093
94## -----------------------------------------------------------------------
Joey Armstrongd99e3d22023-01-29 12:35:43 -050095## Intent: Cleanup scratch area on exit
96## -----------------------------------------------------------------------
97function sigtrap()
98{
99 ## Prevent mishaps
100 local is_read_only
101 is_read_only="$(declare -p scratch)"
102 if [[ $is_read_only != *"declare -r scratch="* ]]; then
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400103 echo "ERROR: variable scratch is not read-only, cleanup skipped"
104 exit 1
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500105 fi
106
107 if [ -d "$scratch" ]; then
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400108 /bin/rm -fr "$scratch"
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500109 fi
110
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400111 do_logout
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500112 return
113}
114trap sigtrap EXIT
115
116## -----------------------------------------------------------------------
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400117## Intent: Return a release version for queries
118## Note: Do not use in production, function is intended for interactive use
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400119## -----------------------------------------------------------------------
120function get_version()
121{
122 declare -n ref="$1"
123
124 banner
125 declare -a rev=()
126 rev+=("$(( RANDOM % 10 + 1 ))")
127 rev+=("$(( RANDOM % 256 + 1 ))")
Joey Armstrongeef8c2c2023-03-27 17:27:43 -0400128 rev+=("$(( RANDOM % 10000 + 1 ))")
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400129 ver="v${rev[0]}.${rev[1]}.${rev[2]}"
130
131 func_echo "version: $ver"
132 ref="$ver"
133 return
134}
135
136## -----------------------------------------------------------------------
137## Intent: Provide defaults for environment variables
138## -----------------------------------------------------------------------
139function initEnvVars()
140{
141 # when not running under Jenkins, use current dir as workspace and a blank
142 # project name
143 declare -g WORKSPACE=${WORKSPACE:-.}
144 declare -g GERRIT_PROJECT=${GERRIT_PROJECT:-}
145
146 # Github organization (or user) this project is published on. Project name should
147 # be the same on both Gerrit and GitHub
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400148 declare -g GITHUB_ORGANIZATION=${GITHUB_ORGANIZATION:-}
149
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400150 # glob pattern relative to project dir matching release artifacts
151 # ARTIFACT_GLOB=${ARTIFACT_GLOB:-"release/*"} # stat -- release/* not found, literal string (?)
152 declare -g ARTIFACT_GLOB=${ARTIFACT_GLOB:-"release/."}
153
154 # Use "release" as the default makefile target, can be a space separated list
155 declare -g RELEASE_TARGETS=${RELEASE_TARGETS:-release}
156
157 # Set and handle GOPATH and PATH
158 export GOPATH=${GOPATH:-$WORKSPACE/go}
159 export PATH=$PATH:/usr/lib/go-1.12/bin:/usr/local/go/bin:$GOPATH/bin
160 return
161}
162
163## -----------------------------------------------------------------------
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500164## Intent: Create a scratch area for downloads and transient tools
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400165## temp directory will be automatically removed upon exit.
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500166## -----------------------------------------------------------------------
167function init()
168{
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500169 local pkgbase="${0##*/}" # basename
170 local pkgname="${pkgbase%.*}"
171
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400172 # initEnvVars # moved to full_banner()
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400173
174 ## Create a temp directory for auto-cleanup
175 declare -g scratch
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500176 scratch="$(mktemp -d -t "${pkgname}.XXXXXXXXXX")"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400177 readonly scratch
178 declare -p scratch
179
180 ## prime the stream
181 local work
182 get_release_dir work
183 declare -p work
184 return
185}
186
187## -----------------------------------------------------------------------
188## Intent: Verbose output for logging
189## -----------------------------------------------------------------------
190function banner()
191{
192 local iam="${0##*/}"
193 cat <<EOB
194
195** -----------------------------------------------------------------------
196** ${iam}::${FUNCNAME[1]}: $*
197** -----------------------------------------------------------------------
198EOB
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500199}
200
201## -----------------------------------------------------------------------
Joey Armstrong7f382ef2023-01-25 12:00:08 -0500202## Intent: Output a log banner to identify the running script/version.
203## -----------------------------------------------------------------------
204## TODO:
205## o SCRIPT_VERSION => git changeset for repo:ci-managment
206## o echo "library version: ${env."library.libName.version"}"
207# -----------------------------------------------------------------------
208# 14:18:38 > git fetch --no-tags --progress -- https://gerrit.opencord.org/ci-management.git +refs/heads/*:refs/remotes/origin/* # timeout=10
209# 14:18:39 Checking out Revision 50f6e0b97f449b32d32ec0e02d59642000351847 (master)
210# -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400211function full_banner()
Joey Armstrong7f382ef2023-01-25 12:00:08 -0500212{
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400213 local iam="${0##*/}"
214
215 initEnvVars # set defaults
Joey Armstrong7f382ef2023-01-25 12:00:08 -0500216
217cat <<EOH
218
219** -----------------------------------------------------------------------
220** IAM: ${iam} :: ${FUNCNAME[0]}
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400221** ARGV: ${ARGV[@]}
Joey Armstrong7f382ef2023-01-25 12:00:08 -0500222** PWD: $(/bin/pwd)
223** NOW: $(date '+%Y/%m/%d %H:%M:%S')
224** VER: ${SCRIPT_VERSION:-'unknown'}
225** -----------------------------------------------------------------------
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400226** GERRIT_PROJECT: $(declare -p GERRIT_PROJECT)
227** GITHUB_ORGANIZATION: $(declare -p GITHUB_ORGANIZATION)
228** RELEASE_TARGETS: $(declare -p RELEASE_TARGETS)
229** GOPATH: $(declare -p GOPATH)
230** -----------------------------------------------------------------------
231** PATH += /usr/lib/go-1.12/bin:/usr/local/go/bin:GOPATH/bin
232** -----------------------------------------------------------------------
Joey Armstrong7f382ef2023-01-25 12:00:08 -0500233EOH
234
235 return
236}
237
Joey Armstrongaf577ab2022-12-15 14:43:33 -0500238## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400239## Intent: Display a message with 'iam' identifier for logging
Joey Armstrong50f6e0b2023-01-24 14:14:08 -0500240## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400241function func_echo()
Joey Armstrong1962bcf2023-01-27 13:53:18 -0500242{
243 local iam="${0##*/}"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400244 echo "** ${iam} :: ${FUNCNAME[1]}: $*"
Joey Armstrong1962bcf2023-01-27 13:53:18 -0500245 return
246}
247
248## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400249## Intent: Display an error message then exit with status.
250## -----------------------------------------------------------------------
251function error()
252{
253 local iam="${0##*/}"
254 echo "ERROR ${iam} :: ${FUNCNAME[1]}: $*"
255 exit 1
256}
257
258## -----------------------------------------------------------------------
259## Intent: Verify sandbox/build is versioned for release.
260## -----------------------------------------------------------------------
261function getGitVersion()
262{
263 declare -n varname="$1"; shift
264 local ver
265
266 banner
Joey Armstrong39fac652023-03-27 18:50:43 -0400267
268 ## [TODO] move to get_version()
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400269 ver="$(git tag -l --points-at HEAD)"
270 declare -p ver
Joey Armstrong39fac652023-03-27 18:50:43 -0400271 # get_version 'ver'
272 # declare -p ver
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400273
274 # ------------------------------------------------------
275 # match bare versions or v-prefixed golang style version
276 # Critical failure for new/yet-to-be-released repo ?
277 # ------------------------------------------------------
278 if [[ "$ver" =~ ^v?([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
279 then
280 echo "git has a SemVer released version tag: '$ver'"
281 echo "Building artifacts for GitHub release."
282 else
283 error "No SemVer released version tag found, exiting..."
284 fi
285
286 varname="$ver"
287 func_echo "GIT_VERSION is [$GIT_VERSION] from $(/bin/pwd)"
288 return
289}
290
291## -----------------------------------------------------------------------
292## Intent:
293## Note: Release description is sanitized version of the log message
294## -----------------------------------------------------------------------
295function getReleaseDescription()
296{
297 declare -n varname="$1"; shift
298
299 local msg
300 msg="$(git log -1 --pretty=%B)"
301
302 local val
303 val="$(tr -dc "[:alnum:]\n\r\.\[\]\:\-\\\/\`\' " <<< "$msg")"
304
305 [[ ${#val} -eq 0 ]] && error "Release Description is empty ($msg)"
306 varname="$val"
307 return
308}
309
310## -----------------------------------------------------------------------
311## Intent: Retrieve value of the release temp directory.
312## -----------------------------------------------------------------------
313## Note: Limit use of globals so logic can be isolated in function calls.
314## -----------------------------------------------------------------------
315# declare -g RELEASE_TEMP
316function get_release_dir()
317{
318 declare -n varname=$1; shift
319
320 # Temporary staging directory to copy artifacts to
321 varname="$scratch/release"
322 mkdir -p "$varname"
323 return
324}
325
326## -----------------------------------------------------------------------
327## Intent: Retrieve github server hostname
328## -----------------------------------------------------------------------
329function get_gh_hostname()
330{
331 declare -n varname=$1; shift
332 varname+=('--hostname' "${__githost}")
333 return
334}
335
336## -----------------------------------------------------------------------
337## Intent: Retrieve repository organizaiton name
338## -----------------------------------------------------------------------
339function get_gh_repo_org()
340{
341 declare -n varname=$1; shift
342 declare -g __repo_org
343
344 local org
345 if [[ -v __repo_org ]]; then
346 org="$__repo_org"
347 elif [[ ! -v GITHUB_ORGANIZATION ]]; then
348 error "--repo-org or GITHUB_ORGANIZATION= are required"
349 else
350 org="${GITHUB_ORGANIZATION}"
351 fi
352
353 # shellcheck disable=SC2178
354 varname="$org"
355 return
356}
357
358## -----------------------------------------------------------------------
359## Intent: Retrieve repository organizaiton name
360## -----------------------------------------------------------------------
361function get_gh_repo_name()
362{
363 declare -n varname=$1; shift
364 declare -g __repo_name
365
366 local name
367 if [[ -v __repo_name ]]; then
368 name="$__repo_name"
Joey Armstrong39fac652023-03-27 18:50:43 -0400369 elif [[ ! -v GERRIT_PROJECT ]]; then
370 error "--repo-name or GERRIT_PROJECT= are required"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400371 else
Joey Armstrong39fac652023-03-27 18:50:43 -0400372 name="${GERRIT_PROJECT}"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400373 fi
374
375 varname="$name"
376 return
377}
378
379## -----------------------------------------------------------------------
380## Intent: Return path for the gh release query
381## -----------------------------------------------------------------------
382function get_gh_releases()
383{
384 declare -n ref="$1"
385
386 local repo_org
387 get_gh_repo_org repo_org
388
389 local repo_name
390 get_gh_repo_name repo_name
391
392 ref="repos/${repo_org}/${repo_name}/releases"
393 func_echo "ref=$ref"
394 return
395}
396
397## -----------------------------------------------------------------------
398## Intent: Retrieve repository path argument
399## -----------------------------------------------------------------------
400function get_argv_repo()
401{
402 declare -n varname=$1; shift
403
404 local repo_org
405 get_gh_repo_org repo_org
406
407 local repo_name
408 get_gh_repo_name repo_name
409
410 varname="${repo_org}/${repo_name}"
411 func_echo "VARNAME=$varname"
412 return
413}
414
415## -----------------------------------------------------------------------
416## Intent: Retrieve release name string "project - version"
417## -----------------------------------------------------------------------
418function get_argv_name()
419{
420 declare -n varname=$1; shift
421
422 local repo_name
423 get_gh_repo_name repo_name
424 varname="${repo_name} - $GIT_VERSION"
425 func_echo "varname=$varname"
426 return
427}
428
429## -----------------------------------------------------------------------
430## Intent: Retrieve tag version
431## -----------------------------------------------------------------------
432function get_argv_tag()
433{
434 declare -n varname=$1; shift
435
436 # cached_argv_tag='v3.41.3204'
437 if [[ ! -v cached_argv_tag ]]; then
438 declare -g cached_argv_tag
439 if [[ -v GIT_VERSION ]]; then # hello jenkins
440 cached_argv_tag="$GIT_VERSION"
441 fi
442 fi
443
444 [[ ${#cached_argv_tag} -eq 0 ]] && error "Unable to determine GIT_VERSION="
445 varname="$cached_argv_tag"
446 func_echo "varname=$varname"
447 return
448}
449
450## -----------------------------------------------------------------------
451## Intent:
452## -----------------------------------------------------------------------
453# To support golang projects that require GOPATH to be set and code checked out there
454# If $DEST_GOPATH is not an empty string:
455# - create GOPATH within WORKSPACE, and destination directory within
456# - set PATH to include $GOPATH/bin and the system go binaries
457# - move project from $WORKSPACE/$GERRIT_PROJECT to new location in $GOPATH
458# - start release process within that directory
459## -----------------------------------------------------------------------
460function get_release_path()
461{
462 declare -n varname=$1; shift
463
464 DEST_GOPATH=${DEST_GOPATH:-}
465 if [ -n "$DEST_GOPATH" ]; then
466 # if [[ -v DEST_GOPATH ]] && [[ -n DEST_GOPATH ]]; then
467 ## [jenkins] Suspect this will taint the golang installation.
468 ## [jenkins] Install succeeds, release fails, next job affected due to corruption.
469 ## [jenkins] Copy golang to temp then augment ?
470 ## [jenkins] Worst case (problematic) backup then restore
471 mkdir -p "$GOPATH/src/$DEST_GOPATH"
472 varname="$GOPATH/src/$DEST_GOPATH/$GERRIT_PROJECT"
473 mv "$WORKSPACE/$GERRIT_PROJECT" "$varname"
474
475 ## [TODO] - support local dev use
476 # elif [[ ! -v WORKSPACE ]] && [[ -d '.git' ]]; then
477 # project=$(git remote -v show | awk -F' ' '{print $2}' | xargs basename)
478 # project=voltctl.git
479
480 else
481 varname="$WORKSPACE/$GERRIT_PROJECT"
482 fi
483
484 if [ ! -f "$varname/Makefile" ]; then
485 :
486 elif [ ! -f "$varname/makefile" ]; then
487 :
488 else
489 error "Makefile not found at $varname!"
490 fi
491
492 return
493}
494
495## -----------------------------------------------------------------------
496## Intent: Display future enhancements
497## -----------------------------------------------------------------------
498function todo()
499{
500 local iam="${0##*/}"
501
502cat <<EOT
503
504** -----------------------------------------------------------------------
505** IAM: ${iam} :: ${FUNCNAME[0]}
506** -----------------------------------------------------------------------
507 o get_release_path()
508 - refactor redundant paths into local vars.
509 - see comments, do we have a one-off failure condition ?
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400510 o PATH += golang appended 3 times, release needs a single, reliable answer.
511 o do_login, do_logout and api calls do not use the my_gh wrapper:
512 - Add a lookup function to cache and retrieve path to downloaded gh command.
513
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400514EOT
515
516 return
517}
518
519## -----------------------------------------------------------------------
520## Intent: Copy files from the build directory into the release staging
521## directory for publishing to github releases/ endpoint.
Joey Armstrong26707f02023-01-26 12:41:12 -0500522## -----------------------------------------------------------------------
523function copyToRelease()
524{
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400525 func_echo "ENTER"
Joey Armstrong26707f02023-01-26 12:41:12 -0500526
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400527 local artifact_glob="${ARTIFACT_GLOB%/*}"
528 func_echo "$(declare -p artifact_glob)"
529
530 local work
531 get_release_dir work
532
533 ## Flatten filesystem, should we recurse here to release subdirs ?
Joey Armstrong472bfba2023-03-27 18:12:28 -0400534 #cp $(which ls) "$work"
Joey Armstrong472bfba2023-03-27 18:12:28 -0400535 readarray -t artifacts < <(find "$work" -type f)
536 func_echo "$(declare -p artifacts)"
537
Joey Armstrong39fac652023-03-27 18:50:43 -0400538 [[ ${#artifacts[@]} -eq 0 ]] && error "Artifact dir is empty, check for build failures in $artifact_glob"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400539
Joey Armstrong26707f02023-01-26 12:41:12 -0500540 # Copy artifacts into the release temp dir
541 # shellcheck disable=SC2086
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400542 echo "rsync -rv --checksum \"$artifact_glob/.\" \"$work/.\""
543 rsync -rv --checksum "$artifact_glob/." "$work/."
Joey Armstrong1962bcf2023-01-27 13:53:18 -0500544
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400545 func_echo "LEAVE"
Joey Armstrong26707f02023-01-26 12:41:12 -0500546
Joey Armstrong26707f02023-01-26 12:41:12 -0500547 return
548}
549
550## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400551## https://docs.github.com/en/rest/releases?apiVersion=2022-11-28
552 # https://cli.github.com/manual/gh_release_create
553 # --target <branch> or commit SHA
554 # --title
555 # --generate-notes
556 # --release-notes (notes file)
557 # --release
558 # release create dist/*.tgz
559 # --discussion-category "General"
Joey Armstrongf085d872023-01-28 17:52:29 -0500560## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400561# https://cli.github.com/manual/gh_release_create
562## -----------------------------------------------------------------------
563function gh_release_create()
Joey Armstrong38bfeea2023-02-06 18:01:29 -0500564{
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400565 banner ''
Joey Armstrong38bfeea2023-02-06 18:01:29 -0500566
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400567 local version="$GIT_VERSION"
568# get_version 'version'
569# create_release_by_version "$version"
Joey Armstrong38bfeea2023-02-06 18:01:29 -0500570
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400571 declare -a args=()
572 args+=('--host-repo')
573 args+=('--notes' "'Testing release create -- ignore'")
574 args+=('--title')
575 if [[ -v draft_release ]]; then
576 args+=('--draft')
577 else
578 args+=('--discussion-category' 'Announcements')
579 fi
Joey Armstrong38bfeea2023-02-06 18:01:29 -0500580
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400581 local work
582 get_release_dir work
583
584 # pushd "$work" >/dev/null
585 readarray -t payload < <(find "$work" ! -type d -print)
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400586 func_echo "$gh_cmd release create ${version} ${args[@]}" "${payload[@]}"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400587 my_gh 'release' 'create' "'$version'" "${args[@]}" "${payload[@]}"
588 # popd >/dev/null
589
Joey Armstrong38bfeea2023-02-06 18:01:29 -0500590 return
591}
592
593## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400594## Intent: Authenticate credentials for a github gh session
Joey Armstrong38bfeea2023-02-06 18:01:29 -0500595## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400596## NOTE: my_gh currently unused due to --with-token < "$pac"
597## -----------------------------------------------------------------------
598function do_login()
Joey Armstrongf085d872023-01-28 17:52:29 -0500599{
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400600 declare -g pac
Joey Armstrong485081f2023-03-27 13:34:08 -0400601 declare -a login_args=()
602 [[ $# -gt 0 ]] && login_args+=("$@")
Joey Armstrongf085d872023-01-28 17:52:29 -0500603
Joey Armstronge6e18eb2023-03-27 14:19:21 -0400604 func_echo "$(declare -p WORKSPACE)"
605
Joey Armstrong485081f2023-03-27 13:34:08 -0400606 # https://github.com/cli/cli/issues/2922#issuecomment-775027762
607 # (sigh) why not quietly return VS forcing a special case
Joey Armstronge6e18eb2023-03-27 14:19:21 -0400608 # [[ -v WORKSPACE ]] && [[ -v GITHUB_TOKEN ]] && return
609
610# 12:58:36 ** -----------------------------------------------------------------------
611# 12:58:36 ** jenkins582353203049151829.sh::do_login: --hostname github.com
612# 12:58:36 ** --------------------------------------------------------------------# ---
613# 12:58:36 ** jenkins582353203049151829.sh :: do_login: Detected ENV{GITHUB_TOKEN}=
614# 12:58:36 The value of the GITHUB_TOKEN environment variable is being used for authentication.
615# 12:58:36 To have GitHub CLI store credentials instead, first clear the value from the environment.
616 return
Joey Armstrong485081f2023-03-27 13:34:08 -0400617
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400618 # bridge to my_gh()
Joey Armstrong485081f2023-03-27 13:34:08 -0400619 get_gh_hostname login_args
Joey Armstrongf085d872023-01-28 17:52:29 -0500620
Joey Armstrong485081f2023-03-27 13:34:08 -0400621 banner "${login_args[@]}"
Joey Armstrongf085d872023-01-28 17:52:29 -0500622
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400623 ## Read from disk is safer than export GITHUB_TOKEN=
624 if [[ -v pac ]] && [[ ${#pac} -gt 0 ]]; then # interactive/debugging
625 [ ! -f "$pac" ] && error "PAC token file $pac does not exist"
626 # func_echo "--token file is $pac"
Joey Armstrong485081f2023-03-27 13:34:08 -0400627 "$gh_cmd" auth login "${login_args[@]}" --with-token < "$pac"
Joey Armstrongf085d872023-01-28 17:52:29 -0500628
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400629 elif [[ ! -v GITHUB_TOKEN ]]; then
630 error "--token [t] or GITHUB_TOKEN= are required"
Joey Armstrong41923cc2023-01-30 14:38:16 -0500631
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400632 else # jenkins
633 func_echo 'Detected ENV{GITHUB_TOKEN}='
Joey Armstrong485081f2023-03-27 13:34:08 -0400634 "$gh_cmd" auth login "${login_args[@]}"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400635 fi
Joey Armstrongf085d872023-01-28 17:52:29 -0500636
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400637 declare -i -g active_login=1 # signal logout
Joey Armstrongf085d872023-01-28 17:52:29 -0500638
Joey Armstrongf085d872023-01-28 17:52:29 -0500639 return
640}
641
642## -----------------------------------------------------------------------
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400643## Intent: Destroy credentials/gh session authenticated by do_login
644## -----------------------------------------------------------------------
645## NOTE: my_gh currently unused due to "<<< 'y'"
646## -----------------------------------------------------------------------
647function do_logout()
648{
649 declare -i -g active_login
650 [[ ! -v active_login ]] && return
651
652 declare -a out_args=()
653 [[ $# -gt 0 ]] && out_args+=("$@")
654
655 # bridge to my_gh()
656
657 get_gh_hostname in_args
658
659 banner "${out_args[@]}"
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400660 "$gh_cmd" auth logout "${out_args[@]}" <<< 'Y'
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400661
662 unset active_login
663 return
664}
665
666## -----------------------------------------------------------------------
667## Intent: Query for repository version strings
668## -----------------------------------------------------------------------
669function get_releases()
670{
671 declare -n ref="$1"; shift
672 local func="${FUNCNAME[0]}"
673
674 banner ""
675 pushd "$scratch" >/dev/null
676
677 # gh api repos/{owner}/{repo}/releases
678 local releases_uri
679 get_gh_releases releases_uri
680 declare -p releases_uri
681
682 ref=()
Joey Armstrongad7b1e02023-03-27 11:55:48 -0400683 "$gh_cmd" api "$releases_uri" "${common[@]}" | jq . > 'release.raw'
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400684 readarray -t __tmp < <(jq '.[] | "\(.tag_name)"' 'release.raw')
685
686 local release
687 for release in "${__tmp[@]}";
688 do
689 release="${release//\"/}"
690 ref+=("$release")
691 done
692
693 popd >/dev/null
694 return
695}
696
697## -----------------------------------------------------------------------
698## Intent: Display repository query strings.
699## Indirect: verify authentication and API
700## -----------------------------------------------------------------------
701function showReleases()
702{
703 declare -a releases=()
704 get_releases releases
705
706 local release
707 for release in "${releases[@]}";
708 do
709 func_echo "$release"
710 done
711 return
712}
713
714## -----------------------------------------------------------------------
715## Intent: Install the gh command line tool locally
Joey Armstrong26707f02023-01-26 12:41:12 -0500716## -----------------------------------------------------------------------
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500717function install_gh_binary()
Joey Armstrong26707f02023-01-26 12:41:12 -0500718{
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400719 banner
Joey Armstrong26707f02023-01-26 12:41:12 -0500720
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500721 pushd "$scratch"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400722 func_echo "Retrieve latest gh download URLs"
Joey Armstrongf085d872023-01-28 17:52:29 -0500723
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500724 local latest="https://github.com/cli/cli/releases/latest"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400725 local tarball="gh.tar.tgz"
726
727 readarray -t latest < <(curl --silent -qI "$latest" \
728 | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}')
729 declare -p latest
730 if [ ${#latest[@]} -ne 1 ]; then
731 error "Unable to determine latest gh package version"
732 fi
733
734 local VER="${latest[0]}"
735
736 func_echo "Download latest gh binary"
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500737 local url="https://github.com/cli/cli/releases/download/${VER}/gh_${VER#v}_linux_amd64.tar.gz"
738 wget --quiet --output-document="$tarball" "$url"
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400739
740 func_echo "Unpack tarball"
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500741 tar zxf "$tarball"
742
743 gh_cmd="$(find "${scratch}" -name 'gh' -print)"
744 readonly gh_cmd
745
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400746 func_echo "Command: ${gh_cmd}"
747 func_echo "Version: $("$gh_cmd" --version)"
Joey Armstrongd99e3d22023-01-29 12:35:43 -0500748 popd
749
Joey Armstrong2097d3e2023-03-26 10:32:03 -0400750 return
751}
752
753## -----------------------------------------------------------------------
754## Intent: Danger Will Robinson
755## -----------------------------------------------------------------------
756function releaseDelete()
757{
758 local version="$1"; shift
759
760 banner "${in_args[@]}"
761 declare -a args=()
762 args+=('--host-repo')
763 args+=('--yes')
764 # args+=('--cleanup-tag')
765
766# ** github-release.sh :: get_argv_repo: VARNAME=opencord/voltctl
767#* Running: /tmp/github-release.R7geZo7Ywo/gh_2.25.1_linux_amd64/bin/gh release delete v4.175.710 --repo 'github.com/opencord/voltctl' --yes --cleanup-tag
768#rror connecting to 'github.com
769#heck your internet connection or https://githubstatus.com
770
771 echo
772 echo "==========================================================================="
773 my_gh 'release' 'delete' "$version" "${args[@]}"
774 echo "==========================================================================="
775 echo
776
777 showReleases
778 return
779}
780
781## -----------------------------------------------------------------------
782## Intent: Copy binaries into temp/release, checksum then publish
783## -----------------------------------------------------------------------
784function release_staging()
785{
786 local release_temp
787 get_release_dir release_temp
788
789 banner ''
790 func_echo "Packaging release files"
791 # pushd "$RELEASE_TEMP"
792 pushd "$release_temp" >/dev/null || error "pushd failed: dir is [$release_temp]"
793
794 readarray -t to_release < <(find . -mindepth 1 -maxdepth 1 -type f -print)
795 func_echo "Files to release: $(declare -p to_release)"
796
797 # Generate and check checksums
798 sha256sum -- * > checksum.SHA256
799 sha256sum -c < checksum.SHA256
800
801 echo
802 func_echo "Checksums(checksum.SHA256):"
803 cat checksum.SHA256
804
805 ## ARGS NEEDED
806 gh_release_create
807
808 popd >/dev/null || error "pushd failed: dir is [$release_temp]"
809
810 return
811}
812
813## -----------------------------------------------------------------------
814## Intent: Display program usage
815## -----------------------------------------------------------------------
816function usage()
817{
818 [[ $# -gt 0 ]] && func_echo "$*"
819
820 cat <<EOH
821Usage: github-release.sh [options] [target] ...
822
823[Github CLI (gh) arguments]
824 --login Perform authentication using a PAC
825 --logout
826 --host [h] Specify github server for connection.
827
828[Options]
829 --token Login debugging, alternative to env var use.
830
831[Modes]
832 --debug Enable script debug mode
833 --verbose Enable script verbose mode
834
835All remaining arguments are passthrough to the gh command.
836EOH
837
838 exit 0
839}
840
841## -----------------------------------------------------------------------
842## Intent: Provide common arguments and access to the gh command.
843## o Cache path to the gh command
844## o Construct a gh command line from given args
845## o Command wrapper can provide defaults (--hostname github.com)
846## -----------------------------------------------------------------------
847## Given:
848## scalar Array variable name (declare -n is a reference)
849## Return:
850## ref gh command line passed back to caller
851## Switches:
852## --host Pass default github hostname
853## --verbose Enable verbose mode#
854## --version Display command version
855## @array Remaining arguments passed as command switches.
856## -----------------------------------------------------------------------
857## See Also:
858## o https://cli.github.com/manual
859## -----------------------------------------------------------------------
860function my_gh()
861{
862 ## ------------------------
863 ## Cache path to gh command
864 ## ------------------------
865 if [[ ! -v gh_cmd ]]; then
866 readarray -t cmds < <(which -a gh)
867 declare -p cmds
868 if [ ${#cmds} -eq 0 ]; then
869 error "Unable to locate the gh command"
870 fi
871 gh_cmd="${cmds[0]}"
872 readonly gh_cmd
873 fi
874
875 declare -a cmd=()
876 cmd+=("$gh_cmd")
877
878 ## ----------------------
879 ## Construct command line
880 ## ----------------------
881 # shellcheck disable=SC2034
882 declare -A action=() # pending operations
883 declare -a args=() # common gh command line args
884
885 while [ $# -gt 0 ]; do
886 local arg="$1"; shift
887 case "$arg" in
888
889 # Modes
890 -*debug) declare -i -g debug=1 ;;
891 -*help) show_help ;;
892 -*verbose) args+=('--verbose') ;;
893
894 -*hostname)
895 get_gh_hostname in_args
896 ;;
897
898 --host-repo)
899 local val
900 get_argv_repo val
901
902 # --repo <[HOST/]OWNER/REPO>
903 args+=('--repo' "'${__githost}/${val}'")
904 ;;
905
906 --repo)
907 local val
908 get_argv_repo val
909 args+=('--repo' "$val")
910 ;;
911
912 --tag)
913 local val
914 get_argv_tag val
915 args+=("'$val'") # No switch, pass inline
916 ;;
917
918 --title)
919 local val
920 get_argv_name val
921 args+=('--title' "'$val'")
922 ;;
923
924 # --draft
925 # --latest
926 *) args+=("$arg") ;;
927 esac
928 done
929
930 cmd+=("${args[@]}")
931 echo "** Running: ${cmd[*]}"
932 "${cmd[@]}"
933 local status=$?
934
935 [[ $status -eq 0 ]] && { true; } || { false; }
936 return
937}
938
939## ---------------------------------------------------------------------------
940## Intent:
941## ---------------------------------------------------------------------------
942function usage()
943{
944 cat <<EOH
945
946Usage: $0
947Usage: make [options] [target] ...
948 --help This mesage
949 --pac Personal Access Token (file)
950
951[DEBUG]
952 --gen-version Generate a random release version string.
953 --git-hostname Git server hostname (default=github.com)
954
955EOH
956 return
957}
958
959## ---------------------------------------------------------------------------
960## Intent: Parse script command line arguments
961## ---------------------------------------------------------------------------
962function parse_args()
963{
964 # declare -n ref="$1"; shift
965
966 [[ -v DEBUG ]] && func_echo "ENTER"
967
968# ref="repos/${__repo_user}/${__repo_name}/releases"
969
970 while [ $# -gt 0 ]; do
971 local arg="$1"; shift
972 case "$arg" in
973 -*gen-version)
974 get_version GIT_VERSION
975 ;;
976
977 -*git-hostname)
978 __githost="$1"; shift
979 ;;
980
981 -*repo-name)
982 __repo_name="$1"; shift
983 ;;
984
985 -*repo-org)
986 __repo_org="$1"; shift
987 ;;
988
989 -*pac)
990 declare -g pac="$1"; shift
991 readonly pac
992 [[ ! -f "$pac" ]] && error "--token= does not exist ($pac)"
993 : # nop/true
994 ;;
995
996 -*help)
997 usage
998 exit 0
999 ;;
1000 *) error "Detected unknown argument $arg" ;;
1001 esac
1002 done
1003
Joey Armstrong26707f02023-01-26 12:41:12 -05001004 return
1005}
1006
Joey Armstrongaf577ab2022-12-15 14:43:33 -05001007##----------------##
1008##---] MAIN [---##
1009##----------------##
Joey Armstrong1962bcf2023-01-27 13:53:18 -05001010iam="${0##*/}"
1011
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001012full_banner
1013parse_args $@
Joey Armstrongd99e3d22023-01-29 12:35:43 -05001014init
1015install_gh_binary
Joey Armstrong7f382ef2023-01-25 12:00:08 -05001016
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001017do_login
Zack Williams27cd3e52018-09-18 16:44:50 -07001018
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001019release_path='/dev/null'
1020get_release_path release_path
1021declare -p release_path
Zack Williams27cd3e52018-09-18 16:44:50 -07001022
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001023pushd "$release_path" || error "pushd failed: dir is [$release_path]"
Zack Williams27cd3e52018-09-18 16:44:50 -07001024
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001025 # legacy: getGitVersion "$GERRIT_PROJECT" GIT_VERSION
1026 getGitVersion GIT_VERSION
1027 getReleaseDescription RELEASE_DESCRIPTION
Zack Williams27cd3e52018-09-18 16:44:50 -07001028
Joey Armstrongeef8c2c2023-03-27 17:27:43 -04001029 cat <<EOM
1030
1031** -----------------------------------------------------------------------
1032** GIT VERSION: $(declare -p GIT_VERSION)
1033** RELEASE_DESCRIPTION: $(declare -p RELEASE_DESCRIPTION)
1034** RELEASE_TARGETS: $(declare -p RELEASE_TARGETS)
1035** make release
1036** -----------------------------------------------------------------------
1037EOM
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001038 # build the release, can be multiple space separated targets
1039 # -----------------------------------------------------------------------
1040 # % go build command-line-arguments:
1041 # copying /tmp/go-build4212845548/b001/exe/a.out:
1042 # open release/voltctl-1.8.25-linux-amd64: permission denied
1043 # missing: docker run mkdir
1044 # -----------------------------------------------------------------------
1045 # shellcheck disable=SC2086
Joey Armstrongeef8c2c2023-03-27 17:27:43 -04001046 make "$RELEASE_TARGETS"
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001047 copyToRelease
Joey Armstrong50f6e0b2023-01-24 14:14:08 -05001048
Joey Armstrong26707f02023-01-26 12:41:12 -05001049 cat <<EOM
Joey Armstrong1962bcf2023-01-27 13:53:18 -05001050
1051** -----------------------------------------------------------------------
1052** Create the release:
1053** 1) Create initial github release with download area.
1054** 2) Generate checksum.SHA256 for all released files.
1055** 3) Upload files to complete the release.
1056** 4) Display released info from github.
1057** -----------------------------------------------------------------------
Joey Armstrong26707f02023-01-26 12:41:12 -05001058EOM
1059
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001060 showReleases
1061 # releaseDelete 'v4.175.710'
1062 release_staging
1063 popd || error "pushd failed: dir is [$release_path]"
Zack Williams27cd3e52018-09-18 16:44:50 -07001064fi
Joey Armstrong28eddda2023-01-10 03:09:34 -05001065
Joey Armstrong2097d3e2023-03-26 10:32:03 -04001066do_logout
1067
Joey Armstrong28eddda2023-01-10 03:09:34 -05001068# [SEE ALSO]
1069# -----------------------------------------------------------------------
1070# https://www.shellcheck.net/wiki/SC2236
Joey Armstrong26707f02023-01-26 12:41:12 -05001071# https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release
Joey Armstrong28eddda2023-01-10 03:09:34 -05001072# -----------------------------------------------------------------------
Joey Armstrongf085d872023-01-28 17:52:29 -05001073# https://cli.github.com/manual/gh_help_reference
1074# https://cli.github.com/manual/gh_release
1075# -----------------------------------------------------------------------
Joey Armstrong28eddda2023-01-10 03:09:34 -05001076
1077# [EOF]