Skip to content

Instantly share code, notes, and snippets.

@allex
Last active June 5, 2024 01:25
Show Gist options
  • Save allex/88b3f45dde15b7aa88916c81fca3cf0c to your computer and use it in GitHub Desktop.
Save allex/88b3f45dde15b7aa88916c81fca3cf0c to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -eu
# Helper cli command for upload artifacts to depot server
# by @allex_wang
#
# GistID: 88b3f45dde15b7aa88916c81fca3cf0c
# GistURL: https://gist.github.com/88b3f45dde15b7aa88916c81fca3cf0c
PROG=$(basename "$0")
WORKDIR="$(umask 0077; mktemp -d)"
handle_exit() {
local ec="$?"
# declare -F on_exit, not avaiable in alipine/sh
if type on_exit >/dev/null 2>&1; then on_exit; fi
local tmpDir=${TMP:-${TMPDIR:-/tmp/}}
if [ "${WORKDIR##${tmpDir%%/}/*}" != "${WORKDIR}" ]; then
rm -rf "${WORKDIR--}"
else
warn "For security, The \$WORKDIR:${WORKDIR} not allot at system tmpdir, will not be cleanup"
fi
trap - INT TERM EXIT
exit $ec
}
trap handle_exit 0 1 2 3 6 15
### Helpers {{{
BOLD="$(tput bold 2>/dev/null || echo '')"
GREY="$(tput setaf 0 2>/dev/null || echo '')"
UNDERLINE="$(tput smul 2>/dev/null || echo '')"
RED="$(tput setaf 1 2>/dev/null || echo '')"
GREEN="$(tput setaf 2 2>/dev/null || echo '')"
YELLOW="$(tput setaf 3 2>/dev/null || echo '')"
BLUE="$(tput setaf 4 2>/dev/null || echo '')"
MAGENTA="$(tput setaf 5 2>/dev/null || echo '')"
CYAN="$(tput setaf 6 2>/dev/null || echo '')"
NO_COLOR="$(tput sgr0 2>/dev/null || echo '')"
info() { printf "${BOLD}${GREY}>${NO_COLOR} %s\n" "$*"; }
warn() { printf "${YELLOW}! %s${NO_COLOR}\n" "$*" >&2; }
error() { printf "${RED}x %s${NO_COLOR}\n" "$*" >&2; }
complete() { printf "${GREEN}✓${NO_COLOR} %s\n" "$*"; }
die() { [ "${1-}" ] && error "fatal: ${1}"; exit "${2-1}"; }
assert() { [ -n "$1" ] || die "${2?assert message required}"; }
has() { type "${1:?command required}" >/dev/null 2>&1; }
### }}}
evaluate_glob() {
(shopt -s nullglob;eval "echo $*")
}
showhelp() {
cat <<-EOF
Usage: $PROG --path <FILE> --destpath <DESTDIR>
Options:
--path | --file Target file(s) to upload. Supports multiple files, e.g., --path a.js --path b.js. Globs are expanded.
--destpath Destination path for file upload.
--token Authentication token for the depot. Defaults to the 'DEPOT_TOKEN' environment variable, if set.
--overwrite Enable overwrite in single file mode.
Environment variables:
DEPOT_TOKEN Authentication token for the depot. Can also be set with the --token argument.
DEPOT_ENDPOINT URL of the depot for uploading files. Defaults to 'https://depot.tidu.io'.
EOF
exit 1
}
# usage: cmd_upload_artifacts [ --path <file>, ] --destpath <path>
main () {
local paths=()
local destpath=
local overwrite=
local token=${DEPOT_TOKEN-}
local depot_endpoint=${DEPOT_ENDPOINT:-https://depot.tidu.io}
if [ $# -eq 0 ]; then
showhelp
fi
while (( "$#" )); do
case "$1" in
# target files to upload, support multiple path, eg: --path a.js --path b.js
--path | --file)
# shellcheck disable=SC2207
# append to the paths array
paths+=($(evaluate_glob "$2")) # expand glob if needed
shift 2
;;
# For sigle file mode, the 'destpath' been used for placing the uploaded file
# and when in multiple files mode, the 'destpath' will be use as as a base directory, files will be extracted in it
--destpath)
# normalize destpath, strip prefix `/`
destpath=${2##/}
shift 2
;;
# specify the depot token, default to use env variable ${DEPOT_TOKEN}
--token)
token=$$2
shift 2
;;
# enable overwrite in single file mode
--overwrite)
overwrite=1
shift
;;
-h | --help)
showhelp
;;
*)
showhelp
;;
esac
done
if [ -z "$destpath" ]; then
die "destpath not valid (--destpath)"
fi
local file_num source_file curl_args tmp_file
file_num=${#paths[@]}
multi=0
# 'destpath' as a directory with suffix `/`, handle as multi mode
if [ "${destpath%%/}" != "$destpath" ]; then
multi=1
if (( file_num == 1 )); then
die "uploading single file, the '--destpath' value should not be end with '/'"
fi
else
if (( file_num > 1 )); then
die "uploading multi files, the '--destpath' value should be end with '/'"
fi
fi
if (( file_num == 0 )); then
die "at least one path (--path <FILE>) is required"
else
if [ "$multi" == "1" ]; then
# create an archive file out of all the paths
tmp_file="$(mktemp -p "$WORKDIR").tar"
tar cvf "$tmp_file" "${paths[@]}"
source_file=$tmp_file
# multiple mode with destpath, will auto extract all files to destpath
curl_args="$depot_endpoint/upload?Dest-Dir=$destpath&extract=true"
else
source_file="${paths[0]}"
curl_args="-XPUT $depot_endpoint/files/${destpath}${overwrite:+?overwrite=true}"
fi
fi
if [ -z "$source_file" ] || [ ! -f "$source_file" ]; then
die "invalid source file"
fi
# shellcheck disable=SC2086
curl \
-F"file=@${source_file};type=$(file --mime-type -b "$source_file")" \
-H "PRIVATE-TOKEN: $token" \
${curl_args}
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment