Fixes #1 Allow for multiple artifacts

This commit is contained in:
Nick Cipollo
2019-09-02 17:20:04 -04:00
parent 261c1fc08b
commit a698287254
24 changed files with 462 additions and 167 deletions

View File

@@ -3,7 +3,8 @@
This action will create a github release and optionally upload an artifact to it.
## Action Inputs
- **artifact**: A path to an optional artifact to upload to the release.
- **artifact**: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
- **artifacts**: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
- **artifactContentType**: The content type of the artifact. Defaults to raw.
- **body**: An optional body for the release.
- **bodyFile**: An optional body file for the release. This should be the path to the file.
@@ -32,7 +33,7 @@ jobs:
- uses: actions/checkout@v1
- uses: ncipollo/release-action@v1
with:
artifact: "release.tar.gz"
artifacts: "release.tar.gz,foo/*.txt"
bodyFile: "body.md"
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,13 +1,17 @@
import { Action } from "../src/Action";
import { Artifact } from "../src/Artifact";
import { Inputs } from "../src/Inputs";
import { Releases } from "../src/Releases";
import { ArtifactUploader } from "../src/ArtifactUploader";
const createMock = jest.fn()
const uploadMock = jest.fn()
const artifactPath = 'a/path'
const artifactName = 'path'
const artifactData = Buffer.from('blob','utf-8')
const artifacts = [
new Artifact('a/art1'),
new Artifact('b/art2')
]
const artifactData = Buffer.from('blob', 'utf-8')
const body = 'body'
const commit = 'commit'
const contentType = "raw"
@@ -44,7 +48,7 @@ describe("Action", () => {
await action.perform()
expect(createMock).toBeCalledWith(tag, body, commit, draft, name)
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactData, 'path')
expect(uploadMock).toBeCalledWith(artifacts, url)
})
it('throws error when create fails', async () => {
@@ -79,28 +83,25 @@ describe("Action", () => {
}
expect(createMock).toBeCalledWith(tag, body, commit, draft, name)
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactData, 'path')
expect(uploadMock).toBeCalledWith(artifacts, url)
})
function createAction(hasArtifact: boolean): Action {
let artifact: string
let inputArtifact: Artifact[]
if (hasArtifact) {
artifact = artifactPath
inputArtifact = artifacts
} else {
artifact = ''
inputArtifact = []
}
const MockReleases = jest.fn<Releases, any>(() => {
return {
create: createMock,
uploadArtifact: uploadMock
uploadArtifact: jest.fn()
}
})
const MockInputs = jest.fn<Inputs, any>(() => {
return {
artifact: artifact,
artifactName: artifactName,
artifactContentType: contentType,
artifactContentLength: contentLength,
artifacts: inputArtifact,
body: body,
commit: commit,
draft: draft,
@@ -110,9 +111,16 @@ describe("Action", () => {
readArtifact: () => artifactData
}
})
const MockUploader = jest.fn<ArtifactUploader, any>(() => {
return {
uploadArtifacts: uploadMock
}
})
const inputs = new MockInputs()
const releases = new MockReleases()
const uploader = new MockUploader()
return new Action(inputs, releases)
return new Action(inputs, releases, uploader)
}
})

View File

@@ -0,0 +1,38 @@
import { Artifact } from "../src/Artifact";
const fileContents = Buffer.from('artful facts', 'utf-8')
const contentLength = 42
jest.mock('fs', () => {
return {
readFileSync: () => fileContents,
statSync: () => { return { size: contentLength } }
};
})
describe("Artifact", () => {
it('defaults contentType to raw', () => {
const artifact = new Artifact('')
expect(artifact.contentType).toBe('raw')
})
it('generates name from path', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.name).toBe('artifact')
})
it('provides contentLength', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.contentLength).toBe(contentLength)
})
it('provides path', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.path).toBe('some/artifact')
})
it('reads artifact', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.readFile()).toBe(fileContents)
})
})

View File

@@ -0,0 +1,39 @@
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
import { Globber } from "../src/Globber";
import { Artifact } from "../src/Artifact";
const contentType = "raw"
const globResults = ["file1", "file2"]
describe("ArtifactGlobber", () => {
it("globs simple path", () => {
const globber = createArtifactGlobber()
const expectedArtifacts =
globResults.map((path) => new Artifact(path, contentType))
expect(globber.globArtifactString('path', 'raw'))
.toEqual(expectedArtifacts)
})
it("splits multiple paths", () => {
const globber = createArtifactGlobber()
const expectedArtifacts =
globResults
.concat(globResults)
.map((path) => new Artifact(path, contentType))
expect(globber.globArtifactString('path1,path2', 'raw'))
.toEqual(expectedArtifacts)
})
function createArtifactGlobber(): FileArtifactGlobber {
const MockGlobber = jest.fn<Globber, any>(() => {
return {
glob: () => globResults
}
})
return new FileArtifactGlobber(new MockGlobber())
}
})

View File

@@ -0,0 +1,43 @@
import { Artifact } from "../src/Artifact"
import { GithubArtifactUploader } from "../src/ArtifactUploader"
import { Releases } from "../src/Releases";
const artifacts = [
new Artifact('a/art1'),
new Artifact('b/art2')
]
const fileContents = Buffer.from('artful facts', 'utf-8')
const contentLength = 42
const uploadMock = jest.fn()
const url = 'http://api.example.com'
jest.mock('fs', () => {
return {
readFileSync: () => fileContents,
statSync: () => { return { size: contentLength } }
};
})
describe('ArtifactUploader', () => {
it('uploads artifacts', () => {
const uploader = createUploader()
uploader.uploadArtifacts(artifacts, url)
expect(uploadMock).toBeCalledTimes(2)
expect(uploadMock)
.toBeCalledWith(url, contentLength, 'raw', fileContents, 'art1')
expect(uploadMock)
.toBeCalledWith(url, contentLength, 'raw', fileContents, 'art2')
})
function createUploader(): GithubArtifactUploader {
const MockReleases = jest.fn<Releases, any>(() => {
return {
create: jest.fn(),
uploadArtifact: uploadMock
}
})
return new GithubArtifactUploader(new MockReleases())
}
});

View File

@@ -1,89 +1,100 @@
const mockGetInput = jest.fn();
const mockGlob = jest.fn()
const mockReadFileSync = jest.fn();
const mockStatSync = jest.fn();
import { Inputs, CoreInputs } from "../src/Inputs";
import { Artifact } from "../src/Artifact";
import { ArtifactGlobber } from "../src/ArtifactGlobber";
import { Context } from "@actions/github/lib/context";
import { Inputs, CoreInputs } from "../src/Inputs";
const artifacts = [
new Artifact('a/art1'),
new Artifact('b/art2')
]
jest.mock('@actions/core', () => {
return { getInput: mockGetInput };
})
jest.mock('fs', () => {
return {
return {
readFileSync: mockReadFileSync,
statSync: mockStatSync
};
};
})
describe('Inputs', () => {
let context: Context;
let inputs: Inputs;
beforeEach(() => {
mockGetInput.mockReturnValue(null)
mockGetInput.mockReset()
context = new Context()
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")
})
it('returns artifactContentLength', () => {
mockGetInput.mockReturnValue("a/path")
mockStatSync.mockReturnValue({size: 100})
expect(inputs.artifactContentLength).toBe(100)
})
it('returns artifactName', () => {
mockGetInput.mockReturnValue("a/path")
expect(inputs.artifactName).toBe("path")
inputs = new CoreInputs(createGlobber(), context)
})
it('returns targetCommit', () => {
mockGetInput.mockReturnValue("42")
expect(inputs.commit).toBe("42")
mockGetInput.mockReturnValue('42')
expect(inputs.commit).toBe('42')
})
it('returns token', () => {
mockGetInput.mockReturnValue("42")
expect(inputs.token).toBe("42")
mockGetInput.mockReturnValue('42')
expect(inputs.token).toBe('42')
})
describe('artifactContentType', () => {
it('returns input content-type', () => {
mockGetInput.mockReturnValue("type")
expect(inputs.artifactContentType).toBe("type")
describe('artifacts', () => {
it('returns empty artifacts', () => {
mockGetInput.mockReturnValueOnce('')
.mockReturnValueOnce('')
expect(inputs.artifacts).toEqual([])
expect(mockGlob).toBeCalledTimes(0)
})
it('returns raw as default', () => {
expect(inputs.artifactContentType).toBe("raw")
it('returns input.artifacts', () => {
mockGetInput.mockReturnValueOnce('art1')
.mockReturnValueOnce('contentType')
expect(inputs.artifacts).toEqual(artifacts)
expect(mockGlob).toBeCalledTimes(1)
expect(mockGlob).toBeCalledWith('art1', 'contentType')
})
it('returns input.artifacts with default contentType', () => {
mockGetInput.mockReturnValueOnce('art1')
expect(inputs.artifacts).toEqual(artifacts)
expect(mockGlob).toBeCalledTimes(1)
expect(mockGlob).toBeCalledWith('art1', 'raw')
})
it('returns input.artifact', () => {
mockGetInput.mockReturnValueOnce('')
.mockReturnValueOnce('art2')
.mockReturnValueOnce('contentType')
expect(inputs.artifacts).toEqual(artifacts)
expect(mockGlob).toBeCalledTimes(1)
expect(mockGlob).toBeCalledWith('art2', 'contentType')
})
})
describe('body', () => {
it('returns input body', () => {
mockGetInput.mockReturnValue("body")
expect(inputs.body).toBe("body")
mockGetInput.mockReturnValue('body')
expect(inputs.body).toBe('body')
})
it('returns body file contents', () => {
mockGetInput.mockReturnValueOnce("").mockReturnValueOnce("a/path")
mockReadFileSync.mockReturnValue("file")
mockGetInput.mockReturnValueOnce('').mockReturnValueOnce('a/path')
mockReadFileSync.mockReturnValue('file')
expect(inputs.body).toBe("file")
expect(inputs.body).toBe('file')
})
it('returns empty', () => {
expect(inputs.body).toBe("")
expect(inputs.body).toBe('')
})
})
@@ -91,43 +102,53 @@ describe('Inputs', () => {
it('returns false', () => {
expect(inputs.draft).toBe(false)
})
it('returns true', () => {
mockGetInput.mockReturnValue("true")
mockGetInput.mockReturnValue('true')
expect(inputs.draft).toBe(true)
})
})
describe('name', () => {
it('returns input name', () => {
mockGetInput.mockReturnValue("name")
expect(inputs.name).toBe("name")
mockGetInput.mockReturnValue('name')
expect(inputs.name).toBe('name')
})
it('returns tag', () => {
mockGetInput.mockReturnValue("")
context.ref = "refs/tags/sha-tag"
expect(inputs.name).toBe("sha-tag")
mockGetInput.mockReturnValue('')
context.ref = 'refs/tags/sha-tag'
expect(inputs.name).toBe('sha-tag')
})
})
describe('tag', () => {
it('returns input tag', () => {
mockGetInput.mockReturnValue("tag")
expect(inputs.tag).toBe("tag")
mockGetInput.mockReturnValue('tag')
expect(inputs.tag).toBe('tag')
})
it('returns context sha when input is empty', () => {
mockGetInput.mockReturnValue("")
context.ref = "refs/tags/sha-tag"
expect(inputs.tag).toBe("sha-tag")
mockGetInput.mockReturnValue('')
context.ref = 'refs/tags/sha-tag'
expect(inputs.tag).toBe('sha-tag')
})
it('returns context sha when input is null', () => {
mockGetInput.mockReturnValue(null)
context.ref = "refs/tags/sha-tag"
expect(inputs.tag).toBe("sha-tag")
context.ref = 'refs/tags/sha-tag'
expect(inputs.tag).toBe('sha-tag')
})
it('throws if no tag', () => {
expect(() => inputs.tag).toThrow()
})
})
function createGlobber(): ArtifactGlobber {
const MockGlobber = jest.fn<ArtifactGlobber, any>(() => {
return {
globArtifactString: mockGlob
}
})
mockGlob.mockImplementation(() => artifacts)
return new MockGlobber()
}
})

View File

@@ -3,8 +3,11 @@ description: 'Creates github releases'
author: 'Nick Cipollo'
inputs:
artifact:
description: 'A path to an optional artifact to upload to the release.'
description: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs)'
default: ''
artifacts:
description: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs)'
default: ''
artifactContentType:
description: 'The content type of the artifact. Defaults to raw'
default: ''

View File

@@ -1,22 +0,0 @@
# Contributors
### Checkin
- Do checkin source (src)
- Do checkin build output (lib)
- Do checkin runtime node_modules
- Do not checkin devDependency node_modules (husky can help see below)
### devDependencies
In order to handle correctly checking in node_modules without devDependencies, we run [Husky](https://github.com/typicode/husky) before each commit.
This step ensures that formatting and checkin rules are followed and that devDependencies are excluded. To make sure Husky runs correctly, please use the following workflow:
```
npm install # installs all devDependencies including Husky
git add abc.ext # Add the files you've changed. This should include files in src, lib, and node_modules (see above)
git commit -m "Informative commit message" # Commit. This will run Husky
```
During the commit step, Husky will take care of formatting all files with [Prettier](https://github.com/prettier/prettier) as well as pruning out devDependencies using `npm prune --production`.
It will also make sure these changes are appropriately included in your commit (no further work is needed)

View File

@@ -9,16 +9,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", { value: true });
class Action {
constructor(inputs, releases) {
constructor(inputs, releases, uploader) {
this.inputs = inputs;
this.releases = releases;
this.uploader = uploader;
}
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.inputs.readArtifact();
yield this.releases.uploadArtifact(createResult.data.upload_url, this.inputs.artifactContentLength, this.inputs.artifactContentType, artifactData, this.inputs.artifactName);
const artifacts = this.inputs.artifacts;
if (artifacts.length > 0) {
yield this.uploader.uploadArtifacts(artifacts, createResult.data.upload_url);
}
});
}

18
lib/Artifact.js Normal file
View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const fs_1 = require("fs");
class Artifact {
constructor(path, contentType = "raw") {
this.path = path;
this.name = path_1.basename(path);
this.contentType = contentType;
}
get contentLength() {
return fs_1.statSync(this.path).size;
}
readFile() {
return fs_1.readFileSync(this.path);
}
}
exports.Artifact = Artifact;

16
lib/ArtifactGlobber.js Normal file
View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Globber_1 = require("./Globber");
const Artifact_1 = require("./Artifact");
class FileArtifactGlobber {
constructor(globber = new Globber_1.FileGlobber()) {
this.globber = globber;
}
globArtifactString(artifact, contentType) {
return artifact.split(',')
.map((path) => this.globber.glob(path))
.reduce((accumulated, current) => accumulated.concat(current))
.map((path) => new Artifact_1.Artifact(path, contentType));
}
}
exports.FileArtifactGlobber = FileArtifactGlobber;

23
lib/ArtifactUploader.js Normal file
View File

@@ -0,0 +1,23 @@
"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 });
class GithubArtifactUploader {
constructor(releases) {
this.releases = releases;
}
uploadArtifacts(artifacts, uploadUrl) {
return __awaiter(this, void 0, void 0, function* () {
artifacts.forEach((artifact) => __awaiter(this, void 0, void 0, function* () {
yield this.releases.uploadArtifact(uploadUrl, artifact.contentLength, artifact.contentType, artifact.readFile(), artifact.name);
}));
});
}
}
exports.GithubArtifactUploader = GithubArtifactUploader;

9
lib/Globber.js Normal file
View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const glob_1 = require("glob");
class FileGlobber {
glob(pattern) {
return new glob_1.GlobSync(pattern, { mark: true }).found;
}
}
exports.FileGlobber = FileGlobber;

View File

@@ -9,26 +9,25 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const fs_1 = require("fs");
const path_1 = require("path");
class CoreInputs {
constructor(context) {
constructor(artifactGlobber, context) {
this.artifactGlobber = artifactGlobber;
this.context = context;
}
get artifact() {
return core.getInput('artifact');
}
get artifactName() {
return path_1.basename(this.artifact);
}
get artifactContentType() {
const type = core.getInput('artifactContentType');
if (type) {
return type;
get artifacts() {
let artifacts = core.getInput('artifacts');
if (!artifacts) {
artifacts = core.getInput('artifacts');
}
return 'raw';
}
get artifactContentLength() {
return fs_1.statSync(this.artifact).size;
if (artifacts) {
let contentType = core.getInput('artifactContentType');
if (!contentType) {
contentType = 'raw';
}
return this.artifactGlobber
.globArtifactString(artifacts, contentType);
}
return [];
}
get body() {
const body = core.getInput('body');
@@ -70,9 +69,6 @@ class CoreInputs {
get token() {
return core.getInput('token', { required: true });
}
readArtifact() {
return fs_1.readFileSync(this.artifact);
}
stringFromFile(path) {
return fs_1.readFileSync(path, 'utf-8');
}

View File

@@ -20,6 +20,8 @@ const core = __importStar(require("@actions/core"));
const Inputs_1 = require("./Inputs");
const Releases_1 = require("./Releases");
const Action_1 = require("./Action");
const ArtifactUploader_1 = require("./ArtifactUploader");
const ArtifactGlobber_1 = require("./ArtifactGlobber");
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
@@ -35,8 +37,10 @@ function createAction() {
const token = core.getInput('token');
const context = github.context;
const git = new github.GitHub(token);
const globber = new ArtifactGlobber_1.FileArtifactGlobber();
const inputs = new Inputs_1.CoreInputs(globber, context);
const releases = new Releases_1.GithubReleases(context, git);
const inputs = new Inputs_1.CoreInputs(context);
return new Action_1.Action(inputs, releases);
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases);
return new Action_1.Action(inputs, releases, uploader);
}
run();

View File

@@ -21,9 +21,11 @@
"license": "MIT",
"dependencies": {
"@actions/core": "^1.0.0",
"@actions/github": "^1.0.0"
"@actions/github": "^1.0.0",
"glob": "^7.1.4"
},
"devDependencies": {
"@types/glob": "^7.1.1",
"@types/jest": "^24.0.13",
"@types/node": "^12.0.4",
"jest": "^24.8.0",

View File

@@ -1,15 +1,16 @@
import { Inputs } from "./Inputs";
import { Releases } from "./Releases";
import { basename } from "path";
import { readFileSync } from "fs";
import { ArtifactUploader } from "./ArtifactUploader";
export class Action {
private inputs: Inputs
private releases: Releases
private uploader: ArtifactUploader
constructor(inputs: Inputs, releases: Releases) {
constructor(inputs: Inputs, releases: Releases, uploader: ArtifactUploader) {
this.inputs = inputs
this.releases = releases
this.uploader = uploader
}
async perform() {
@@ -21,14 +22,11 @@ export class Action {
this.inputs.name
)
if (this.inputs.artifact) {
const artifactData = this.inputs.readArtifact()
await this.releases.uploadArtifact(
createResult.data.upload_url,
this.inputs.artifactContentLength,
this.inputs.artifactContentType,
artifactData,
this.inputs.artifactName
const artifacts = this.inputs.artifacts
if (artifacts.length > 0) {
await this.uploader.uploadArtifacts(
artifacts,
createResult.data.upload_url
)
}
}

22
src/Artifact.ts Normal file
View File

@@ -0,0 +1,22 @@
import { basename } from "path";
import { readFileSync, statSync } from "fs";
export class Artifact {
readonly contentType: string
readonly name: string
readonly path: string
constructor(path: string, contentType: string = "raw") {
this.path = path
this.name = basename(path)
this.contentType = contentType;
}
get contentLength(): number {
return statSync(this.path).size
}
readFile(): Buffer {
return readFileSync(this.path)
}
}

22
src/ArtifactGlobber.ts Normal file
View File

@@ -0,0 +1,22 @@
import { Globber, FileGlobber } from "./Globber";
import { Artifact } from "./Artifact";
export interface ArtifactGlobber {
globArtifactString(artifact: string, contentType: string): Artifact[]
}
export class FileArtifactGlobber implements ArtifactGlobber {
private globber: Globber
constructor(globber: Globber = new FileGlobber()) {
this.globber = globber
}
globArtifactString(artifact: string, contentType: string): Artifact[] {
return artifact.split(',')
.map((path) => this.globber.glob(path))
.reduce((accumulated, current) => accumulated.concat(current))
.map((path) => new Artifact(path, contentType))
}
}

24
src/ArtifactUploader.ts Normal file
View File

@@ -0,0 +1,24 @@
import { Artifact } from "./Artifact";
import { Releases } from "./Releases";
export interface ArtifactUploader {
uploadArtifacts(artifacts: Artifact[], uploadUrl: string): void
}
export class GithubArtifactUploader implements ArtifactUploader {
private releases: Releases
constructor(releases: Releases) {
this.releases = releases
}
async uploadArtifacts(artifacts: Artifact[], uploadUrl: string) {
artifacts.forEach(async artifact => {
await this.releases.uploadArtifact(uploadUrl,
artifact.contentLength,
artifact.contentType,
artifact.readFile(),
artifact.name)
});
}
}

11
src/Globber.ts Normal file
View File

@@ -0,0 +1,11 @@
import { GlobSync } from "glob";
export interface Globber {
glob(pattern: string): string[]
}
export class FileGlobber implements Globber {
glob(pattern: string): string[] {
return new GlobSync(pattern, { mark: true }).found
}
}

View File

@@ -1,49 +1,42 @@
import * as core from '@actions/core';
import { Context } from "@actions/github/lib/context";
import { readFileSync, statSync } from 'fs';
import { basename } from 'path';
import { readFileSync } from 'fs';
import { ArtifactGlobber } from './ArtifactGlobber';
import { Artifact } from './Artifact';
export interface Inputs {
readonly artifact: string
readonly artifactName: string
readonly artifactContentType: string
readonly artifactContentLength: number
readonly artifacts: Artifact[]
readonly body: string
readonly commit: string
readonly draft: boolean
readonly name: string
readonly tag: string
readonly token: string
readArtifact(): Buffer
}
export class CoreInputs implements Inputs {
private artifactGlobber: ArtifactGlobber
private context: Context
constructor(context: Context) {
constructor(artifactGlobber: ArtifactGlobber, context: Context) {
this.artifactGlobber = artifactGlobber
this.context = context
}
get artifact(): string {
return core.getInput('artifact')
}
get artifactName(): string {
return basename(this.artifact)
}
get artifactContentType(): string {
const type = core.getInput('artifactContentType')
if(type) {
return type;
get artifacts(): Artifact[] {
let artifacts = core.getInput('artifacts')
if (!artifacts) {
artifacts = core.getInput('artifacts')
}
return 'raw'
}
get artifactContentLength(): number {
return statSync(this.artifact).size
if (artifacts) {
let contentType = core.getInput('artifactContentType')
if (!contentType) {
contentType = 'raw'
}
return this.artifactGlobber
.globArtifactString(artifacts, contentType)
}
return []
}
get body(): string {
@@ -97,10 +90,6 @@ 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

@@ -3,6 +3,8 @@ import * as core from '@actions/core';
import { CoreInputs } from './Inputs';
import { GithubReleases } from './Releases';
import { Action } from './Action';
import { GithubArtifactUploader } from './ArtifactUploader';
import { FileArtifactGlobber } from './ArtifactGlobber';
async function run() {
try {
@@ -17,9 +19,12 @@ function createAction(): Action {
const token = core.getInput('token')
const context = github.context
const git = new github.GitHub(token)
const globber = new FileArtifactGlobber()
const inputs = new CoreInputs(globber, context)
const releases = new GithubReleases(context, git)
const inputs = new CoreInputs(context)
return new Action(inputs, releases)
const uploader = new GithubArtifactUploader(releases)
return new Action(inputs, releases, uploader)
}
run();

View File

@@ -391,6 +391,20 @@
dependencies:
"@babel/types" "^7.3.0"
"@types/events@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
"@types/glob@^7.1.1":
version "7.1.1"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
@@ -423,6 +437,16 @@
dependencies:
"@types/jest-diff" "*"
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/node@*":
version "12.7.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.3.tgz#27b3f40addaf2f580459fdb405222685542f907a"
integrity sha512-3SiLAIBkDWDg6vFo0+5YJyHPWU9uwu40Qe+v+0MH8wRKYBimHvvAOyk3EzMrD/TrIlLYfXrqDqrg913PynrMJQ==
"@types/node@^12.0.4":
version "12.7.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44"
@@ -1346,7 +1370,7 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3:
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
version "7.1.4"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==