· 5 years ago · Oct 09, 2020, 06:44 PM
1#!/bin/bash
2usage() {
3 cat <<-USAGE
4 Deploy file to Artifactory
5
6 usage: ${0##*/} [-h] FILE HOST TARGET_DIR
7
8 positional parameters:
9 FILE local file path
10 HOST Artifactory host, e.g. \`artifactory.example.com:5040\`
11 TARGET_DIR
12 remote directory including project key e.g. \`PROJECT/subdir\`
13
14 optional arguments:
15 -h show this text
16
17 required environment variables:
18 ARTIFACTORY_API_KEY Artifactory API key
19
20 DEPENDENCIES
21 - curl
22 - \`coreutils\` or \`openssl\` for calculating local checksums to be able to
23 verify upload integrity.
24 USAGE
25}
26
27declare -r F_BOLD=$(tput bold)
28declare -r F_RESET=$(tput sgr0)
29declare -r F_RED=$(tput setaf 1)
30declare -r F_GREEN=$(tput setaf 2)
31declare -r F_BLUE=$(tput setaf 4)
32declare -r F_MAGENTA=$(tput setaf 5)
33
34declare -r ICON_START="$F_BOLD${F_BLUE}▸$F_RESET"
35declare -r ICON_DONE="$F_BOLD${F_GREEN}✔$F_RESET"
36declare -r ICON_ERROR="$F_BOLD${F_RED}✘$F_RESET"
37
38# Log script output.
39log() { printf '%b%s%b: %s\n' "$F_MAGENTA" "${0##*/}" "$F_RESET" "$1"; }
40
41# Log wrappers.
42log_error() { log "$ICON_ERROR $F_BOLD${F_RED}error$F_RESET: $1" 1>&2; }
43_log_task() { log "$1 $F_BOLD$2$F_RESET"; }
44log_start() { _log_task "$ICON_START" "$1"; }
45log_done() { _log_task "$ICON_DONE" "$1"; }
46
47# Return whether arguments are executable programs in path.
48has() { for i; do command -v "$i" >/dev/null || return 1; done; }
49
50main() {
51 while getopts 'h' option; do
52 case $option in
53 h ) usage; return 2;;
54 \? ) usage; return 2;;
55 esac
56 done
57 shift $((OPTIND - 1))
58 (($# != 3)) && { usage; return 2; }
59
60 if [[ -z $ARTIFACTORY_API_KEY ]]; then
61 usage
62 log_error 'could not read API key'
63 return 2
64 fi
65
66 local -r local_file=$1
67 local -r host=$2
68 local -r target_dir=$3
69
70 [[ ! -f $local_file ]] && \
71 { log_error "local file \`$local_file\` does not exist"; return 1; }
72
73 log_start 'Calculating checksums'
74 local md5 sha1 sha256
75 if has sha256sum sha1sum md5sum; then
76 log 'Using coreutils'
77 log '- Calculating MD5'
78 md5=$(md5sum "$local_file")
79 md5=${md5:0:32}
80 log '- Calculating SHA-1'
81 sha1=$(sha1sum "$local_file")
82 sha1=${sha1:0:40}
83 log '- Calculating SHA-256'
84 sha256=$(sha256sum "$local_file")
85 sha256=${sha256:0:65}
86 elif has openssl; then
87 log 'Using openssl'
88 log '- Calculating MD5'
89 md5=$(openssl dgst -md5 "$local_file")
90 md5=${md5##*)= }
91 log '- Calculating SHA-1'
92 sha1=$(openssl dgst -sha1 "$local_file")
93 sha1=${sha1##*)= }
94 log '- Calculating SHA-256'
95 sha256=$(openssl dgst -sha256 "$local_file")
96 sha256=${sha256##*)= }
97 else
98 log_error 'need `coreutils` or `openssl` to calculate checksums'
99 return 3
100 fi
101 log_done 'Checksums calculated.'
102
103 local -r filename=${local_file##*/}
104 local -r upload_target="https://${host}/artifactory/$target_dir/$filename"
105 log 'Metadata:'
106 log "- Local file $local_file"
107 log "- MD5 $md5"
108 log "- SHA-1 $sha1"
109 log "- SHA-256 $sha256"
110 log "- Remote target $upload_target"
111
112 log_start 'Sending request'
113 curl \
114 --include \
115 --request PUT \
116 --user ":$ARTIFACTORY_API_KEY" \
117 --fail \
118 --header "X-Checksum-Md5: $md5" \
119 --header "X-Checksum-Sha1: $sha1" \
120 --header "X-Checksum-Sha256: $sha256" \
121 --upload-file "$local_file" \
122 "$upload_target" \
123 | tee /dev/null
124 local -ri curl_rc=${PIPESTATUS[0]}
125 echo
126 ((curl_rc)) && { log_error "error: curl failed with return code $curl_rc"; return $curl_rc; }
127 log_done 'Upload complete'
128 local -r artifact_url="https://$host/artifactory/webapp/#/artifacts/browse/tree/General/$target_dir/$filename"
129 log "Browse the artifact at $artifact_url"
130}
131
132main "$@"