Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wait for check by ID #45

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ This Action accepts the following configuration parameters via `with:`

The GitHub token to use for making API requests. Typically, this would be set to `${{ secrets.GITHUB_TOKEN }}`.

**IMPORTANT** One of checkName or checkRunID is required!

- `checkName`

**Required**
Expand All @@ -42,6 +44,30 @@ This Action accepts the following configuration parameters via `with:`

**IMPORTANT**: If the check you're referencing is provided by another GitHub Actions workflow, make sure that you reference the name of a _Job_ within that workflow, and _not_ the name the _Workflow_ itself.

- `checkRunID`

**Required**

The ID of the GitHub check to wait for. For example:

```
- uses: LouisBrunner/[email protected]
id: check
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: Some run
status: queued

#...other actions steps

- name: Wait for build to succeed
uses: fountainhead/action-wait-for-check@some-version
id: wait-for-regression
with:
token: ${{ secrets.GITHUB_TOKEN }}
checkRunID: ${{steps.check.outputs.check_id }}
```

- `ref`

**Default: `github.sha`**
Expand Down
234 changes: 151 additions & 83 deletions __tests__/poll.test.ts
Original file line number Diff line number Diff line change
@@ -1,105 +1,173 @@
import {poll} from '../src/poll'
import {poll, pollByID} from '../src/poll'

const client = {
rest: {
checks: {
listForRef: jest.fn()
rest: {
checks: {
listForRef: jest.fn(),
get: jest.fn(),
}
}
}
}

const run = () =>
poll({
client: client as any,
log: () => {},
checkName: 'test',
owner: 'testOrg',
repo: 'testRepo',
ref: 'abcd',
timeoutSeconds: 3,
intervalSeconds: 0.1
})
poll({
client: client as any,
log: () => {},
checkName: 'test',
checkRunID: 123,
owner: 'testOrg',
repo: 'testRepo',
ref: 'abcd',
timeoutSeconds: 3,
intervalSeconds: 0.1
})

test('returns conclusion of completed check', async () => {
client.rest.checks.listForRef.mockResolvedValue({
data: {
check_runs: [
{
id: '1',
status: 'pending'
},
{
id: '2',
status: 'completed',
conclusion: 'success'
client.rest.checks.listForRef.mockResolvedValue({
data: {
check_runs: [
{
id: '1',
status: 'pending'
},
{
id: '2',
status: 'completed',
conclusion: 'success'
}
]
}
]
}
})
})

const result = await run()
const result = await run()

expect(result).toBe('success')
expect(client.rest.checks.listForRef).toHaveBeenCalledWith({
owner: 'testOrg',
repo: 'testRepo',
ref: 'abcd',
check_name: 'test'
})
expect(result).toBe('success')
expect(client.rest.checks.listForRef).toHaveBeenCalledWith({
owner: 'testOrg',
repo: 'testRepo',
ref: 'abcd',
check_name: 'test'
})
})

test('polls until check is completed', async () => {
client.rest.checks.listForRef
.mockResolvedValueOnce({
data: {
check_runs: [
{
id: '1',
status: 'pending'
}
]
}
})
.mockResolvedValueOnce({
data: {
check_runs: [
{
id: '1',
status: 'pending'
}
]
}
})
.mockResolvedValueOnce({
data: {
check_runs: [
{
id: '1',
status: 'completed',
conclusion: 'failure'
}
]
}
})
client.rest.checks.listForRef
.mockResolvedValueOnce({
data: {
check_runs: [
{
id: '1',
status: 'pending'
}
]
}
})
.mockResolvedValueOnce({
data: {
check_runs: [
{
id: '1',
status: 'pending'
}
]
}
})
.mockResolvedValueOnce({
data: {
check_runs: [
{
id: '1',
status: 'completed',
conclusion: 'failure'
}
]
}
})

const result = await run()
const result = await run()

expect(result).toBe('failure')
expect(client.rest.checks.listForRef).toHaveBeenCalledTimes(3)
expect(result).toBe('failure')
expect(client.rest.checks.listForRef).toHaveBeenCalledTimes(3)
})

test(`returns 'timed_out' if exceeding deadline`, async () => {
client.rest.checks.listForRef.mockResolvedValue({
data: {
check_runs: [
{
id: '1',
status: 'pending'
client.rest.checks.listForRef.mockResolvedValue({
data: {
check_runs: [
{
id: '1',
status: 'pending'
}
]
}
]
}
})
})

const result = await run()
expect(result).toBe('timed_out')
const result = await run()
expect(result).toBe('timed_out')
})

const runByID = () =>
pollByID({
client: client as any,
log: () => {},
checkRunID: 123,
owner: 'testOrg',
repo: 'testRepo',
timeoutSeconds: 3,
intervalSeconds: 0.1
});

client.rest.checks.get = jest.fn();

test('returns conclusion of completed check by ID', async () => {
client.rest.checks.get.mockResolvedValue({
data: {
id: 123,
status: 'completed',
conclusion: 'success'
}
});

const result = await runByID();

expect(result).toBe('success');
expect(client.rest.checks.get).toHaveBeenCalledWith({
check_run_id: 123,
owner: 'testOrg',
repo: 'testRepo'
});
});

test('polls until check by ID is completed', async () => {
client.rest.checks.get
.mockResolvedValueOnce({
data: {
id: 123,
status: 'pending'
}
})
.mockResolvedValueOnce({
data: {
id: 123,
status: 'completed',
conclusion: 'failure'
}
});

const result = await runByID();

expect(result).toBe('failure');
expect(client.rest.checks.get).toHaveBeenCalledTimes(2);
});

test(`returns 'timed_out' if exceeding deadline by ID`, async () => {
client.rest.checks.get.mockResolvedValue({
data: {
id: 123,
status: 'pending'
}
});

const result = await runByID();
expect(result).toBe('timed_out');
});
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ inputs:
required: true
checkName:
description: 'The name of the GitHub check to wait for. For example, `build` or `deploy`.'
required: true
required: false
checkRunID:
description: 'The id of the GitHub check to wait for. For example, `build` or `deploy`.'
required: false
ref:
description: 'The Git ref of the commit you want to poll for a passing check.'
repo:
Expand Down
Loading