Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ Create a [Buildkite API Access Token](https://buildkite.com/docs/apis/rest-api#a

Refer to the [action.yml](./action.yml) for more detailed information on parameter use.

### Author Information

The action automatically determines the commit author from the GitHub event payload using the following priority order:

1. `.pusher.name` and `.pusher.email` from the event payload (existing behavior)
2. `.head_commit.author.name` and `.head_commit.author.email` from the event payload (for push events)
3. `.commit.commit.author.name` and `.commit.commit.author.email` from the event payload (for status events)
4. `commit_author_name` and `commit_author_email` input parameters (user-provided defaults)
5. Git commit information from the repository (last resort)

**Note:** Some GitHub events (like `status` events) don't include a `pusher` field. The action will automatically fall back through these options to find author information. You can provide default values using the `commit_author_name` and `commit_author_email` parameters if the event payload doesn't contain author information.

### Example

The following workflow creates a new Buildkite build to the target `pipeline` on every commit.
Expand All @@ -40,6 +52,23 @@ steps:
wait_timeout: 300
```

#### Example with Default Author Values

For events without a `pusher` field (like `status` events), you can provide default author values:

```yaml
on: [status]

steps:
- name: Trigger a Buildkite Build
uses: "buildkite/trigger-pipeline-action@v2.3.0"
with:
buildkite_api_access_token: ${{ secrets.TRIGGER_BK_BUILD_TOKEN }}
pipeline: "my-org/my-deploy-pipeline"
commit_author_name: ${{ github.event.commit.commit.author.name }}
commit_author_email: ${{ github.event.commit.commit.author.email }}
```

## Outputs

The following outputs are provided by the action:
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ inputs:
description: 'Maximum time in seconds to wait for build completion'
required: false
default: '3600'
commit_author_name:
description: 'Default commit author name to use if not available from event payload (useful for events without pusher field like status events)'
required: false
commit_author_email:
description: 'Default commit author email to use if not available from event payload (useful for events without pusher field like status events)'
required: false

runs:
using: 'docker'
Expand Down
54 changes: 52 additions & 2 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,56 @@ function get_github_env_json() {
echo "$GITHUB_EVENT_JSON"
}

function get_author_name() {
local NAME

# 1. Try pusher.name from event (existing behavior)
if NAME=$(jq -r ".pusher.name // empty" "$GITHUB_EVENT_PATH") && [[ -n "$NAME" ]]; then
: # NAME is already set
# 2. Try head_commit.author.name from event (for push events)
elif NAME=$(jq -r ".head_commit.author.name // empty" "$GITHUB_EVENT_PATH") && [[ -n "$NAME" ]]; then
: # NAME is already set
# 3. Try commit.commit.author.name from event (for status events)
elif NAME=$(jq -r ".commit.commit.author.name // empty" "$GITHUB_EVENT_PATH") && [[ -n "$NAME" ]]; then
: # NAME is already set
# 4. Use default input parameter if provided
elif [[ -n "${INPUT_COMMIT_AUTHOR_NAME:-}" ]]; then
NAME="$INPUT_COMMIT_AUTHOR_NAME"
# 5. Try to get from git commit (if we're in a git repo and commit exists)
elif [[ -d .git ]] && NAME=$(git show -s --format=%an "${COMMIT}" 2>/dev/null) && [[ -n "$NAME" ]]; then
: # NAME is already set
else
NAME=""
fi

echo "$NAME"
}

function get_author_email() {
local EMAIL

# 1. Try pusher.email from event (existing behavior)
if EMAIL=$(jq -r ".pusher.email // empty" "$GITHUB_EVENT_PATH") && [[ -n "$EMAIL" ]]; then
: # EMAIL is already set
# 2. Try head_commit.author.email from event (for push events)
elif EMAIL=$(jq -r ".head_commit.author.email // empty" "$GITHUB_EVENT_PATH") && [[ -n "$EMAIL" ]]; then
: # EMAIL is already set
# 3. Try commit.commit.author.email from event (for status events)
elif EMAIL=$(jq -r ".commit.commit.author.email // empty" "$GITHUB_EVENT_PATH") && [[ -n "$EMAIL" ]]; then
: # EMAIL is already set
# 4. Use default input parameter if provided
elif [[ -n "${INPUT_COMMIT_AUTHOR_EMAIL:-}" ]]; then
EMAIL="$INPUT_COMMIT_AUTHOR_EMAIL"
# 5. Try to get from git commit (if we're in a git repo and commit exists)
elif [[ -d .git ]] && EMAIL=$(git show -s --format=%ae "${COMMIT}" 2>/dev/null) && [[ -n "$EMAIL" ]]; then
: # EMAIL is already set
else
EMAIL=""
fi

echo "$EMAIL"
}

function get_INPUT_BUILD_ENV_VARS_json() {
INPUT_BUILD_ENV_VARS=$(
jq -c -s 'add' \
Expand Down Expand Up @@ -132,8 +182,8 @@ COMMIT="${INPUT_COMMIT:-${GITHUB_SHA}}"
BRANCH="${INPUT_BRANCH:-${GITHUB_REF#"refs/heads/"}}"
MESSAGE="${INPUT_MESSAGE:-}"

NAME=$(jq -r ".pusher.name" "$GITHUB_EVENT_PATH")
EMAIL=$(jq -r ".pusher.email" "$GITHUB_EVENT_PATH")
NAME=$(get_author_name)
EMAIL=$(get_author_email)
PULL_REQUEST_ID=""
PULL_REQUEST_BASE_BRANCH="${INPUT_PULL_REQUEST_BASE_BRANCH:-}"
if [[ "${INPUT_SEND_PULL_REQUEST:-true}" == 'true' ]]; then
Expand Down
76 changes: 76 additions & 0 deletions tests/entrypoint.bats
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,79 @@ teardown() {

unstub curl
}

@test "Creates a build with author from commit.commit when pusher is not available (status events)" {

export INPUT_BUILDKITE_API_ACCESS_TOKEN="123"
export INPUT_PIPELINE="my-org/my-pipeline"
export GITHUB_EVENT_PATH="tests/status.json"
export GITHUB_EVENT_NAME="status"

EXPECTED_JSON='{"commit":"a-sha","branch":"a-branch","message":"","author":{"name":"Status Author","email":"status@author.com"},"env":{"GITHUB_REPOSITORY":"buildkite/test-repo","SOURCE_REPO_SHA":"a-sha","SOURCE_REPO_REF":"a-branch"}}'
RESPONSE_JSON='{"web_url": "https://buildkite.com/build-url"}'

stub curl "--fail-with-body --silent --show-error -X POST -H \"Authorization: Bearer 123\" https://api.buildkite.com/v2/organizations/my-org/pipelines/my-pipeline/builds -d '$EXPECTED_JSON' : echo '$RESPONSE_JSON'"

run "${PWD}"/entrypoint.sh

assert_output --partial "Build created:"
assert_output --partial "https://buildkite.com/build-url"
assert_output --partial "::set-output name=json::$RESPONSE_JSON"
assert_output --partial "::set-output name=url::https://buildkite.com/build-url"

assert_success

unstub curl
}

@test "Creates a build with author from default parameters when no author in event" {

export INPUT_BUILDKITE_API_ACCESS_TOKEN="123"
export INPUT_PIPELINE="my-org/my-pipeline"
export INPUT_COMMIT_AUTHOR_NAME="Default Name"
export INPUT_COMMIT_AUTHOR_EMAIL="default@email.com"
export GITHUB_EVENT_PATH="tests/no-author.json"
export GITHUB_EVENT_NAME="create"

EXPECTED_JSON='{"commit":"a-sha","branch":"a-branch","message":"","author":{"name":"Default Name","email":"default@email.com"},"env":{"GITHUB_REPOSITORY":"buildkite/test-repo","SOURCE_REPO_SHA":"a-sha","SOURCE_REPO_REF":"a-branch"}}'
RESPONSE_JSON='{"web_url": "https://buildkite.com/build-url"}'

stub curl "--fail-with-body --silent --show-error -X POST -H \"Authorization: Bearer 123\" https://api.buildkite.com/v2/organizations/my-org/pipelines/my-pipeline/builds -d '$EXPECTED_JSON' : echo '$RESPONSE_JSON'"

run "${PWD}"/entrypoint.sh

assert_output --partial "Build created:"
assert_output --partial "https://buildkite.com/build-url"
assert_output --partial "::set-output name=json::$RESPONSE_JSON"
assert_output --partial "::set-output name=url::https://buildkite.com/build-url"

assert_success

unstub curl
}

@test "Pusher fields take precedence over default parameters" {

export INPUT_BUILDKITE_API_ACCESS_TOKEN="123"
export INPUT_PIPELINE="my-org/my-pipeline"
export INPUT_COMMIT_AUTHOR_NAME="Default Name"
export INPUT_COMMIT_AUTHOR_EMAIL="default@email.com"
export GITHUB_EVENT_PATH="tests/push.json"
export GITHUB_EVENT_NAME="push"

EXPECTED_JSON='{"commit":"a-sha","branch":"a-branch","message":"","author":{"name":"The Pusher","email":"pusher@pusher.com"},"env":{"GITHUB_REPOSITORY":"buildkite/test-repo","SOURCE_REPO_SHA":"a-sha","SOURCE_REPO_REF":"a-branch"}}'
RESPONSE_JSON='{"web_url": "https://buildkite.com/build-url"}'

stub curl "--fail-with-body --silent --show-error -X POST -H \"Authorization: Bearer 123\" https://api.buildkite.com/v2/organizations/my-org/pipelines/my-pipeline/builds -d '$EXPECTED_JSON' : echo '$RESPONSE_JSON'"

run "${PWD}"/entrypoint.sh

assert_output --partial "Build created:"
assert_output --partial "https://buildkite.com/build-url"
assert_output --partial "::set-output name=json::$RESPONSE_JSON"
assert_output --partial "::set-output name=url::https://buildkite.com/build-url"

assert_success

unstub curl
}
3 changes: 3 additions & 0 deletions tests/no-author.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ref": "refs/heads/main"
}
10 changes: 10 additions & 0 deletions tests/status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"commit": {
"commit": {
"author": {
"name": "Status Author",
"email": "status@author.com"
}
}
}
}