Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: buildkite-plugins/test-collector-buildkite-plugin
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.2.0
Choose a base ref
...
head repository: buildkite-plugins/test-collector-buildkite-plugin
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.3.0
Choose a head ref
  • 9 commits
  • 5 files changed
  • 4 contributors

Commits on Dec 14, 2022

  1. Copy the full SHA
    a807eae View commit details

Commits on Dec 15, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    bfcfcce View commit details
  2. Copy the full SHA
    c5a0ea0 View commit details
  3. Copy the full SHA
    e3cf1e4 View commit details
  4. Added tests for new options

    toote committed Dec 15, 2022
    Copy the full SHA
    21b7dee View commit details
  5. Remove docker dependency

    toote committed Dec 15, 2022
    Copy the full SHA
    3ef7f8c View commit details
  6. Fix JUnit/JSON mismatch

    Uploading a JUnit file or a JSON file? 🤔
    DrJosh9000 authored Dec 15, 2022
    Copy the full SHA
    ebbab4b View commit details
  7. Merge pull request #29 from DrJosh9000/patch-1

    Fix JUnit/JSON mismatch
    toote authored Dec 15, 2022
    Copy the full SHA
    1a573c2 View commit details

Commits on Dec 16, 2022

  1. Copy the full SHA
    46e6127 View commit details
Showing with 367 additions and 20 deletions.
  1. +110 −15 README.md
  2. +14 −0 hooks/pre-exit
  3. +8 −5 plugin.yml
  4. +127 −0 tests/branches.bats
  5. +108 −0 tests/exclude-branches.bats
125 changes: 110 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -2,11 +2,73 @@

A Buildkite plugin for uploading [JSON](https://buildkite.com/docs/test-analytics/importing-json) or [JUnit](https://buildkite.com/docs/test-analytics/importing-junit-xml) files to [Buildkite Test Analytics](https://buildkite.com/test-analytics)

## Example
## Options

These are all the options available to configure this plugin's behaviour.

### Required

#### `files` (string)

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)

#### `format` (string)

Format of the file.

Only the following values are allowed: `junit`, `json`

### Optional

#### `api-token-env-name` (string)

Name of the environment variable that contains the Test Analytics API token.

Default value: `BUILDKITE_ANALYTICS_TOKEN`

#### `branches` (string)

String containing a regex to only do an upload in branches that match it (using the case-insensitive bash `=~` operator against the `BUILDKITE_BRANCH` environment variable).

For example:
* `prod` will match any branch name that **contains the substring** `prod`
* `^stage-` will match all branches that start with `stage-`
* `-ISSUE-[0-9]*$` will match branches that end with `ISSUE-X` (where X is any number)

Important: you may have to be careful to escape special characters like `$` during pipeline upload

#### `debug` (boolean)

Print debug information to the build output.

Default value: `false`.

Can also be enabled with the environment variable `BUILDKITE_ANALYTICS_DEBUG_ENABLED`.

#### `exclude-branches` (string)

String containing a regex avoid doing an upload in branches that match it (using the case-insensitive bash `=~` operator against the `BUILDKITE_BRANCH` environment variable ).

For example:
* `prod` will exclude any branch name that **contains the substring** `prod`
* `^stage-` will exclude all branches that start with `stage-`
* `-SECURITY-[0-9]*$` will exclude branches that end with `SECURITY-X` (where X is any number)

Important:
* you may have to be careful to escape special characters like `$` during pipeline upload
* exclusion of branches is done after the inclusion (through the [`branches` option](#branches-string))

#### `timeout`(number)

Maximum number of seconds to wait for each file to upload before timing out.

Default value: `30`

## Examples

### Upload a JUnit file

To upload a JSON file to Test Analytics from a build step:
To upload a JUnit file to Test Analytics from a build step:

```yaml
steps:
@@ -32,9 +94,9 @@ steps:
format: "json"
```
<!-- ### Upload a build artifact
### Using build artifacts
You can also upload build artifact that was generated in a previous step:
You can also use build artifacts generated in a previous step:
```yaml
steps:
@@ -45,23 +107,56 @@ steps:

- wait

- label: "🔍 Upload tests"
- label: "🔍 Test Analytics"
command: buildkite-agent artifact download tests-*.xml
plugins:
- buildkite/test-collector#main:
- test-collector#v1.2.0:
files: "tests-*.xml"
format: "junit"
artifact: true
``` -->
```
### Branch filtering
## Properties
Only upload on the branches that end with `-qa`

* `files` — Required — String — 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)
* `format` — Required — String — Format of the file. Possible values: `"junit"`, `"json"`
* `api-token-env-name` — Optional — String — Name of the environment variable that contains the Test Analytics API token. Default value: `"BUILDKITE_ANALYTICS_TOKEN"`
* `timeout` — Optional — Number — Maximum number of seconds to wait for each file to upload before timing out. Default value: `30`
* `debug` — Optional — Boolean — Print debug information to the build output. Default value: `false`. Can also be enabled with the environment variable `BUILDKITE_ANALYTICS_DEBUG_ENABLED`.
```yaml
steps:
- label: "🔨 Test"
command: "make test"
plugins:
- test-collector#v1.2.0:
files: "test-data-*.json"
format: "json"
branches: "-qa$"
```

Do not upload on the branch that is exactly named `legacy`:

```yaml
steps:
- label: "🔨 Test"
command: "make test"
plugins:
- test-collector#v1.2.0:
files: "test-data-*.json"
format: "json"
exclude-branches: "^legacy$"
```

Only upload on branches that start with `stage-` but do not contain `hotfix`

```yaml
steps:
- label: "🔨 Test"
command: "make test"
plugins:
- test-collector#v1.2.0:
files: "test-data-*.json"
format: "json"
branches: "^stage-"
exclude-branches: "hotfix"
```

<!-- * `artifact` — Optional — Boolean — Search for the files as build artifacts. Default value: `false` -->

## ⚒ Developing

14 changes: 14 additions & 0 deletions hooks/pre-exit
Original file line number Diff line number Diff line change
@@ -17,6 +17,20 @@ elif [[ "${BUILDKITE_ANALYTICS_DEBUG_ENABLED:-}" =~ ^(true|on|1|always)$ ]]; the
DEBUG="true"
fi

if [[ -n "${BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES:-}" ]]; then
if [[ ! "${BUILDKITE_BRANCH}" =~ ${BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES} ]]; then
echo "Branch ${BUILDKITE_BRANCH} does not match selector ${BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES}. Skipping it."
exit 0
fi
fi

if [[ -n "${BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES:-}" ]]; then
if [[ "${BUILDKITE_BRANCH}" =~ ${BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES} ]]; then
echo "Branch ${BUILDKITE_BRANCH} matches exclude selector ${BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES}. Skipping it."
exit 0
fi
fi

TOKEN_VALUE=$(eval "echo \${$TOKEN_ENV_NAME:-}")
PLUGIN_VERSION=$(git rev-parse --short HEAD 2>/dev/null || echo "")

13 changes: 8 additions & 5 deletions plugin.yml
Original file line number Diff line number Diff line change
@@ -2,20 +2,23 @@ name: Test Collector
description: Uploads your JSON or JUnit files to Buildkite Test Analytics
author: https://github.com/buildkite
requirements:
- docker
- curl
configuration:
properties:
api-token-env-name:
type: string
branches:
type: string
debug:
type: boolean
exclude-branches:
type: string
files:
type: string
format:
enum:
- json
- junit
api-token-env-name:
type: string
debug:
type: boolean
timeout:
type: integer
required:
127 changes: 127 additions & 0 deletions tests/branches.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env bats

# To debug stubs, uncomment these lines:
# export CURL_STUB_DEBUG=/dev/tty
# export GIT_STUB_DEBUG=/dev/tty

CURL_DEFAULT_STUB='\* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*'

setup() {
load "$BATS_PLUGIN_PATH/load.bash"
export BUILDKITE_PLUGIN_TEST_COLLECTOR_API_TOKEN_ENV_NAME=""

# Mandatory Config
export BUILDKITE_ANALYTICS_TOKEN='a-secret-analytics-token'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES='**/*/junit-1.xml'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FORMAT='junit'
# Build env
export BUILDKITE_BUILD_ID="an-id"
export BUILDKITE_BUILD_URL="https://url.com/"
export BUILDKITE_BRANCH="a-branch"
export BUILDKITE_COMMIT="a-commit"
export BUILDKITE_BUILD_NUMBER="123"
export BUILDKITE_JOB_ID="321"
export BUILDKITE_MESSAGE="A message"
}

@test "branches string specific, do nothing" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES='no-branch'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch does not match selector"
assert_output --partial "Skipping it."
}

@test "branches does not match, do nothing" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES='no-.*'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch does not match selector"
assert_output --partial "Skipping it."
}

@test "branches match exactly" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES='a-branch'

stub git "rev-parse --short HEAD : echo 'some-commit-id'"
stub curl "${CURL_DEFAULT_STUB} : echo 'curl success'"

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "curl success"
refute_output --partial "Branch a-branch does not match selector"
refute_output --partial "Skipping it."

unstub curl
unstub git
}

@test "branches match prefix" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES='^a-br'

stub git "rev-parse --short HEAD : echo 'some-commit-id'"
stub curl "${CURL_DEFAULT_STUB} : echo 'curl success'"

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "curl success"
refute_output --partial "Branch a-branch does not match selector"
refute_output --partial "Skipping it."

unstub curl
unstub git
}

@test "branches match suffix" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES='anch$'

stub git "rev-parse --short HEAD : echo 'some-commit-id'"
stub curl "${CURL_DEFAULT_STUB} : echo 'curl success'"

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "curl success"
refute_output --partial "Branch a-branch does not match selector"
refute_output --partial "Skipping it."

unstub curl
unstub git
}

@test "branches match regex" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES='^.*-b[ra]*n.*'

stub git "rev-parse --short HEAD : echo 'some-commit-id'"
stub curl "${CURL_DEFAULT_STUB} : echo 'curl success'"

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "curl success"
refute_output --partial "Branch a-branch does not match selector"
refute_output --partial "Skipping it."

unstub curl
unstub git
}

@test "branches does not match regex, do nothing" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_BRANCHES='^.*-b[er]*n.*'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch does not match selector"
assert_output --partial "Skipping it."
}
108 changes: 108 additions & 0 deletions tests/exclude-branches.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/usr/bin/env bats

# To debug stubs, uncomment these lines:
# export CURL_STUB_DEBUG=/dev/tty
# export GIT_STUB_DEBUG=/dev/tty

CURL_DEFAULT_STUB='\* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*'

setup() {
load "$BATS_PLUGIN_PATH/load.bash"
export BUILDKITE_PLUGIN_TEST_COLLECTOR_API_TOKEN_ENV_NAME=""

# Mandatory Config
export BUILDKITE_ANALYTICS_TOKEN='a-secret-analytics-token'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES='**/*/junit-1.xml'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FORMAT='junit'
# Build env
export BUILDKITE_BUILD_ID="an-id"
export BUILDKITE_BUILD_URL="https://url.com/"
export BUILDKITE_BRANCH="a-branch"
export BUILDKITE_COMMIT="a-commit"
export BUILDKITE_BUILD_NUMBER="123"
export BUILDKITE_JOB_ID="321"
export BUILDKITE_MESSAGE="A message"
}

@test "exclude specific matches string" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES='an'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch matches exclude selector"
assert_output --partial "Skipping it."
}

@test "exclude matches string exactly" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES='a-branch'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch matches exclude selector"
assert_output --partial "Skipping it."
}

@test "exclude does not match" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES='x'

stub git "rev-parse --short HEAD : echo 'some-commit-id'"
stub curl "${CURL_DEFAULT_STUB} : echo 'curl success'"

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "curl success"
refute_output --partial "Branch a-branch matches exclude selector"
refute_output --partial "Skipping it."

unstub curl
unstub git
}

@test "exclude matches prefix" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES='^a-br'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch matches exclude selector"
assert_output --partial "Skipping it."
}

@test "exclude matches suffix" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES='anch$'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch matches exclude selector"
assert_output --partial "Skipping it."
}

@test "exclude match regex" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES='^.*-b[ra]*n.*'

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Branch a-branch matches exclude selector"
assert_output --partial "Skipping it."
}

@test "exclude does not match regex" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_EXCLUDE_BRANCHES='^.*-b[er]*n.*'

stub git "rev-parse --short HEAD : echo 'some-commit-id'"
stub curl "${CURL_DEFAULT_STUB} : echo 'curl success'"

run "$PWD/hooks/pre-exit"

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "curl success"
refute_output --partial "Branch a-branch matches exclude selector"
refute_output --partial "Skipping it."
}