From e145372119f40b207a8835f985450839f37b800d Mon Sep 17 00:00:00 2001 From: Kamaz Date: Sun, 23 Feb 2020 22:20:54 +0000 Subject: [PATCH 1/5] feat: inactive state introduction --- .github/workflows/tear-down.yml | 17 ++++++++ src/app.ts | 74 ++++++++++++++++++++++++-------- src/deployment-status-payload.ts | 2 +- src/github-client.ts | 14 ++++++ 4 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/tear-down.yml diff --git a/.github/workflows/tear-down.yml b/.github/workflows/tear-down.yml new file mode 100644 index 0000000..506a39f --- /dev/null +++ b/.github/workflows/tear-down.yml @@ -0,0 +1,17 @@ +name: 'build-test' +on: # rebuild any PRs and main branch changes + pull_request: + push: + branches: + - master + - 'releases/*' + +jobs: + tear-down: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: ./ + with: + token: ${{secrets.GITHUB_TOKEN}} + state: inactive diff --git a/src/app.ts b/src/app.ts index d9b3bbd..3ba06d7 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,6 @@ import {createDeploymentPayload} from './deployment-payload' import {createDeploymentStatusPayload} from './deployment-status-payload' +import {Octokit} from '@octokit/rest' import {GitHubClient} from './github-client' import {GitHubContext} from './github-context' import {Context} from '@actions/github/lib/context' @@ -9,30 +10,65 @@ export type AppContext = GitHubContext & gitHubContext: Context } +const getDeploymentId = (context: AppContext): number => { + return parseInt(context.getInput('deploymentId'), 10) +} + +const isInactive = (context: AppContext): boolean => { + const state = context.getInput('state') as DeploymentState + const deploymentId = getDeploymentId(context) + + return state === 'inactive' && isNaN(deploymentId) +} + +const createDeploymentStatus = async ( + deploymentId: number, + context: AppContext +): Promise => { + const deploymentStatusPayload = createDeploymentStatusPayload( + deploymentId, + context + ) + + const deploymentStatus = await context.createDeploymentStatus( + deploymentStatusPayload + ) + + context.info(`Created deployment status: ${deploymentStatus.data.id}`) +} + +const hasInactiveStatus = ( + status: Octokit.ReposListDeploymentStatusesResponse +): boolean => status.some(d => d.state === 'inactive') + export const app = async (context: AppContext): Promise => { try { - let deploymentId = parseInt(context.getInput('deploymentId'), 10) - context.info(`Deployment id ${deploymentId}`) - - if (isNaN(deploymentId)) { - const deploymentPayload = createDeploymentPayload(context) - const deployment = await context.createDeployment(deploymentPayload) - deploymentId = deployment.data.id - context.info(`Created deployment id: ${deploymentId}`) - } - - const deploymentStatusPayload = createDeploymentStatusPayload( - deploymentId, - context - ) + let deploymentId: number + if (isInactive(context)) { + const deployments = await context.listDeployments() - const deploymentStatus = await context.createDeploymentStatus( - deploymentStatusPayload - ) + for (const deployment of deployments.data) { + const status = await context.request< + Octokit.ReposListDeploymentStatusesResponse + >(deployment.statuses_url) + if (!hasInactiveStatus(status.data)) { + await createDeploymentStatus(deployment.id, context) + } + } + } else { + deploymentId = getDeploymentId(context) + context.info(`Deployment id ${deploymentId}`) - context.info(`Created deployment status: ${deploymentStatus.data.id}`) + if (isNaN(deploymentId)) { + const deploymentPayload = createDeploymentPayload(context) + const deployment = await context.createDeployment(deploymentPayload) + deploymentId = deployment.data.id + context.info(`Created deployment id: ${deploymentId}`) + } - context.setOutput('deploymentId', `${deploymentId}`) + await createDeploymentStatus(deploymentId, context) + context.setOutput('deploymentId', `${deploymentId}`) + } } catch (error) { context.error(error.message) context.setFailed(error.message) diff --git a/src/deployment-status-payload.ts b/src/deployment-status-payload.ts index 3e7a069..2163dce 100644 --- a/src/deployment-status-payload.ts +++ b/src/deployment-status-payload.ts @@ -2,7 +2,7 @@ import {Octokit} from '@octokit/rest' import {deploymentContext} from './deployment-context' import {AppContext} from './app' -type DeploymentState = Octokit.ReposCreateDeploymentStatusParams['state'] +export type DeploymentState = Octokit.ReposCreateDeploymentStatusParams['state'] export const createDeploymentStatusPayload = ( deploymentId: number, diff --git a/src/github-client.ts b/src/github-client.ts index ed02366..4d16b19 100644 --- a/src/github-client.ts +++ b/src/github-client.ts @@ -13,6 +13,10 @@ export type CreateDeploymentResponse = Octokit.Response< Octokit.ReposCreateDeploymentResponse > +export type ListDeploymentsResponse = Octokit.Response< + Octokit.ReposListDeploymentsResponse +> + export type CreateDeployment = ( params: CreateDeploymentParams ) => Promise @@ -25,9 +29,13 @@ export type CreateDeploymentStatus = ( params: CreateDeploymentStatusParams ) => Promise +export type ListDeployments = () => Promise + export type GitHubClient = { createDeployment: CreateDeployment createDeploymentStatus: CreateDeploymentStatus + listDeployments: ListDeployments + request(url: string): Promise> } export const createGitHubClient = (context: GitHubContext): GitHubClient => { @@ -39,6 +47,12 @@ export const createGitHubClient = (context: GitHubContext): GitHubClient => { }, async createDeploymentStatus(deploymentStatus) { return octokit.repos.createDeploymentStatus(deploymentStatus) + }, + async listDeployments() { + return octokit.repos.listDeployments() + }, + async request(url: string) { + return (octokit.request(url) as unknown) as Octokit.Response } } } From 0dab3c033bcd63b1392be4791ac022568dd53e33 Mon Sep 17 00:00:00 2001 From: Kamaz Date: Sun, 23 Feb 2020 22:23:34 +0000 Subject: [PATCH 2/5] fix: compilation error --- dist/index.js | 59 +++++++++++++++++++++++++++++++++++++++------------ src/app.ts | 5 ++++- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/dist/index.js b/dist/index.js index 003857f..a7faeec 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4507,20 +4507,44 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge Object.defineProperty(exports, "__esModule", { value: true }); const deployment_payload_1 = __webpack_require__(792); const deployment_status_payload_1 = __webpack_require__(666); +const getDeploymentId = (context) => { + return parseInt(context.getInput('deploymentId'), 10); +}; +const isInactive = (context) => { + const state = context.getInput('state'); + const deploymentId = getDeploymentId(context); + return state === 'inactive' && isNaN(deploymentId); +}; +const createDeploymentStatus = (deploymentId, context) => __awaiter(void 0, void 0, void 0, function* () { + const deploymentStatusPayload = deployment_status_payload_1.createDeploymentStatusPayload(deploymentId, context); + const deploymentStatus = yield context.createDeploymentStatus(deploymentStatusPayload); + context.info(`Created deployment status: ${deploymentStatus.data.id}`); +}); +const hasInactiveStatus = (status) => status.some(d => d.state === 'inactive'); exports.app = (context) => __awaiter(void 0, void 0, void 0, function* () { try { - let deploymentId = parseInt(context.getInput('deploymentId'), 10); - context.info(`Deployment id ${deploymentId}`); - if (isNaN(deploymentId)) { - const deploymentPayload = deployment_payload_1.createDeploymentPayload(context); - const deployment = yield context.createDeployment(deploymentPayload); - deploymentId = deployment.data.id; - context.info(`Created deployment id: ${deploymentId}`); - } - const deploymentStatusPayload = deployment_status_payload_1.createDeploymentStatusPayload(deploymentId, context); - const deploymentStatus = yield context.createDeploymentStatus(deploymentStatusPayload); - context.info(`Created deployment status: ${deploymentStatus.data.id}`); - context.setOutput('deploymentId', `${deploymentId}`); + let deploymentId; + if (isInactive(context)) { + const deployments = yield context.listDeployments(); + for (const deployment of deployments.data) { + const status = yield context.request(deployment.statuses_url); + if (!hasInactiveStatus(status.data)) { + yield createDeploymentStatus(deployment.id, context); + } + } + } + else { + deploymentId = getDeploymentId(context); + context.info(`Deployment id ${deploymentId}`); + if (isNaN(deploymentId)) { + const deploymentPayload = deployment_payload_1.createDeploymentPayload(context); + const deployment = yield context.createDeployment(deploymentPayload); + deploymentId = deployment.data.id; + context.info(`Created deployment id: ${deploymentId}`); + } + yield createDeploymentStatus(deploymentId, context); + context.setOutput('deploymentId', `${deploymentId}`); + } } catch (error) { context.error(error.message); @@ -5020,6 +5044,16 @@ exports.createGitHubClient = (context) => { return __awaiter(this, void 0, void 0, function* () { return octokit.repos.createDeploymentStatus(deploymentStatus); }); + }, + listDeployments() { + return __awaiter(this, void 0, void 0, function* () { + return octokit.repos.listDeployments(); + }); + }, + request(url) { + return __awaiter(this, void 0, void 0, function* () { + return octokit.request(url); + }); } }; }; @@ -9509,7 +9543,6 @@ const converter_1 = __webpack_require__(538); const envName = (context) => { const { type, number } = deployment_context_1.deploymentContext(context); const environment = context.getInput('environment'); - context.info(`env name is: ${environment}`); if (environment && environment !== '') { return environment; } diff --git a/src/app.ts b/src/app.ts index 3ba06d7..a644592 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,8 @@ import {createDeploymentPayload} from './deployment-payload' -import {createDeploymentStatusPayload} from './deployment-status-payload' +import { + createDeploymentStatusPayload, + DeploymentState +} from './deployment-status-payload' import {Octokit} from '@octokit/rest' import {GitHubClient} from './github-client' import {GitHubContext} from './github-context' From 39814fee562cd03bbb7d0dafdbedd8a839e8b9bd Mon Sep 17 00:00:00 2001 From: Kamaz Date: Sun, 23 Feb 2020 22:30:13 +0000 Subject: [PATCH 3/5] fix: add params to list deployment and tear down on close pr --- .github/workflows/tear-down.yml | 6 ++---- dist/index.js | 12 +++++++++--- src/app.ts | 8 +++++++- src/github-client.ts | 9 ++++++--- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/.github/workflows/tear-down.yml b/.github/workflows/tear-down.yml index 506a39f..75419aa 100644 --- a/.github/workflows/tear-down.yml +++ b/.github/workflows/tear-down.yml @@ -1,10 +1,8 @@ name: 'build-test' on: # rebuild any PRs and main branch changes pull_request: - push: - branches: - - master - - 'releases/*' + types: + - closed jobs: tear-down: diff --git a/dist/index.js b/dist/index.js index a7faeec..a0b763f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4507,6 +4507,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge Object.defineProperty(exports, "__esModule", { value: true }); const deployment_payload_1 = __webpack_require__(792); const deployment_status_payload_1 = __webpack_require__(666); +const deployment_context_1 = __webpack_require__(157); const getDeploymentId = (context) => { return parseInt(context.getInput('deploymentId'), 10); }; @@ -4525,7 +4526,12 @@ exports.app = (context) => __awaiter(void 0, void 0, void 0, function* () { try { let deploymentId; if (isInactive(context)) { - const deployments = yield context.listDeployments(); + const { owner, repo, ref } = deployment_context_1.deploymentContext(context); + const deployments = yield context.listDeployments({ + owner, + repo, + ref + }); for (const deployment of deployments.data) { const status = yield context.request(deployment.statuses_url); if (!hasInactiveStatus(status.data)) { @@ -5045,9 +5051,9 @@ exports.createGitHubClient = (context) => { return octokit.repos.createDeploymentStatus(deploymentStatus); }); }, - listDeployments() { + listDeployments(params) { return __awaiter(this, void 0, void 0, function* () { - return octokit.repos.listDeployments(); + return octokit.repos.listDeployments(params); }); }, request(url) { diff --git a/src/app.ts b/src/app.ts index a644592..452d4db 100644 --- a/src/app.ts +++ b/src/app.ts @@ -7,6 +7,7 @@ import {Octokit} from '@octokit/rest' import {GitHubClient} from './github-client' import {GitHubContext} from './github-context' import {Context} from '@actions/github/lib/context' +import {deploymentContext} from './deployment-context' export type AppContext = GitHubContext & GitHubClient & { @@ -48,7 +49,12 @@ export const app = async (context: AppContext): Promise => { try { let deploymentId: number if (isInactive(context)) { - const deployments = await context.listDeployments() + const {owner, repo, ref} = deploymentContext(context) + const deployments = await context.listDeployments({ + owner, + repo, + ref + }) for (const deployment of deployments.data) { const status = await context.request< diff --git a/src/github-client.ts b/src/github-client.ts index 4d16b19..d03c62a 100644 --- a/src/github-client.ts +++ b/src/github-client.ts @@ -8,6 +8,7 @@ Octokit.plugin([throttling, retry]) export type CreateDeploymentParams = Octokit.ReposCreateDeploymentParams export type CreateDeploymentStatusParams = Octokit.ReposCreateDeploymentStatusParams +export type ListDeploymentsParam = Octokit.ReposListDeploymentsParams export type CreateDeploymentResponse = Octokit.Response< Octokit.ReposCreateDeploymentResponse @@ -29,7 +30,9 @@ export type CreateDeploymentStatus = ( params: CreateDeploymentStatusParams ) => Promise -export type ListDeployments = () => Promise +export type ListDeployments = ( + params: ListDeploymentsParam +) => Promise export type GitHubClient = { createDeployment: CreateDeployment @@ -48,8 +51,8 @@ export const createGitHubClient = (context: GitHubContext): GitHubClient => { async createDeploymentStatus(deploymentStatus) { return octokit.repos.createDeploymentStatus(deploymentStatus) }, - async listDeployments() { - return octokit.repos.listDeployments() + async listDeployments(params) { + return octokit.repos.listDeployments(params) }, async request(url: string) { return (octokit.request(url) as unknown) as Octokit.Response From e872ca871a09d0186106773e380d7fa21c39a971 Mon Sep 17 00:00:00 2001 From: Kamaz Date: Sun, 23 Feb 2020 22:30:54 +0000 Subject: [PATCH 4/5] fix: rename tear down name of github action --- .github/workflows/tear-down.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tear-down.yml b/.github/workflows/tear-down.yml index 75419aa..0d3ae25 100644 --- a/.github/workflows/tear-down.yml +++ b/.github/workflows/tear-down.yml @@ -1,4 +1,4 @@ -name: 'build-test' +name: 'tear-down-test' on: # rebuild any PRs and main branch changes pull_request: types: From 7d0a137d64ba5378704c2a802f8aa746be408658 Mon Sep 17 00:00:00 2001 From: Kamaz Date: Sun, 23 Feb 2020 22:48:29 +0000 Subject: [PATCH 5/5] fix: missing values on mock context --- __tests__/app.test.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/__tests__/app.test.ts b/__tests__/app.test.ts index 26119fd..8a41bc6 100644 --- a/__tests__/app.test.ts +++ b/__tests__/app.test.ts @@ -3,7 +3,8 @@ import { CreateDeploymentStatusResponse, CreateDeploymentResponse, CreateDeploymentParams, - CreateDeploymentStatusParams + CreateDeploymentStatusParams, + ListDeploymentsResponse } from '../src/github-client' import {Context} from '@actions/github/lib/context' @@ -122,6 +123,12 @@ const createMockAppContext = ( status: 200 } as CreateDeploymentStatusResponse }, + async listDeployments(params) { + return {} as ListDeploymentsResponse + }, + async request(url: string) { + return {} as T + }, gitHubContext } }