diff --git a/README.md b/README.md index 37797b3..74d3844 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ These are all the options available to configure this plugin's behaviour. ### Required -#### `files` (string) +#### `files` (string or array of strings) -Pattern of files to upload to Test Analytics, relative to the checkout path (`./` will be added to it). May contain `*` to match any number of characters of any type (unlike shell expansions, it will match `/` and `.` if necessary). +One or more patterns of files to upload to Test Analytics, relative to the root of the searching path (`./` by default). May contain `*` to match any number of characters of any type (unlike shell expansions, it will match `/` and `.` if necessary). Can be either a single pattern in a string or any number of them in an array. #### `format` (string) @@ -87,7 +87,7 @@ steps: - label: "🔨 Test" command: "make test" plugins: - - test-collector#v1.6.0: + - test-collector#v1.7.0: files: "test/junit-*.xml" format: "junit" ``` @@ -101,8 +101,9 @@ steps: - label: "🔨 Test" command: "make test" plugins: - - test-collector#v1.6.0: - files: "test-data-*.json" + - test-collector#v1.7.0: + files: + - "test-data-*.json" format: "json" ``` @@ -122,7 +123,7 @@ steps: - label: "🔍 Test Analytics" command: buildkite-agent artifact download tests-*.xml plugins: - - test-collector#v1.6.0: + - test-collector#v1.7.0: files: "tests-*.xml" format: "junit" ``` @@ -136,7 +137,7 @@ steps: - label: "🔨 Test" command: "make test" plugins: - - test-collector#v1.6.0: + - test-collector#v1.7.0: files: "test-data-*.json" format: "json" branches: "-qa$" @@ -149,7 +150,7 @@ steps: - label: "🔨 Test" command: "make test" plugins: - - test-collector#v1.6.0: + - test-collector#v1.7.0: files: "test-data-*.json" format: "json" exclude-branches: "^legacy$" @@ -162,7 +163,7 @@ steps: - label: "🔨 Test" command: "make test" plugins: - - test-collector#v1.6.0: + - test-collector#v1.7.0: files: "test-data-*.json" format: "json" branches: "^stage-" diff --git a/hooks/pre-exit b/hooks/pre-exit index ae7c2e5..75fe3c2 100755 --- a/hooks/pre-exit +++ b/hooks/pre-exit @@ -2,7 +2,6 @@ set -euo pipefail TOKEN_ENV_NAME="${BUILDKITE_PLUGIN_TEST_COLLECTOR_API_TOKEN_ENV_NAME:-BUILDKITE_ANALYTICS_TOKEN}" -FILES_PATTERN="${BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES:-}" FORMAT="${BUILDKITE_PLUGIN_TEST_COLLECTOR_FORMAT:-}" TIMEOUT="${BUILDKITE_PLUGIN_TEST_COLLECTOR_TIMEOUT:-30}" BASE_PATH="${BUILDKITE_PLUGIN_TEST_COLLECTOR_BASE_PATH:-.}" @@ -31,6 +30,16 @@ fi TOKEN_VALUE="${!TOKEN_ENV_NAME:-}" PLUGIN_VERSION=$(git rev-parse --short HEAD 2>/dev/null || echo "") +if [[ -z "${TOKEN_VALUE}" ]]; then + echo "Missing $TOKEN_ENV_NAME environment variable" + exit 1 +fi + +if [[ -z "${FORMAT}" ]]; then + echo "Missing file format 'format'. Possible values: 'junit', 'json'" + exit 1 +fi + # Uploads files to the Test Analytics API # # Upload failures should not fail the build, and should have a sensible timeout, @@ -78,43 +87,52 @@ upload() { curl "${curl_args[@]}" } -if [[ -z "${TOKEN_VALUE}" ]]; then - echo "Missing $TOKEN_ENV_NAME environment variable" - exit 1 -fi +# Runs the whole plugin logic for a particular find pattern +find_and_upload() { + FILES_PATTERN="$1" + FIND_CMD=(find) -if [[ -z "${FILES_PATTERN}" ]]; then - echo "Missing file upload pattern 'files', e.g. 'junit-*.xml'" - exit 1 -fi - -if [[ -z "${FORMAT}" ]]; then - echo "Missing file format 'format'. Possible values: 'junit', 'json'" - exit 1 -fi + if [[ "${BUILDKITE_PLUGIN_TEST_COLLECTOR_FOLLOW_SYMLINKS:-}" =~ ^(true|on|1|always)$ ]]; then + FIND_CMD+=('-L') + fi -FIND_CMD=(find) + matching_files=() + while IFS=$'' read -r matching_file ; do + matching_files+=("$matching_file") + done < <("${FIND_CMD[@]}" "${BASE_PATH}" -path "${BASE_PATH}/${FILES_PATTERN}") -if [[ "${BUILDKITE_PLUGIN_TEST_COLLECTOR_FOLLOW_SYMLINKS:-}" =~ ^(true|on|1|always)$ ]]; then - FIND_CMD+=('-L') -fi - -matching_files=() -while IFS=$'' read -r matching_file ; do - matching_files+=("$matching_file") -done < <("${FIND_CMD[@]}" "${BASE_PATH}" -path "${BASE_PATH}/${FILES_PATTERN}") + if [[ "${#matching_files[@]}" -eq "0" ]]; then + echo "No files found matching '${FILES_PATTERN}'" + if [[ "${BUILDKITE_COMMAND_EXIT_STATUS:-0}" -eq "0" ]]; then + exit 1 + fi + else + # needs to be part of else for bash4.3 compatibility + for file in "${matching_files[@]}"; do + echo "Uploading '$file'..." + if ! upload "$TOKEN_VALUE" "$FORMAT" "${file}"; then + echo "Error uploading, will continue" + fi + done + fi +} -if [[ "${#matching_files[@]}" -eq "0" ]]; then - echo "No files found matching '${FILES_PATTERN}'" - if [[ "${BUILDKITE_COMMAND_EXIT_STATUS:-0}" -eq "0" ]]; then - exit 1 +if [ -n "${BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES:-}" ]; then + find_and_upload "${BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES}" +elif [ -n "${BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES_0:-}" ]; then + prefix="BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES" + parameter="${prefix}_0" + + if [ -n "${!parameter:-}" ]; then + i=0 + parameter="${prefix}_${i}" + while [ -n "${!parameter:-}" ]; do + find_and_upload "${!parameter}" + i=$((i+1)) + parameter="${prefix}_${i}" + done fi else - # needs to be part of else for bash4.3 compatibility - for file in "${matching_files[@]}"; do - echo "Uploading '$file'..." - if ! upload "$TOKEN_VALUE" "$FORMAT" "${file}"; then - echo "Error uploading, will continue" - fi - done + echo "Missing file upload pattern 'files', e.g. 'junit-*.xml'" + exit 1 fi \ No newline at end of file diff --git a/plugin.yml b/plugin.yml index 1422f40..9bfd2bc 100644 --- a/plugin.yml +++ b/plugin.yml @@ -18,7 +18,11 @@ configuration: exclude-branches: type: string files: - type: string + oneOf: + - type: string + - type: array + items: + type: string follow-symlinks: type: boolean format: diff --git a/tests/pre-exit-errors.bats b/tests/pre-exit-errors.bats index cf787ec..c7b70a2 100644 --- a/tests/pre-exit-errors.bats +++ b/tests/pre-exit-errors.bats @@ -22,6 +22,7 @@ setup() { @test "Errors with no 'files' set" { export BUILDKITE_ANALYTICS_TOKEN='abc' + export BUILDKITE_PLUGIN_TEST_COLLECTOR_FORMAT='junit' run "$PWD/hooks/pre-exit" assert_failure diff --git a/tests/pre-exit-success.bats b/tests/pre-exit-success.bats index 2d27772..93635c8 100644 --- a/tests/pre-exit-success.bats +++ b/tests/pre-exit-success.bats @@ -54,6 +54,43 @@ COMMON_CURL_OPTIONS='--form \* --form \* --form \* --form \* --form \* --form \* assert_output --partial "curl success 2" } +@test "Single file pattern through array" { + export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES_0='**/*/junit-1.xml' + unset BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES + + stub curl \ + "-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} \* -H \* : echo 'curl success 1'" + + run "$PWD/hooks/pre-exit" + + assert_success + assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..." + refute_output --partial "Uploading './tests/fixtures/junit-2.xml'..." + assert_output --partial "curl success 1" + + unstub curl +} + +@test "Multiple file pattern through array" { + export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES_0="*/fixtures/*-1.xml" + export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES_1="*/fixtures/*-2.xml" + unset BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES + + stub curl \ + "-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} \* -H \* : echo 'curl success 1'" \ + "-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} \* -H \* : echo 'curl success 2'" + + run "$PWD/hooks/pre-exit" + + assert_success + assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..." + assert_output --partial "Uploading './tests/fixtures/junit-2.xml'..." + assert_output --partial "curl success 1" + assert_output --partial "curl success 2" + + unstub curl +} + @test "Debug true prints the curl info w/o token" { export BUILDKITE_PLUGIN_TEST_COLLECTOR_DEBUG="true"