Skip to content

Commit 29b9d86

Browse files
authored
Merge pull request #106 from buildkite-plugins/toote_expand_vars
Expand vars option
2 parents b09c8fb + 40ed953 commit 29b9d86

8 files changed

Lines changed: 488 additions & 83 deletions

File tree

README.md

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ steps:
3131
- command: ...
3232
plugins:
3333
- artifacts#v1.9.4:
34-
upload:
34+
upload:
3535
- from: log1.log
3636
to: log2.log
3737
```
@@ -91,7 +91,7 @@ steps:
9191
- command: ...
9292
plugins:
9393
- artifacts#v1.9.4:
94-
download:
94+
download:
9595
- from: log1.log
9696
to: log2.log
9797
```
@@ -105,7 +105,7 @@ steps:
105105
- artifacts#v1.9.4:
106106
step: UUID-DEFAULT
107107
build: UUID-DEFAULT-2
108-
download:
108+
download:
109109
- from: log1.log
110110
to: log2.log
111111
step: UUID-1
@@ -114,25 +114,25 @@ steps:
114114
build: UUID-2
115115
```
116116
117-
## Configuration
117+
## Mandatory Configuration
118118
119-
### `upload` (string, array of strings, {from,to}, array of {from,to})
120-
121-
A glob pattern, or array of glob patterns, for files to upload.
119+
You must specify at least one of the following
122120
123121
### `download` (string, array of strings, {from,to}, array of {from,to[,step][,build]})
124122

125-
A glob pattern, or array of glob patterns, for files to download.
123+
A glob pattern, or array of glob patterns, for files to download. Alternatively you can specify `from` and `to` to rename the artifact after downloading. If you do so, you can also specify `step` and/or `build` to override those options for that particular artifact.
124+
125+
### `upload` (string, array of strings, {from,to}, array of {from,to})
126126

127-
### `step` (optional, string)
127+
A glob pattern, or array of glob patterns, for files to upload as-is. Alternatively, you can specify `from` and `to` to rename the artifact before uploading.
128128

129-
The job UUID or name to download the artifacts from unless specified otherwise in the `download` array specification.
129+
## Other Configuration
130130

131-
### `build` (optional, string)
131+
### `build` (string, download only)
132132

133-
The build UUID to download the artifact from unless specificed otherwise in the `download` array specification.
133+
The build UUID to download all artifacts from. Note that you can override it for specific artifacts when using the verbose format of the `download` element.
134134

135-
### `compressed` (optional, string)
135+
### `compressed` (string)
136136

137137
⚠️ Limitations:
138138
* filename needs to end with `.zip` or `.tgz` and that will determine the compression executable to use
@@ -161,11 +161,23 @@ steps:
161161
compressed: logs.tgz
162162
```
163163

164-
### `ignore-missing` (optional, boolean)
164+
### `expand-download-vars` (boolean, **unsafe**, download only)
165+
166+
When set to true, it will activate interpolation of variables in the elements of the `download` path-related configurations as well as `compressed` option if present. When turned off (the default), attempting to use variables will fail as the literal `$VARIABLE_NAME` string will be used.
167+
168+
⚠️ Important: this is considered an unsafe option as the most compatible way to achieve this is to run the strings through `eval` which could lead to arbitrary code execution or information leaking if you don't have complete control of the pipeline.
169+
170+
### `expand-upload-vars` (boolean, **unsafe**, download only)
171+
172+
When set to true, it will activate interpolation of variables in the elements of the `upload` path-related configurations as well as `compressed` option if present. When turned off (the default), attempting to use variables will fail as the literal `$VARIABLE_NAME` string will be used.
173+
174+
⚠️ Important: this is considered an unsafe option as the most compatible way to achieve this is to run the strings through `eval` which could lead to arbitrary code execution or information leaking if you don't have complete control of the pipeline.
175+
176+
### `ignore-missing` (boolean)
165177

166178
If set to `true`, it will ignore errors caused when calling `buildkite-agent artifact` to prevent failures if you expect artifacts not to be present in some situations. When using the `compressed` property, it will ignore compressing the artifacts that are not present.
167179

168-
### `skip-on-status` (optional, integer or array of integers, uploads only)
180+
### `skip-on-status` (integer or array of integers, upload only)
169181

170182
You can set this to the exit codes or array of exit codes of the command step (as defined by the `BUILDKITE_COMMAND_EXIT_STATUS` variable) that will cause the plugin to avoid trying to upload artifacts.
171183

@@ -195,6 +207,10 @@ steps:
195207
- 5
196208
```
197209

210+
### `step` (string, download only)
211+
212+
The job UUID or name to download all artifacts from. Note that you can override it for specific artifacts when using the verbose format of the `download` element.
213+
198214
## Developing
199215

200216
To run testing, shellchecks and plugin linting use use `bk run` with the [Buildkite CLI](https://github.com/buildkite/cli).

hooks/post-command

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ if [[ "${BUILDKITE_PLUGIN_ARTIFACTS_DEBUG:-false}" =~ (true|on|1) ]] ; then
66
set -x
77
fi
88

9+
10+
# expand variables in the variable name referenced
11+
# DANGEROUS due to the use of eval
12+
# assumes that the environment variable name exists
13+
expand_vars() {
14+
if [[ ${BUILDKITE_PLUGIN_ARTIFACTS_EXPAND_UPLOAD_VARS:-false} != "false" ]]; then
15+
# expand the variable
16+
eval echo "${!1}"
17+
else
18+
echo "${!1}"
19+
fi
20+
}
21+
922
while IFS='=' read -r EXIT_VAR _ ; do
1023
if [[ $EXIT_VAR =~ ^(BUILDKITE_PLUGIN_ARTIFACTS_SKIP_ON_STATUS(|_[0-9]+))$ ]]; then
1124
if [ "${BUILDKITE_COMMAND_EXIT_STATUS}" -eq "${!EXIT_VAR}" ]; then
@@ -55,9 +68,9 @@ if [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED:-}" ]]; then
5568
COMPRESSED="true"
5669

5770
if [[ "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}" =~ .*\.zip ]]; then
58-
compress+=("zip" "-r" "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}")
71+
compress+=("zip" "-r")
5972
elif [[ "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}" =~ .*\.tgz ]]; then
60-
compress+=("tar" "czf" "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}")
73+
compress+=("tar" "czf")
6174
else
6275
echo "+++ 🚨 The inferred compression file format for the artifact is not currently supported"
6376
exit 1
@@ -66,8 +79,8 @@ fi
6679

6780
workdir=${BUILDKITE_PLUGIN_ARTIFACTS_WORKDIR:-.}
6881

69-
pushd "${workdir}"
70-
trap popd EXIT
82+
pushd "${workdir}" > /dev/null
83+
trap "popd > /dev/null" EXIT
7184

7285
bk_agent() {
7386
if ! buildkite-agent artifact "${@}"; then
@@ -91,11 +104,14 @@ handle_relocation() {
91104
dest_env_var="BUILDKITE_PLUGIN_ARTIFACTS_UPLOAD_${var_string}TO"
92105

93106
if [[ -n "${!source_env_var:-}" ]] && [[ -n "${!dest_env_var:-}" ]]; then
94-
if [[ -e ${!source_env_var} ]]; then
95-
echo "~~~ Moving [${!source_env_var}] to [${!dest_env_var}]..."
96-
mv "${!source_env_var}" "${!dest_env_var}"
107+
SOURCE_FILE="$(expand_vars "${source_env_var}")"
108+
DEST_FILE="$(expand_vars "${dest_env_var}")"
109+
110+
if [[ -e "${SOURCE_FILE}" ]]; then
111+
echo "~~~ Moving [${SOURCE_FILE}] to [${DEST_FILE}]..."
112+
mv "${SOURCE_FILE}" "${DEST_FILE}"
97113
elif [[ ${BUILDKITE_PLUGIN_ARTIFACTS_IGNORE_MISSING:-"false"} == "true" ]]; then
98-
echo "Ignoring missing file ${!source_env_var} for relocation"
114+
echo "Ignoring missing file ${SOURCE_FILE} for relocation"
99115
fi
100116
fi
101117
}
@@ -121,42 +137,49 @@ fi
121137
if [[ "${SINGULAR_UPLOAD_OBJECT}" == "true" ]]; then
122138
if [[ "${RELOCATION}" == "true" ]]; then
123139
handle_relocation ""
124-
path="${BUILDKITE_PLUGIN_ARTIFACTS_UPLOAD_TO}"
140+
path="$(expand_vars BUILDKITE_PLUGIN_ARTIFACTS_UPLOAD_TO)"
125141
else
126-
path="${paths[0]}"
142+
export FILENAME="${paths[0]}"
143+
path="$(expand_vars FILENAME)"
127144
fi
128145

129146
if [[ "${COMPRESSED}" == "true" ]]; then
130-
echo "~~~ Compressing ${path} to ${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}"
147+
COMPRESSED_FILENAME="$(expand_vars BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED)"
148+
echo "~~~ Compressing ${path} to ${COMPRESSED_FILENAME}"
131149
if [[ ! -e "${path}" ]]; then
132150
echo "+++ 🚨 Unable to compress artifact, '${path}' may not exist or is an empty directory"
133151
else
134-
"${compress[@]}" "${path}"
135-
path=" ${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}"
152+
"${compress[@]}" "${COMPRESSED_FILENAME}" "${path}"
153+
path="${COMPRESSED_FILENAME}"
136154
fi
137155
fi
138156

139157
echo "~~~ Uploading artifacts ${EXTRA_MESSAGE}"
140158
bk_agent "${args[@]}" "${path}"
141159
elif [[ "${COMPRESSED}" == "true" ]]; then
160+
COMPRESSED_FILENAME="$(expand_vars BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED)"
142161
final_paths=()
143162
index=0
144163
for path in "${paths[@]}"; do
145164
handle_relocation "${index}"
146165
dest_env_var="BUILDKITE_PLUGIN_ARTIFACTS_UPLOAD_${index}_TO"
147166
if [[ -n "${!dest_env_var:-}" ]]; then
148-
path="${!dest_env_var}"
167+
path="$(expand_vars "${dest_env_var}")"
168+
else
169+
# could use $path directly, but would break the ordering because 0,1,10,11,2,20,3 :(
170+
# may be solved by using sort -V but it is GNU-specific
171+
path="$(expand_vars "BUILDKITE_PLUGIN_ARTIFACTS_UPLOAD_${index}")"
149172
fi
150173

151174
final_paths+=("$path")
152175
((index+=1))
153176
done
154177

155-
echo "~~~ Compressing ${final_paths[*]} to ${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}"
178+
echo "~~~ Compressing ${final_paths[*]} to ${COMPRESSED_FILENAME}"
156179
"${compress[@]}" "${final_paths[@]}"
157180

158181
echo "~~~ Uploading artifacts ${EXTRA_MESSAGE}"
159-
bk_agent "${args[@]}" "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}"
182+
bk_agent "${args[@]}" "${COMPRESSED_FILENAME}"
160183
elif [[ "${MULTIPLE_UPLOADS}" == "true" ]]; then
161184
index=0
162185
echo "~~~ Uploading artifacts ${EXTRA_MESSAGE}"
@@ -165,7 +188,9 @@ elif [[ "${MULTIPLE_UPLOADS}" == "true" ]]; then
165188
handle_relocation "${index}"
166189
dest_env_var="BUILDKITE_PLUGIN_ARTIFACTS_UPLOAD_${index}_TO"
167190
if [[ -n "${!dest_env_var:-}" ]]; then
168-
path="${!dest_env_var}"
191+
path="$(expand_vars "${dest_env_var}")"
192+
else
193+
path="$(expand_vars path)"
169194
fi
170195

171196
bk_agent "${args[@]}" "$path"

hooks/pre-command

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,33 @@ compress=()
1414

1515
COMPRESSED="false"
1616
SINGULAR_DOWNLOAD_OBJECT="false"
17-
RELOCATION="false"
1817
MULTIPLE_DOWNLOADS="false"
1918

19+
# expand variables in the variable name referenced
20+
# DANGEROUS due to the use of eval
21+
# assumes that the environment variable name exists
22+
expand_vars() {
23+
if [[ ${BUILDKITE_PLUGIN_ARTIFACTS_EXPAND_DOWNLOAD_VARS:-false} != "false" ]]; then
24+
# expand the variable
25+
eval echo "${!1}"
26+
else
27+
echo "${!1}"
28+
fi
29+
}
30+
2031
if [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD:-}" ]] || { [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_FROM:-}" ]] && [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_TO:-}" ]]; }; then
2132
SINGULAR_DOWNLOAD_OBJECT="true"
2233
if [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD:-}" ]] ; then
23-
paths+=("$BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD")
34+
paths+=("$(expand_vars BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD)")
2435
elif [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_FROM:-}" ]] && [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_TO:-}" ]] ; then
25-
RELOCATION="true"
26-
paths+=("$BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_FROM")
36+
paths+=("$(expand_vars BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_FROM)")
2737
fi
2838
fi
2939

3040
while IFS='=' read -r path _ ; do
3141
if [[ $path =~ ^(BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_[0-9]+)$ ]] || [[ $path =~ ^(BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_[0-9]+_FROM)$ ]]; then
3242
MULTIPLE_DOWNLOADS="true"
33-
paths+=("${!path}")
43+
paths+=("$(expand_vars "${path}")")
3444
fi
3545
done < <(env | sort)
3646

@@ -87,25 +97,28 @@ handle_relocation() {
8797
source_env_var="BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_${var_string}FROM"
8898
dest_env_var="BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_${var_string}TO"
8999
if [[ -n "${!dest_env_var:-}" ]]; then
90-
if ! [[ -d $(dirname "${!dest_env_var}") ]]; then
91-
mkdir -p "$(dirname "${!dest_env_var}")"
100+
SOURCE_FILE="$(expand_vars "${source_env_var}")"
101+
DEST_FILE="$(expand_vars "${dest_env_var}")"
102+
if ! [[ -d "$(dirname "${DEST_FILE}")" ]]; then
103+
mkdir -p "$(dirname "${DEST_FILE}")"
92104
fi
93105

94-
if [[ ! -e "${!source_env_var}" ]] && [[ ${BUILDKITE_PLUGIN_ARTIFACTS_IGNORE_MISSING:-"false"} != "false" ]]; then
95-
echo "Ignoring missing file ${!source_env_var} for relocation"
106+
if [[ ! -e "${SOURCE_FILE}" ]] && [[ ${BUILDKITE_PLUGIN_ARTIFACTS_IGNORE_MISSING:-"false"} != "false" ]]; then
107+
echo "Ignoring missing file ${SOURCE_FILE} for relocation"
96108
else
97-
echo "~~~ Moving [${!source_env_var}] to [${!dest_env_var}]..."
98-
mv "${!source_env_var}" "${!dest_env_var}"
109+
echo "~~~ Moving [${SOURCE_FILE}] to [${DEST_FILE}]..."
110+
mv "${SOURCE_FILE}" "${DEST_FILE}"
99111
fi
100112
fi
101113
}
102114

103115
if [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED:-}" ]]; then
104116
COMPRESSED="true"
105-
if [[ "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}" =~ .*\.zip ]]; then
106-
compress+=("unzip" "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}")
107-
elif [[ "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}" =~ .*\.tgz ]]; then
108-
compress+=("tar" "xzf" "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}")
117+
COMPRESSED_FILENAME="$(expand_vars BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED)"
118+
if [[ "${COMPRESSED_FILENAME}" =~ .*\.zip ]]; then
119+
compress+=("unzip" "${COMPRESSED_FILENAME}")
120+
elif [[ "${COMPRESSED_FILENAME}" =~ .*\.tgz ]]; then
121+
compress+=("tar" "xzf" "${COMPRESSED_FILENAME}")
109122
else
110123
echo "+++ 🚨 The inferred compression file format for the artifact is not currently supported"
111124
exit 1
@@ -115,16 +128,14 @@ fi
115128
workdir="${BUILDKITE_PLUGIN_ARTIFACTS_WORKDIR:-.}"
116129

117130
if [[ "${COMPRESSED}" == "true" ]]; then
118-
if ! bk_agent "${step_option}" "${build_option}" "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}" "${workdir}"; then
119-
handle_bk_error "${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}"
131+
if ! bk_agent "${step_option}" "${build_option}" "${COMPRESSED_FILENAME}" "${workdir}"; then
132+
handle_bk_error "${COMPRESSED_FILENAME}"
120133
else
121-
echo "~~~ Uncompressing ${paths[*]} from ${BUILDKITE_PLUGIN_ARTIFACTS_COMPRESSED}"
134+
echo "~~~ Uncompressing ${paths[*]} from ${COMPRESSED_FILENAME}"
122135
"${compress[@]}" "${paths[@]}"
123136

124137
# single relocation
125-
if [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_TO:-}" ]]; then
126-
handle_relocation ""
127-
fi
138+
handle_relocation ""
128139

129140
# multiple relocations
130141
index=0
@@ -135,35 +146,32 @@ if [[ "${COMPRESSED}" == "true" ]]; then
135146
fi
136147

137148
elif [[ "${SINGULAR_DOWNLOAD_OBJECT}" == "true" ]]; then
138-
if [[ "${RELOCATION}" == "true" ]]; then
139-
source="${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_FROM}"
140-
else
141-
source="${paths[*]}"
142-
fi
149+
source="${paths[*]}"
143150

144151
if ! bk_agent "${step_option}" "${build_option}" "${source}" "${workdir}"; then
145152
handle_bk_error "${source}"
146153
else
147-
if [[ -n "${BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_TO:-}" ]]; then
148-
handle_relocation ""
149-
fi
154+
handle_relocation ""
150155
fi
151156
elif [[ "${MULTIPLE_DOWNLOADS}" == "true" ]]; then
152157
index=0
153158

154159
for path in "${paths[@]}"; do
155-
source_env_var="BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_${index}_FROM"
156-
dest_env_var="BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_${index}_TO"
157-
step_env_var="BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_${index}_STEP"
158-
build_env_var="BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_${index}_BUILD"
159-
160-
# finally get the artifact to download
161-
if [ -n "${!source_env_var:-}" ] && [ -n "${!dest_env_var:-}" ]; then
162-
source="${!source_env_var}"
160+
env_var_base="BUILDKITE_PLUGIN_ARTIFACTS_DOWNLOAD_${index}"
161+
dest_env_var="${env_var_base}_TO"
162+
step_env_var="${env_var_base}_STEP"
163+
build_env_var="${env_var_base}_BUILD"
164+
165+
# could use $path directly, but would break the ordering because 0,1,10,11,2,20,3 :(
166+
# may be solved by using sort -V but it is GNU-specific
167+
if [ -z "${!env_var_base:-}" ]; then
168+
source_env_var="${env_var_base}_FROM"
163169
else
164-
source="${path}"
170+
source_env_var="${env_var_base}"
165171
fi
166172

173+
source="$(expand_vars "${source_env_var}")"
174+
167175
if ! bk_agent "${!step_env_var:-${step_option}}" "${!build_env_var:-${build_option}}" "${source}" "${workdir}"; then
168176
handle_bk_error "${source}"
169177
else

plugin.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,17 @@ configuration:
5858
- type: array
5959
items:
6060
type: integer
61+
expand-download-vars:
62+
type: boolean
63+
expand-upload-vars:
64+
type: boolean
6165
oneOf:
6266
- required:
6367
- upload
6468
- required:
6569
- download
6670
dependencies:
6771
skip-on-status: [ upload ]
72+
expand-download-vars: [ download ]
73+
expand-upload-vars: [ upload ]
6874
additionalProperties: false

0 commit comments

Comments
 (0)