From 31813fa7e91eafd5263ad8537f2da9354cb1a5bc Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 04:00:30 +1000 Subject: [PATCH 01/29] fix: Updated test to use pull sha --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 58b69a9..a3c4033 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,4 +16,5 @@ jobs: authToken: ${{secrets.GITHUB_TOKEN}} context: 'Test run' description: 'Passed' - state: 'success' \ No newline at end of file + state: 'success' + sha: ${{github.event.pull_request.head.sha || github.sha}} \ No newline at end of file From f8fe8f41bba328987c7e0171fc01e52c91432c7f Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 04:05:24 +1000 Subject: [PATCH 02/29] ci: updated npm push script commit text --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b2b2347..c1b692a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "test": "ava", "pack": "ncc build", "all": "npm run build && npm test", - "push": "npm run build && npm run pack && git add * && git commit -m \"Updated built file\" && git push" + "push": "npm run build && npm run pack && git add * && git commit -m \"refactor: update built file\" && git push" }, "repository": { "type": "git", From 681a54fbe0984b0f33764ef6ceb771c56b60f1f6 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 10:46:07 +1000 Subject: [PATCH 03/29] docs: fix typo in main.ts --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 3883dbd..455fc2e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -49,7 +49,7 @@ async function run(): Promise { } }); } catch (error) { - core.setFailed("Error creating ovtokit:\n" + error.message); + core.setFailed("Error creating octokit:\n" + error.message); } if (octokit == null) { return; From 6f4b254d53ec7b7d4cb070a1d3127f1c3e73ea4a Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 10:48:01 +1000 Subject: [PATCH 04/29] refactor: updated package-lock.json --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 606628a..34fa903 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "typescript-action", - "version": "0.0.0", + "name": "github-status-action", + "version": "1.0.0-alpha.1", "lockfileVersion": 1, "requires": true, "dependencies": { From b0ead667a048da052e941fe6f6a7bb92e6a25899 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 10:51:21 +1000 Subject: [PATCH 05/29] docs: fixed typo in action.yml --- action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index e470755..7c11d27 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ name: 'github-status-action' -description: 'Adds a check status on a commit, github reports the last status added for a particular context.' +description: 'Adds a check status on a commit, GitHub reports the last status added for a particular context.' author: 'Sibz@EntityZero' branding: icon: 'check' @@ -18,10 +18,10 @@ inputs: description: 'The status of the check: success, error, failure or pending' required: true owner: - description: 'Repostory onwer, defaults to context github.repository_owner if ommited' + description: 'Repostory onwer, defaults to context github.repository_owner if omited' default: ${{ github.repository_owner }} repository: - description: 'Repository, default to context github.repository if ommited' + description: 'Repository, default to context github.repository if omited' default: ${{ github.repository }} sha: description: 'SHA of commit to update status on, defaults to context github.sha' From de4aaf8249a70c01cfa697442e5fe4e637308945 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 10:52:14 +1000 Subject: [PATCH 06/29] style: added required attr to inputs in action.yml --- action.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 7c11d27..4635ade 100644 --- a/action.yml +++ b/action.yml @@ -16,16 +16,19 @@ inputs: required: true state: description: 'The status of the check: success, error, failure or pending' - required: true + required: true owner: description: 'Repostory onwer, defaults to context github.repository_owner if omited' default: ${{ github.repository_owner }} + required: false repository: description: 'Repository, default to context github.repository if omited' default: ${{ github.repository }} + required: false sha: description: 'SHA of commit to update status on, defaults to context github.sha' default: ${{ github.sha }} + required: false runs: using: 'node12' main: 'dist/index.js' From c5f871f85731feef8a91ab4ff81243262384d95a Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 10:53:03 +1000 Subject: [PATCH 07/29] docs: fix case typo in header in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd6ea92..90337cc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ github-status-action status

-# Github Status Action +# GitHub Status Action Adds a status update to a commit. GitHub will always show the latest state of a context. From 68fe245800a7c64218b22de491ab49299bc78945 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 11:06:21 +1000 Subject: [PATCH 08/29] docs: updated readme formated inputs added mention of pull requests requiring to use difffrent sha Closes #5 --- README.md | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 90337cc..dbf407d 100644 --- a/README.md +++ b/README.md @@ -11,29 +11,23 @@ Adds a status update to a commit. GitHub will always show the latest state of a ## Usage ### Inputs -```yml - authToken: - description: 'Use secrets.GITHUB_TOKEN or your own token if you need to trigger other workflows the use "on: status"' - required: true - context: - description: 'The context, this is displayed as the name of the check' - required: true - description: - description: 'Short text explaining the status of the check' - required: true - state: - description: 'The status of the check: success, error, failure or pending' - required: true - owner: - description: 'Repostory onwer, defaults to context github.repository_owner if ommited' - default: ${{ github.repository_owner }} - repository: - description: 'Repository, default to context github.repository if ommited' - default: ${{ github.repository }} - sha: - description: 'SHA of commit to update status on, defaults to context github.sha' - default: ${{ github.sha }} - ``` + + * `authToken` (required) + Use secrets.GITHUB_TOKEN or your own token if you need to trigger other workflows that use "on: status"' + * `context` (required) + The context, this is displayed as the name of the check + * `description` (required) + Short text explaining the status of the check + * `state` (required) + The status of the check should only be `success`, `error`, `failure` or `pending` + * `owner` + Repostory onwer, defaults to context github.repository_owner if omited + * `repository` + Repository, default to context github.repository if omited + * `sha` + SHA of commit to update status on, defaults to context github.sha + *If using `on: pull_request` use `github.event.pull_request.head.sha`* + ### Outputs None. @@ -58,4 +52,5 @@ on: # run on any PRs and main branch changes context: 'Test run' description: 'Passed' state: 'success' + sha: ${{github.event.pull_request.head.sha || github.sha}} ``` From 465a42870aaec98b9cbf44e1788a8c2ee957fcb9 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 12:51:48 +1000 Subject: [PATCH 09/29] refactor: put input names into own file --- src/inputNames.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/inputNames.ts diff --git a/src/inputNames.ts b/src/inputNames.ts new file mode 100644 index 0000000..fd817d3 --- /dev/null +++ b/src/inputNames.ts @@ -0,0 +1,13 @@ + +export const INPUT_NAMES = { + authToken: "authToken", + owner: "owner", + repo: "repository", + state: "state", + context: "context", + sha: "sha", + desc: "description", + //target_url: "target_url" +} + +export default INPUT_NAMES; \ No newline at end of file From 7422fd7b476bf9d3e16ca97de6bba49f8a99052f Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 12:53:01 +1000 Subject: [PATCH 10/29] refactor: create status req. logic now in own file --- src/main.ts | 56 ++++++++++++++-------------------------- src/makeStatusRequest.ts | 32 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 37 deletions(-) create mode 100644 src/makeStatusRequest.ts diff --git a/src/main.ts b/src/main.ts index 455fc2e..dc919c3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,37 +1,14 @@ import * as core from '@actions/core' import { Octokit } from '@octokit/rest' +import makeStatus, { StatusRequest } from './makeStatusRequest' +import makeStatusRequest from './makeStatusRequest'; +import { RequestParameters } from '@octokit/types'; async function run(): Promise { - let authToken: string = ''; - let context: string = ''; - let description: string = ''; - let state: any = ''; - let owner: string = ''; - let repository: string = ''; - let sha: string = ''; - + const authToken: string = core.getInput('authToken'); let octokit: Octokit | null = null; try { - authToken = core.getInput('authToken'); - context = core.getInput('context'); - description = core.getInput('description'); - state = core.getInput('state'); - owner = core.getInput('owner'); - repository = core.getInput('repository'); - sha = core.getInput('sha'); - - } catch (error) { - core.setFailed("Error getting inputs:\n" + error.message); - } - - try { - - - if (repository.startsWith(`${owner}/`)) { - repository = repository.replace(`${owner}/`, ''); - } - octokit = new Octokit({ auth: authToken, userAgent: "github-status-action", @@ -50,22 +27,27 @@ async function run(): Promise { }); } catch (error) { core.setFailed("Error creating octokit:\n" + error.message); + return; } + if (octokit == null) { + core.setFailed("Error creating octokit:\noctokit was null"); return; } + + let statusRequest: StatusRequest try { - console.log(repository); - await octokit.repos.createStatus({ - owner: owner, - repo: repository, - context: context, - sha: sha, - state: state, - description: description - }); + statusRequest = makeStatusRequest(); + } + catch (error) { + core.setFailed(`Error creating status request object: ${error.message}`); + return; + } + + try { + await octokit.repos.createStatus(statusRequest); } catch (error) { - core.setFailed(`Error setting status:\n${error.message}\nDetails:\nowner:${owner}\nrepo:${repository}\nsha:${sha}`); + core.setFailed(`Error setting status:\n${error.message}\nRequest object:\n${statusRequest}`); } } diff --git a/src/makeStatusRequest.ts b/src/makeStatusRequest.ts new file mode 100644 index 0000000..41a0080 --- /dev/null +++ b/src/makeStatusRequest.ts @@ -0,0 +1,32 @@ +import * as actionsCore from '@actions/core' +import inputNames from './inputNames'; +import { RequestParameters } from '@octokit/types'; + +export type StatusRequest = RequestParameters & Pick; + +export default function makeStatusRequest(testCore: any | null = null): StatusRequest { + let core: CoreActionsForTesting = + testCore as CoreActionsForTesting ?? actionsCore as CoreActionsForTesting; + + let request: StatusRequest = {} as StatusRequest; + + request.context = core.getInput(inputNames.context); + request.description = core.getInput(inputNames.desc); + request.state = core.getInput(inputNames.state) as CommitState; + request.owner = core.getInput(inputNames.owner); + request.repo = core.getInput(inputNames.repo); + request.sha = core.getInput(inputNames.sha); + //request.target_url = core.getInput(inputNames.target_url); + + if (request.repo.startsWith(`${request.owner}/`)) { + request.repo = request.repo.replace(`${request.owner}/`, ''); + } + + return request; +} + +export type CommitState = "success" | "error" | "failure" | "pending"; + +export interface CoreActionsForTesting { + getInput: (arg: string) => string +} \ No newline at end of file From 9d1f2110053b2d50c5c68de154d3ab3994cffc48 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 12:53:27 +1000 Subject: [PATCH 11/29] tests: added initial tests for makeStatusRequest --- __tests__/makeStatusRequestTests.ts | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 __tests__/makeStatusRequestTests.ts diff --git a/__tests__/makeStatusRequestTests.ts b/__tests__/makeStatusRequestTests.ts new file mode 100644 index 0000000..82854e2 --- /dev/null +++ b/__tests__/makeStatusRequestTests.ts @@ -0,0 +1,71 @@ +import test from 'ava'; +import makeStatusRequest, { CoreActionsForTesting, CommitState} from '../src/makeStatusRequest' +import inputNames from '../src/inputNames' + +const INPUT_CONTEXT = "test context"; +const INPUT_OWNER = "TestOwner"; +const INPUT_REPOSITORY = "Test.Repository-1"; +const INPUT_REPOSITORY_WITHOWNER = INPUT_OWNER + "/Test.Repository-1"; +const INPUT_STATE: CommitState = "success"; +const INPUT_DESC = "Test Description"; +const INPUT_SHA = "TestSHA"; +//const INPUT_TARGETURL = "test/uri"; + +const actionsCore: CoreActionsForTesting = { + getInput: (arg:string) => { + switch(arg) { + case inputNames.context: + return INPUT_CONTEXT; + case inputNames.owner: + return INPUT_OWNER; + case inputNames.repo: + return INPUT_REPOSITORY; + case inputNames.state: + return INPUT_STATE; + case inputNames.desc: + return INPUT_DESC; + case inputNames.sha: + return INPUT_SHA; + //case inputNames.target_url: + // return INPUT_TARGETURL; + default: + return "input not in test mock"; + } + } +} +const actionsCoreAlt1: CoreActionsForTesting = { + getInput: (arg:string) => { + switch(arg) { + case inputNames.repo: + return INPUT_REPOSITORY_WITHOWNER; + default: + return actionsCore.getInput(arg); + } + } +} + +test("should getInput context", t=> { + t.is(makeStatusRequest(actionsCore).context, INPUT_CONTEXT); +}); +test("should getInput owner", t=> { + t.is(makeStatusRequest(actionsCore).owner, INPUT_OWNER); +}); +test("should getInput repo", t=> { + t.is(makeStatusRequest(actionsCore).repo, INPUT_REPOSITORY); +}); +test("should getInput state", t=> { + t.is(makeStatusRequest(actionsCore).state, INPUT_STATE); +}); +test("should getInput description", t=> { + t.is(makeStatusRequest(actionsCore).description, INPUT_DESC); +}); +test("should getInput sha", t=> { + t.is(makeStatusRequest(actionsCore).sha, INPUT_SHA); +}); +// test("should getInput target_url", t=> { +// t.is(makeStatusRequest(actionsCore).target_url, INPUT_TARGETURL); +// }); + +test("should getInput repo and remove leading owner name", t=> { + t.is(makeStatusRequest(actionsCoreAlt1).repo, INPUT_REPOSITORY); +}); \ No newline at end of file From 1cd5e03f7f7f97700d4338b03cf4dede9ef01f12 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 13:09:24 +1000 Subject: [PATCH 12/29] fix: removed required from context/desc inputs Fixes #9 --- action.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/action.yml b/action.yml index 4635ade..833d7c2 100644 --- a/action.yml +++ b/action.yml @@ -7,16 +7,18 @@ branding: inputs: authToken: description: 'Use secrets.GITHUB_TOKEN or your own token if you need to trigger other workflows the use "on: status"' + required: true + state: + description: 'The status of the check: success, error, failure or pending' required: true context: description: 'The context, this is displayed as the name of the check' - required: true + default: 'default' + required: false description: description: 'Short text explaining the status of the check' - required: true - state: - description: 'The status of the check: success, error, failure or pending' - required: true + default: '' + required: false owner: description: 'Repostory onwer, defaults to context github.repository_owner if omited' default: ${{ github.repository_owner }} From feb04521a7f9fc32af7757b9039219b4e86792d3 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 13:11:58 +1000 Subject: [PATCH 13/29] docs: updated readme Now shows context/description as not required Associated w/ #9 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dbf407d..54ef67d 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,12 @@ Adds a status update to a commit. GitHub will always show the latest state of a * `authToken` (required) Use secrets.GITHUB_TOKEN or your own token if you need to trigger other workflows that use "on: status"' - * `context` (required) - The context, this is displayed as the name of the check - * `description` (required) - Short text explaining the status of the check * `state` (required) The status of the check should only be `success`, `error`, `failure` or `pending` + * `context` + The context, this is displayed as the name of the check + * `description` + Short text explaining the status of the check * `owner` Repostory onwer, defaults to context github.repository_owner if omited * `repository` From e4f049277d296624206df9152eaf1dfce05d9599 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 13:30:32 +1000 Subject: [PATCH 14/29] feat: added validation of owner --- src/makeStatusRequest.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/makeStatusRequest.ts b/src/makeStatusRequest.ts index 41a0080..241f00a 100644 --- a/src/makeStatusRequest.ts +++ b/src/makeStatusRequest.ts @@ -4,6 +4,9 @@ import { RequestParameters } from '@octokit/types'; export type StatusRequest = RequestParameters & Pick; +const regExUsername = /^\w+-?\w+(?!-)$/; +export const ERR_INVALID_OWNER = "Input 'owner' must be a valid GitHub username"; + export default function makeStatusRequest(testCore: any | null = null): StatusRequest { let core: CoreActionsForTesting = testCore as CoreActionsForTesting ?? actionsCore as CoreActionsForTesting; @@ -18,6 +21,11 @@ export default function makeStatusRequest(testCore: any | null = null): StatusRe request.sha = core.getInput(inputNames.sha); //request.target_url = core.getInput(inputNames.target_url); + if (!regExUsername.test(request.owner)) + { + throw new Error(ERR_INVALID_OWNER); + } + if (request.repo.startsWith(`${request.owner}/`)) { request.repo = request.repo.replace(`${request.owner}/`, ''); } From 42cb9a921709e5f71d6c1de72b7c9572d10e899a Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 13:31:59 +1000 Subject: [PATCH 15/29] test: added test Ensures error is thrown when owner is invalid --- __tests__/makeStatusRequestTests.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/__tests__/makeStatusRequestTests.ts b/__tests__/makeStatusRequestTests.ts index 82854e2..8ebf0f3 100644 --- a/__tests__/makeStatusRequestTests.ts +++ b/__tests__/makeStatusRequestTests.ts @@ -1,9 +1,10 @@ import test from 'ava'; -import makeStatusRequest, { CoreActionsForTesting, CommitState} from '../src/makeStatusRequest' +import makeStatusRequest, { CoreActionsForTesting, CommitState, ERR_INVALID_OWNER} from '../src/makeStatusRequest' import inputNames from '../src/inputNames' const INPUT_CONTEXT = "test context"; const INPUT_OWNER = "TestOwner"; +const INPUT_OWNER_INVALID = "-TestOwner"; const INPUT_REPOSITORY = "Test.Repository-1"; const INPUT_REPOSITORY_WITHOWNER = INPUT_OWNER + "/Test.Repository-1"; const INPUT_STATE: CommitState = "success"; @@ -44,6 +45,18 @@ const actionsCoreAlt1: CoreActionsForTesting = { } } +const actionsCoreAlt2: CoreActionsForTesting = { + getInput: (arg:string) => { + switch(arg) { + case inputNames.owner: + return INPUT_OWNER_INVALID; + default: + return actionsCore.getInput(arg); + } + } +} + + test("should getInput context", t=> { t.is(makeStatusRequest(actionsCore).context, INPUT_CONTEXT); }); @@ -68,4 +81,9 @@ test("should getInput sha", t=> { test("should getInput repo and remove leading owner name", t=> { t.is(makeStatusRequest(actionsCoreAlt1).repo, INPUT_REPOSITORY); -}); \ No newline at end of file +}); + +test("when owner is not a valid GitHub username, should throw", t=> { + let err = t.throws(()=> makeStatusRequest(actionsCoreAlt2)); + t.is(err.message, ERR_INVALID_OWNER) +}) \ No newline at end of file From 868b2938749cb5d4abaf5ea3593157f5535e0c82 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 13:39:50 +1000 Subject: [PATCH 16/29] ci: added a workflow to test all commits --- .github/workflows/smoke-screen-tests.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/smoke-screen-tests.yml diff --git a/.github/workflows/smoke-screen-tests.yml b/.github/workflows/smoke-screen-tests.yml new file mode 100644 index 0000000..8a5be6e --- /dev/null +++ b/.github/workflows/smoke-screen-tests.yml @@ -0,0 +1,14 @@ +name: "smoke-screen-tests" +on: + push: + branches-ignore: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: | + npm install + npm test \ No newline at end of file From 76d773fa9490fbaa20229225e20d750d6590a9d3 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 13:51:59 +1000 Subject: [PATCH 17/29] feat: added support for target_url Closes #6 --- __tests__/makeStatusRequestTests.ts | 12 ++++++------ action.yml | 3 +++ src/inputNames.ts | 2 +- src/makeStatusRequest.ts | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/__tests__/makeStatusRequestTests.ts b/__tests__/makeStatusRequestTests.ts index 8ebf0f3..1880023 100644 --- a/__tests__/makeStatusRequestTests.ts +++ b/__tests__/makeStatusRequestTests.ts @@ -10,7 +10,7 @@ const INPUT_REPOSITORY_WITHOWNER = INPUT_OWNER + "/Test.Repository-1"; const INPUT_STATE: CommitState = "success"; const INPUT_DESC = "Test Description"; const INPUT_SHA = "TestSHA"; -//const INPUT_TARGETURL = "test/uri"; +const INPUT_TARGETURL = "test/uri"; const actionsCore: CoreActionsForTesting = { getInput: (arg:string) => { @@ -27,8 +27,8 @@ const actionsCore: CoreActionsForTesting = { return INPUT_DESC; case inputNames.sha: return INPUT_SHA; - //case inputNames.target_url: - // return INPUT_TARGETURL; + case inputNames.target_url: + return INPUT_TARGETURL; default: return "input not in test mock"; } @@ -75,9 +75,9 @@ test("should getInput description", t=> { test("should getInput sha", t=> { t.is(makeStatusRequest(actionsCore).sha, INPUT_SHA); }); -// test("should getInput target_url", t=> { -// t.is(makeStatusRequest(actionsCore).target_url, INPUT_TARGETURL); -// }); +test("should getInput target_url", t=> { + t.is(makeStatusRequest(actionsCore).target_url, INPUT_TARGETURL); +}); test("should getInput repo and remove leading owner name", t=> { t.is(makeStatusRequest(actionsCoreAlt1).repo, INPUT_REPOSITORY); diff --git a/action.yml b/action.yml index 833d7c2..c5654fd 100644 --- a/action.yml +++ b/action.yml @@ -31,6 +31,9 @@ inputs: description: 'SHA of commit to update status on, defaults to context github.sha' default: ${{ github.sha }} required: false + target_url: + description: 'URL/URI to use for further details.' + required: false runs: using: 'node12' main: 'dist/index.js' diff --git a/src/inputNames.ts b/src/inputNames.ts index fd817d3..88f57f0 100644 --- a/src/inputNames.ts +++ b/src/inputNames.ts @@ -7,7 +7,7 @@ export const INPUT_NAMES = { context: "context", sha: "sha", desc: "description", - //target_url: "target_url" + target_url: "target_url" } export default INPUT_NAMES; \ No newline at end of file diff --git a/src/makeStatusRequest.ts b/src/makeStatusRequest.ts index 241f00a..3e3ada3 100644 --- a/src/makeStatusRequest.ts +++ b/src/makeStatusRequest.ts @@ -19,7 +19,7 @@ export default function makeStatusRequest(testCore: any | null = null): StatusRe request.owner = core.getInput(inputNames.owner); request.repo = core.getInput(inputNames.repo); request.sha = core.getInput(inputNames.sha); - //request.target_url = core.getInput(inputNames.target_url); + request.target_url = core.getInput(inputNames.target_url); if (!regExUsername.test(request.owner)) { From eda918c5e23b09e8a87983aaa7c98d47708153a7 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 13:55:53 +1000 Subject: [PATCH 18/29] refactor: reorganised code in makeStatusRequest.ts --- src/makeStatusRequest.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/makeStatusRequest.ts b/src/makeStatusRequest.ts index 3e3ada3..caa8c2b 100644 --- a/src/makeStatusRequest.ts +++ b/src/makeStatusRequest.ts @@ -2,10 +2,11 @@ import * as actionsCore from '@actions/core' import inputNames from './inputNames'; import { RequestParameters } from '@octokit/types'; +export type CommitState = "success" | "error" | "failure" | "pending"; export type StatusRequest = RequestParameters & Pick; +export const ERR_INVALID_OWNER = "Input 'owner' must be a valid GitHub username"; const regExUsername = /^\w+-?\w+(?!-)$/; -export const ERR_INVALID_OWNER = "Input 'owner' must be a valid GitHub username"; export default function makeStatusRequest(testCore: any | null = null): StatusRequest { let core: CoreActionsForTesting = @@ -33,8 +34,6 @@ export default function makeStatusRequest(testCore: any | null = null): StatusRe return request; } -export type CommitState = "success" | "error" | "failure" | "pending"; - export interface CoreActionsForTesting { getInput: (arg: string) => string } \ No newline at end of file From 68f1b6c44edb2cec71fe07193238a3e0fb887d2b Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:02:52 +1000 Subject: [PATCH 19/29] docs: updated readme with target_url input --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 54ef67d..8eff13c 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ Adds a status update to a commit. GitHub will always show the latest state of a * `sha` SHA of commit to update status on, defaults to context github.sha *If using `on: pull_request` use `github.event.pull_request.head.sha`* + * `target_url` + Url to use for the details link. If omited no link is shown. ### Outputs None. From 9b21f92db4d713971beff4ddf50942216392b1e9 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:08:48 +1000 Subject: [PATCH 20/29] test: added extra action run tests --- .github/workflows/test.yml | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a3c4033..c13f6c6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,11 +10,34 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Run the action + - name: Test min args uses: ./ with: authToken: ${{secrets.GITHUB_TOKEN}} - context: 'Test run' - description: 'Passed' - state: 'success' - sha: ${{github.event.pull_request.head.sha || github.sha}} \ No newline at end of file + state: 'success' + - name: Test with all args except owner/repo (success) + uses: ./ + with: + authToken: ${{secrets.GITHUB_TOKEN}} + context: "Test run" + description: "Test with all args" + target_url: "https://github.com/Sibz/github-status-action" + sha: ${{${{github.event.pull_request.head.sha || github.sha}}}} + state: 'success' + - name: Test failing action + uses: ./ + with: + authToken: ${{secrets.GITHUB_TOKEN}} + context: "Test run failed" + description: "Failed test" + sha: ${{${{github.event.pull_request.head.sha || github.sha}}}} + state: 'failed' + - name: Test failing action now succeeded + uses: ./ + with: + authToken: ${{secrets.GITHUB_TOKEN}} + context: "Test run failed" + description: "Failed test now succeeded" + sha: ${{${{github.event.pull_request.head.sha || github.sha}}}} + state: 'success' + \ No newline at end of file From 794e7e25f40556e218d021752b42ce59299805bb Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:10:32 +1000 Subject: [PATCH 21/29] ci: updated version and built file --- dist/index.js | 116 +++++++++++++++++++++++++++++++++------------- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 85 insertions(+), 35 deletions(-) diff --git a/dist/index.js b/dist/index.js index 1d56932..d73c204 100644 --- a/dist/index.js +++ b/dist/index.js @@ -604,35 +604,18 @@ var __importStar = (this && this.__importStar) || function (mod) { result["default"] = mod; return result; }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); const core = __importStar(__webpack_require__(470)); const rest_1 = __webpack_require__(889); +const makeStatusRequest_1 = __importDefault(__webpack_require__(677)); function run() { return __awaiter(this, void 0, void 0, function* () { - let authToken = ''; - let context = ''; - let description = ''; - let state = ''; - let owner = ''; - let repository = ''; - let sha = ''; + const authToken = core.getInput('authToken'); let octokit = null; try { - authToken = core.getInput('authToken'); - context = core.getInput('context'); - description = core.getInput('description'); - state = core.getInput('state'); - owner = core.getInput('owner'); - repository = core.getInput('repository'); - sha = core.getInput('sha'); - } - catch (error) { - core.setFailed("Error getting inputs:\n" + error.message); - } - try { - if (repository.startsWith(`${owner}/`)) { - repository = repository.replace(`${owner}/`, ''); - } octokit = new rest_1.Octokit({ auth: authToken, userAgent: "github-status-action", @@ -651,24 +634,26 @@ function run() { }); } catch (error) { - core.setFailed("Error creating ovtokit:\n" + error.message); + core.setFailed("Error creating octokit:\n" + error.message); + return; } if (octokit == null) { + core.setFailed("Error creating octokit:\noctokit was null"); return; } + let statusRequest; try { - console.log(repository); - yield octokit.repos.createStatus({ - owner: owner, - repo: repository, - context: context, - sha: sha, - state: state, - description: description - }); + statusRequest = makeStatusRequest_1.default(); + } + catch (error) { + core.setFailed(`Error creating status request object: ${error.message}`); + return; + } + try { + yield octokit.repos.createStatus(statusRequest); } catch (error) { - core.setFailed(`Error setting status:\n${error.message}\nDetails:\nowner:${owner}\nrepo:${repository}\nsha:${sha}`); + core.setFailed(`Error setting status:\n${error.message}\nRequest object:\n${statusRequest}`); } }); } @@ -5734,6 +5719,71 @@ if (process.platform === 'linux') { module.exports = require("util"); +/***/ }), + +/***/ 677: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const actionsCore = __importStar(__webpack_require__(470)); +const inputNames_1 = __importDefault(__webpack_require__(686)); +exports.ERR_INVALID_OWNER = "Input 'owner' must be a valid GitHub username"; +const regExUsername = /^\w+-?\w+(?!-)$/; +function makeStatusRequest(testCore = null) { + var _a; + let core = (_a = testCore, (_a !== null && _a !== void 0 ? _a : actionsCore)); + let request = {}; + request.context = core.getInput(inputNames_1.default.context); + request.description = core.getInput(inputNames_1.default.desc); + request.state = core.getInput(inputNames_1.default.state); + request.owner = core.getInput(inputNames_1.default.owner); + request.repo = core.getInput(inputNames_1.default.repo); + request.sha = core.getInput(inputNames_1.default.sha); + request.target_url = core.getInput(inputNames_1.default.target_url); + if (!regExUsername.test(request.owner)) { + throw new Error(exports.ERR_INVALID_OWNER); + } + if (request.repo.startsWith(`${request.owner}/`)) { + request.repo = request.repo.replace(`${request.owner}/`, ''); + } + return request; +} +exports.default = makeStatusRequest; + + +/***/ }), + +/***/ 686: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +exports.INPUT_NAMES = { + authToken: "authToken", + owner: "owner", + repo: "repository", + state: "state", + context: "context", + sha: "sha", + desc: "description", + target_url: "target_url" +}; +exports.default = exports.INPUT_NAMES; + + /***/ }), /***/ 692: diff --git a/package-lock.json b/package-lock.json index 34fa903..d6c87e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "github-status-action", - "version": "1.0.0-alpha.1", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c1b692a..650a5fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "github-status-action", - "version": "1.0.0-alpha.1", + "version": "1.1.0", "private": true, "description": "Github status action", "main": "lib/main.js", From 58f1f7b96986e628242679b2f99ccc58faf0b135 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:11:12 +1000 Subject: [PATCH 22/29] ci: updated script in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 650a5fa..d088eb5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "test": "ava", "pack": "ncc build", "all": "npm run build && npm test", - "push": "npm run build && npm run pack && git add * && git commit -m \"refactor: update built file\" && git push" + "push": "npm run build && npm run pack && git add * && git commit -m \"ci: update built file\" && git push" }, "repository": { "type": "git", From 755dd3b0ab68cb7e351f1405955d090592888e06 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:14:02 +1000 Subject: [PATCH 23/29] test: renamed smoke screen test job --- .github/workflows/smoke-screen-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/smoke-screen-tests.yml b/.github/workflows/smoke-screen-tests.yml index 8a5be6e..26769e3 100644 --- a/.github/workflows/smoke-screen-tests.yml +++ b/.github/workflows/smoke-screen-tests.yml @@ -5,7 +5,7 @@ on: - master jobs: - build: + sst: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 55b194254f046a14cef786686d2dc38731e6f63e Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:16:28 +1000 Subject: [PATCH 24/29] fix: invalid test.yml --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c13f6c6..932f8aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: context: "Test run" description: "Test with all args" target_url: "https://github.com/Sibz/github-status-action" - sha: ${{${{github.event.pull_request.head.sha || github.sha}}}} + sha: ${{github.event.pull_request.head.sha || github.sha}} state: 'success' - name: Test failing action uses: ./ @@ -30,7 +30,7 @@ jobs: authToken: ${{secrets.GITHUB_TOKEN}} context: "Test run failed" description: "Failed test" - sha: ${{${{github.event.pull_request.head.sha || github.sha}}}} + sha: ${{github.event.pull_request.head.sha || github.sha}} state: 'failed' - name: Test failing action now succeeded uses: ./ @@ -38,6 +38,6 @@ jobs: authToken: ${{secrets.GITHUB_TOKEN}} context: "Test run failed" description: "Failed test now succeeded" - sha: ${{${{github.event.pull_request.head.sha || github.sha}}}} + sha: ${{github.event.pull_request.head.sha || github.sha}} state: 'success' \ No newline at end of file From 0f139ac6d246d8f8a5b08121320777353cfed5b0 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:24:37 +1000 Subject: [PATCH 25/29] refactor: output json for error creating status --- src/main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index dc919c3..1f4a381 100644 --- a/src/main.ts +++ b/src/main.ts @@ -43,11 +43,11 @@ async function run(): Promise { core.setFailed(`Error creating status request object: ${error.message}`); return; } - + try { await octokit.repos.createStatus(statusRequest); } catch (error) { - core.setFailed(`Error setting status:\n${error.message}\nRequest object:\n${statusRequest}`); + core.setFailed(`Error setting status:\n${error.message}\nRequest object:\n${JSON.stringify(statusRequest, null, 2)}`); } } From f813911eacca8fc2a7f36192ee24ae80c93c3eae Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:27:52 +1000 Subject: [PATCH 26/29] ci: updated built file --- dist/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/index.js b/dist/index.js index d73c204..f497d3c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -653,7 +653,7 @@ function run() { yield octokit.repos.createStatus(statusRequest); } catch (error) { - core.setFailed(`Error setting status:\n${error.message}\nRequest object:\n${statusRequest}`); + core.setFailed(`Error setting status:\n${error.message}\nRequest object:\n${JSON.stringify(statusRequest, null, 2)}`); } }); } From f0adf1a975ca128a392575dee44b6551fb40c056 Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:37:14 +1000 Subject: [PATCH 27/29] fix: state now validated --- __tests__/makeStatusRequestTests.ts | 21 +++++++++++++++++++-- src/makeStatusRequest.ts | 14 ++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/__tests__/makeStatusRequestTests.ts b/__tests__/makeStatusRequestTests.ts index 1880023..9c02489 100644 --- a/__tests__/makeStatusRequestTests.ts +++ b/__tests__/makeStatusRequestTests.ts @@ -1,5 +1,5 @@ import test from 'ava'; -import makeStatusRequest, { CoreActionsForTesting, CommitState, ERR_INVALID_OWNER} from '../src/makeStatusRequest' +import makeStatusRequest, { CoreActionsForTesting, CommitState, ERR_INVALID_OWNER, ERR_INVALID_STATE} from '../src/makeStatusRequest' import inputNames from '../src/inputNames' const INPUT_CONTEXT = "test context"; @@ -8,6 +8,7 @@ const INPUT_OWNER_INVALID = "-TestOwner"; const INPUT_REPOSITORY = "Test.Repository-1"; const INPUT_REPOSITORY_WITHOWNER = INPUT_OWNER + "/Test.Repository-1"; const INPUT_STATE: CommitState = "success"; +const INPUT_STATE_INVALID: CommitState = "failed" as CommitState; const INPUT_DESC = "Test Description"; const INPUT_SHA = "TestSHA"; const INPUT_TARGETURL = "test/uri"; @@ -56,6 +57,17 @@ const actionsCoreAlt2: CoreActionsForTesting = { } } +const actionsCoreAlt3: CoreActionsForTesting = { + getInput: (arg:string) => { + switch(arg) { + case inputNames.state: + return INPUT_STATE_INVALID; + default: + return actionsCore.getInput(arg); + } + } +} + test("should getInput context", t=> { t.is(makeStatusRequest(actionsCore).context, INPUT_CONTEXT); @@ -86,4 +98,9 @@ test("should getInput repo and remove leading owner name", t=> { test("when owner is not a valid GitHub username, should throw", t=> { let err = t.throws(()=> makeStatusRequest(actionsCoreAlt2)); t.is(err.message, ERR_INVALID_OWNER) -}) \ No newline at end of file +}); + +test("should validate state", t=> { + let err = t.throws(()=> makeStatusRequest(actionsCoreAlt3)); + t.is(err.message, ERR_INVALID_STATE) +}); \ No newline at end of file diff --git a/src/makeStatusRequest.ts b/src/makeStatusRequest.ts index caa8c2b..e032034 100644 --- a/src/makeStatusRequest.ts +++ b/src/makeStatusRequest.ts @@ -5,6 +5,7 @@ import { RequestParameters } from '@octokit/types'; export type CommitState = "success" | "error" | "failure" | "pending"; export type StatusRequest = RequestParameters & Pick; export const ERR_INVALID_OWNER = "Input 'owner' must be a valid GitHub username"; +export const ERR_INVALID_STATE = "Input 'state' must be one of success | error | failure | pending"; const regExUsername = /^\w+-?\w+(?!-)$/; @@ -22,11 +23,14 @@ export default function makeStatusRequest(testCore: any | null = null): StatusRe request.sha = core.getInput(inputNames.sha); request.target_url = core.getInput(inputNames.target_url); - if (!regExUsername.test(request.owner)) - { + if (!regExUsername.test(request.owner)) { throw new Error(ERR_INVALID_OWNER); } + if (!validateState(request.state)) { + throw new Error(ERR_INVALID_STATE); + } + if (request.repo.startsWith(`${request.owner}/`)) { request.repo = request.repo.replace(`${request.owner}/`, ''); } @@ -34,6 +38,12 @@ export default function makeStatusRequest(testCore: any | null = null): StatusRe return request; } +function validateState(state: any): boolean { + return (state == "success" + || state == "error" + || state == "failure" + || state == "pending"); +} export interface CoreActionsForTesting { getInput: (arg: string) => string } \ No newline at end of file From 11a17c43f4ef026cfbbd8e82fe37793dc0059f3a Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:38:44 +1000 Subject: [PATCH 28/29] ci: update built file --- dist/index.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dist/index.js b/dist/index.js index f497d3c..a01f55c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5740,6 +5740,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const actionsCore = __importStar(__webpack_require__(470)); const inputNames_1 = __importDefault(__webpack_require__(686)); exports.ERR_INVALID_OWNER = "Input 'owner' must be a valid GitHub username"; +exports.ERR_INVALID_STATE = "Input 'state' must be one of success | error | failure | pending"; const regExUsername = /^\w+-?\w+(?!-)$/; function makeStatusRequest(testCore = null) { var _a; @@ -5755,12 +5756,21 @@ function makeStatusRequest(testCore = null) { if (!regExUsername.test(request.owner)) { throw new Error(exports.ERR_INVALID_OWNER); } + if (!validateState(request.state)) { + throw new Error(exports.ERR_INVALID_STATE); + } if (request.repo.startsWith(`${request.owner}/`)) { request.repo = request.repo.replace(`${request.owner}/`, ''); } return request; } exports.default = makeStatusRequest; +function validateState(state) { + return (state == "success" + || state == "error" + || state == "failure" + || state == "pending"); +} /***/ }), From b564c407ad1f2e24aea81e69acf53ccaa856d28e Mon Sep 17 00:00:00 2001 From: Sibz <12050358+Sibz@users.noreply.github.com> Date: Fri, 1 May 2020 14:40:15 +1000 Subject: [PATCH 29/29] fix: invalid state in test.xml --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 932f8aa..26b7270 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: context: "Test run failed" description: "Failed test" sha: ${{github.event.pull_request.head.sha || github.sha}} - state: 'failed' + state: 'failure' - name: Test failing action now succeeded uses: ./ with: