Fix bugs found in E2E testing

This commit is contained in:
Nick Cipollo
2019-08-27 09:50:26 -04:00
parent 0280874154
commit 2b2c872297
10 changed files with 183 additions and 32 deletions

View File

@@ -6,6 +6,8 @@ const createMock = jest.fn()
const uploadMock = jest.fn()
const artifactPath = 'a/path'
const artifactName = 'path'
const artifactData = Buffer.from('blob','utf-8')
const body = 'body'
const commit = 'commit'
const contentType = "raw"
@@ -35,14 +37,14 @@ describe("Action", () => {
const action = createAction(true)
createMock.mockResolvedValue({
data: {
assets_url: url
upload_url: url
}
})
await action.perform()
expect(createMock).toBeCalledWith(tag, body, commit, draft, name)
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactPath, 'path')
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactData, 'path')
})
it('throws error when create fails', async () => {
@@ -64,7 +66,7 @@ describe("Action", () => {
const action = createAction(true)
createMock.mockResolvedValue({
data: {
assets_url: url
upload_url: url
}
})
uploadMock.mockRejectedValue("error")
@@ -77,7 +79,7 @@ describe("Action", () => {
}
expect(createMock).toBeCalledWith(tag, body, commit, draft, name)
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactPath, 'path')
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactData, 'path')
})
function createAction(hasArtifact: boolean): Action {
@@ -96,6 +98,7 @@ describe("Action", () => {
const MockInputs = jest.fn<Inputs, any>(() => {
return {
artifact: artifact,
artifactName: artifactName,
artifactContentType: contentType,
artifactContentLength: contentLength,
body: body,
@@ -103,7 +106,8 @@ describe("Action", () => {
draft: draft,
name: name,
tag: tag,
token: token
token: token,
readArtifact: () => artifactData
}
})
const inputs = new MockInputs()

View File

@@ -26,6 +26,12 @@ describe('Inputs', () => {
inputs = new CoreInputs(context)
})
it('reads artifact', () => {
mockGetInput.mockReturnValue("a/path")
mockReadFileSync.mockReturnValue('file')
expect(inputs.artifact).toBe("a/path")
})
it('returns artifact', () => {
mockGetInput.mockReturnValue("a/path")
expect(inputs.artifact).toBe("a/path")
@@ -37,6 +43,11 @@ describe('Inputs', () => {
expect(inputs.artifactContentLength).toBe(100)
})
it('returns artifactName', () => {
mockGetInput.mockReturnValue("a/path")
expect(inputs.artifactName).toBe("path")
})
it('returns targetCommit', () => {
mockGetInput.mockReturnValue("42")
expect(inputs.commit).toBe("42")

View File

@@ -15,13 +15,16 @@ inputs:
description: 'An optional body file for the release. This should be the path to the file'
default: ''
commit:
description: 'An optional commit reference. This will be used to create the tag if it doesn't exist.'
description: "An optional commit reference. This will be used to create the tag if it does not exist."
default: ''
draft:
description: "Optionally marks this release as a draft release. Set to true to enable."
default: ''
name:
description: 'An optional name for the release. If this is omitted the tag will be used.'
default: ''
tag:
description: 'An optional tag for the release. If this is omitted the git ref will be used (if it's a tag).'
description: 'An optional tag for the release. If this is omitted the git ref will be used (if it is a tag).'
default: ''
token:
description: 'The Github token.'
@@ -29,4 +32,4 @@ inputs:
default: ''
runs:
using: 'node12'
main: 'lib/main.js'
main: 'lib/Main.js'

31
lib/Action.js Normal file
View File

@@ -0,0 +1,31 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const fs_1 = require("fs");
class Action {
constructor(inputs, releases) {
this.inputs = inputs;
this.releases = releases;
}
perform() {
return __awaiter(this, void 0, void 0, function* () {
const createResult = yield this.releases.create(this.inputs.tag, this.inputs.body, this.inputs.commit, this.inputs.draft, this.inputs.name);
if (this.inputs.artifact) {
const artifactData = this.readArtifact(this.inputs.artifact);
yield this.releases.uploadArtifact(createResult.data.upload_url, this.inputs.artifactContentLength, this.inputs.artifactContentType, artifactData, path_1.basename(this.inputs.artifact));
}
});
}
readArtifact(path) {
return fs_1.readFileSync(path);
}
}
exports.Action = Action;

73
lib/Inputs.js Normal file
View File

@@ -0,0 +1,73 @@
"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;
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const fs_1 = require("fs");
class CoreInputs {
constructor(context) {
this.context = context;
}
get artifact() {
return core.getInput('artifact');
}
get artifactContentType() {
const type = core.getInput('artifactContentType');
if (type) {
return type;
}
return 'raw';
}
get artifactContentLength() {
return fs_1.statSync(this.artifact).size;
}
get body() {
const body = core.getInput('body');
if (body) {
return body;
}
const bodyFile = core.getInput('bodyFile');
if (bodyFile) {
return this.stringFromFile(bodyFile);
}
return '';
}
get commit() {
return core.getInput('commit');
}
get draft() {
const draft = core.getInput('draft');
return draft == 'true';
}
get name() {
const name = core.getInput('name');
if (name) {
return name;
}
return this.tag;
}
get tag() {
const tag = core.getInput('tag');
if (tag) {
return tag;
}
const ref = this.context.ref;
const tagPath = "refs/tags/";
if (ref && ref.startsWith(tagPath)) {
return ref.substr(tagPath.length, ref.length);
}
throw Error("No tag found in ref or input!");
}
get token() {
return core.getInput('token', { required: true });
}
stringFromFile(path) {
return fs_1.readFileSync(path, 'utf-8');
}
}
exports.CoreInputs = CoreInputs;

View File

@@ -17,25 +17,26 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const github = __importStar(require("@actions/github"));
const core = __importStar(require("@actions/core"));
const releases_1 = require("./releases");
const Inputs_1 = require("./Inputs");
const Releases_1 = require("./Releases");
const Action_1 = require("./Action");
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const token = core.getInput('token');
const context = github.context;
const git = new github.GitHub(token);
const releases = new releases_1.Releases(context, git);
yield releases.create()
.catch(error => {
core.warning(error);
})
.then(response => {
core.warning(`response: ${response}`);
});
const action = createAction();
yield action.perform();
}
catch (error) {
core.setFailed(error.message);
}
});
}
function createAction() {
const token = core.getInput('token');
const context = github.context;
const git = new github.GitHub(token);
const releases = new Releases_1.GithubReleases(context, git);
const inputs = new Inputs_1.CoreInputs(context);
return new Action_1.Action(inputs, releases);
}
run();

View File

@@ -8,22 +8,36 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", { value: true });
class Releases {
class GithubReleases {
constructor(context, git) {
this.context = context;
this.git = git;
}
create() {
create(tag, body, commitHash, draft, name) {
return __awaiter(this, void 0, void 0, function* () {
return this.git.repos.createRelease({
name: "Test release",
draft: true,
body: body,
name: name,
draft: draft,
owner: this.context.repo.owner,
repo: this.context.repo.repo,
target_commitish: "master",
tag_name: "0.0.666"
target_commitish: commitHash,
tag_name: tag
});
});
}
uploadArtifact(assetUrl, contentLength, contentType, file, name) {
return __awaiter(this, void 0, void 0, function* () {
return this.git.repos.uploadReleaseAsset({
url: assetUrl,
headers: {
"content-length": contentLength,
"content-type": contentType
},
file: file,
name: name
});
});
}
}
exports.Releases = Releases;
exports.GithubReleases = GithubReleases;

View File

@@ -1,6 +1,7 @@
import { Inputs } from "./Inputs";
import { Releases } from "./Releases";
import { basename } from "path";
import { readFileSync } from "fs";
export class Action {
private inputs: Inputs
@@ -21,12 +22,13 @@ export class Action {
)
if (this.inputs.artifact) {
const artifactData = this.inputs.readArtifact()
await this.releases.uploadArtifact(
createResult.data.assets_url,
createResult.data.upload_url,
this.inputs.artifactContentLength,
this.inputs.artifactContentType,
this.inputs.artifact,
basename(this.inputs.artifact)
artifactData,
this.inputs.artifactName
)
}
}

View File

@@ -1,9 +1,11 @@
import * as core from '@actions/core';
import { Context } from "@actions/github/lib/context";
import { readFileSync, statSync } from 'fs';
import { basename } from 'path';
export interface Inputs {
readonly artifact: string
readonly artifactName: string
readonly artifactContentType: string
readonly artifactContentLength: number
readonly body: string
@@ -12,6 +14,8 @@ export interface Inputs {
readonly name: string
readonly tag: string
readonly token: string
readArtifact(): Buffer
}
export class CoreInputs implements Inputs {
@@ -25,6 +29,10 @@ export class CoreInputs implements Inputs {
return core.getInput('artifact')
}
get artifactName(): string {
return basename(this.artifact)
}
get artifactContentType(): string {
const type = core.getInput('artifactContentType')
if(type) {
@@ -89,6 +97,10 @@ export class CoreInputs implements Inputs {
return core.getInput('token', { required: true })
}
readArtifact(): Buffer {
return readFileSync(this.artifact)
}
stringFromFile(path: string): string {
return readFileSync(path, 'utf-8')
}

View File

@@ -15,7 +15,7 @@ export interface Releases {
assetUrl: string,
contentLength: number,
contentType: string,
file: string,
file: string | object,
name: string
): Promise<Response<AnyResponse>>
}
@@ -51,7 +51,7 @@ export class GithubReleases implements Releases{
assetUrl: string,
contentLength: number,
contentType: string,
file: string,
file: string | object,
name: string
): Promise<Response<AnyResponse>> {
return this.git.repos.uploadReleaseAsset({