Fixes #33 Add artifactErrorsFailBuild flag
This commit is contained in:
@@ -4,6 +4,7 @@ This action will create a github release and optionally upload an artifact to it
|
|||||||
|
|
||||||
## Action Inputs
|
## Action Inputs
|
||||||
- **allowUpdates**: An optional flag which indicates if we should update a release if it already exists. Defaults to false.
|
- **allowUpdates**: An optional flag which indicates if we should update a release if it already exists. Defaults to false.
|
||||||
|
- **artifactErrorsFailBuild**: An optional flag which indicates if artifact read or upload errors should fail the build.
|
||||||
- **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).
|
- **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).
|
- **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.
|
- **artifactContentType**: The content type of the artifact. Defaults to raw.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const artifacts = [
|
|||||||
new Artifact('b/art2')
|
new Artifact('b/art2')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const artifactErrorsFailBuild = false
|
||||||
const createBody = 'createBody'
|
const createBody = 'createBody'
|
||||||
const createName = 'createName'
|
const createName = 'createName'
|
||||||
const commit = 'commit'
|
const commit = 'commit'
|
||||||
@@ -239,6 +240,7 @@ describe("Action", () => {
|
|||||||
const MockInputs = jest.fn<Inputs, any>(() => {
|
const MockInputs = jest.fn<Inputs, any>(() => {
|
||||||
return {
|
return {
|
||||||
allowUpdates: allowUpdates,
|
allowUpdates: allowUpdates,
|
||||||
|
artifactErrorsFailBuild: true,
|
||||||
artifacts: inputArtifact,
|
artifacts: inputArtifact,
|
||||||
createdReleaseBody: createBody,
|
createdReleaseBody: createBody,
|
||||||
createdReleaseName: createName,
|
createdReleaseName: createName,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const warnMock = jest.fn()
|
const warnMock = jest.fn()
|
||||||
|
|
||||||
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
|
import {FileArtifactGlobber} from "../src/ArtifactGlobber"
|
||||||
import { Globber } from "../src/Globber";
|
import {Globber} from "../src/Globber";
|
||||||
import { Artifact } from "../src/Artifact";
|
import {Artifact} from "../src/Artifact";
|
||||||
import untildify = require("untildify");
|
import untildify = require("untildify");
|
||||||
|
|
||||||
const contentType = "raw"
|
const contentType = "raw"
|
||||||
@@ -24,19 +24,19 @@ describe("ArtifactGlobber", () => {
|
|||||||
const expectedArtifacts =
|
const expectedArtifacts =
|
||||||
globResults.map((path) => new Artifact(path, contentType))
|
globResults.map((path) => new Artifact(path, contentType))
|
||||||
|
|
||||||
expect(globber.globArtifactString('~/path', 'raw'))
|
expect(globber.globArtifactString('~/path', 'raw', false))
|
||||||
.toEqual(expectedArtifacts)
|
.toEqual(expectedArtifacts)
|
||||||
expect(globMock).toBeCalledWith(untildify('~/path'))
|
expect(globMock).toBeCalledWith(untildify('~/path'))
|
||||||
expect(warnMock).not.toBeCalled()
|
expect(warnMock).not.toBeCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("globs simple path", () => {
|
it("globs simple path", () => {
|
||||||
const globber = createArtifactGlobber()
|
const globber = createArtifactGlobber()
|
||||||
|
|
||||||
const expectedArtifacts =
|
const expectedArtifacts =
|
||||||
globResults.map((path) => new Artifact(path, contentType))
|
globResults.map((path) => new Artifact(path, contentType))
|
||||||
|
|
||||||
expect(globber.globArtifactString('path', 'raw'))
|
expect(globber.globArtifactString('path', 'raw', false))
|
||||||
.toEqual(expectedArtifacts)
|
.toEqual(expectedArtifacts)
|
||||||
expect(globMock).toBeCalledWith('path')
|
expect(globMock).toBeCalledWith('path')
|
||||||
expect(warnMock).not.toBeCalled()
|
expect(warnMock).not.toBeCalled()
|
||||||
@@ -50,24 +50,28 @@ describe("ArtifactGlobber", () => {
|
|||||||
.concat(globResults)
|
.concat(globResults)
|
||||||
.map((path) => new Artifact(path, contentType))
|
.map((path) => new Artifact(path, contentType))
|
||||||
|
|
||||||
expect(globber.globArtifactString('path1,path2', 'raw'))
|
expect(globber.globArtifactString('path1,path2', 'raw', false))
|
||||||
.toEqual(expectedArtifacts)
|
.toEqual(expectedArtifacts)
|
||||||
expect(globMock).toBeCalledWith('path1')
|
expect(globMock).toBeCalledWith('path1')
|
||||||
expect(globMock).toBeCalledWith('path2')
|
expect(globMock).toBeCalledWith('path2')
|
||||||
expect(warnMock).not.toBeCalled()
|
expect(warnMock).not.toBeCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("warns when no glob results are produced", () => {
|
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
||||||
const globber = createArtifactGlobber([])
|
const globber = createArtifactGlobber([])
|
||||||
|
|
||||||
const expectedArtifacts =
|
expect(globber.globArtifactString('path', 'raw', false))
|
||||||
globResults.map((path) => new Artifact(path, contentType))
|
|
||||||
|
|
||||||
expect(globber.globArtifactString('path', 'raw'))
|
|
||||||
.toEqual([])
|
.toEqual([])
|
||||||
expect(warnMock).toBeCalled()
|
expect(warnMock).toBeCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("throws when no glob results are produced and empty results shouild throw", () => {
|
||||||
|
const globber = createArtifactGlobber([])
|
||||||
|
expect(() => {
|
||||||
|
globber.globArtifactString('path', 'raw', true)
|
||||||
|
}).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
function createArtifactGlobber(results: string[] = globResults): FileArtifactGlobber {
|
function createArtifactGlobber(results: string[] = globResults): FileArtifactGlobber {
|
||||||
const MockGlobber = jest.fn<Globber, any>(() => {
|
const MockGlobber = jest.fn<Globber, any>(() => {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Artifact } from "../src/Artifact"
|
import {Artifact} from "../src/Artifact"
|
||||||
import { GithubArtifactUploader } from "../src/ArtifactUploader"
|
import {GithubArtifactUploader} from "../src/ArtifactUploader"
|
||||||
import { Releases } from "../src/Releases";
|
import {Releases} from "../src/Releases";
|
||||||
import { RequestError } from '@octokit/request-error'
|
import {RequestError} from '@octokit/request-error'
|
||||||
|
|
||||||
const artifacts = [
|
const artifacts = [
|
||||||
new Artifact('a/art1'),
|
new Artifact('a/art1'),
|
||||||
@@ -19,7 +19,9 @@ const uploadMock = jest.fn()
|
|||||||
jest.mock('fs', () => {
|
jest.mock('fs', () => {
|
||||||
return {
|
return {
|
||||||
readFileSync: () => fileContents,
|
readFileSync: () => fileContents,
|
||||||
statSync: () => { return { size: contentLength } }
|
statSync: () => {
|
||||||
|
return {size: contentLength}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -124,6 +126,19 @@ describe('ArtifactUploader', () => {
|
|||||||
expect(deleteMock).toBeCalledTimes(0)
|
expect(deleteMock).toBeCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('throws upload error when replacesExistingArtifacts is true', async () => {
|
||||||
|
mockListWithoutAssets()
|
||||||
|
mockUploadError()
|
||||||
|
const uploader = createUploader(true, true)
|
||||||
|
|
||||||
|
expect.hasAssertions()
|
||||||
|
try {
|
||||||
|
await uploader.uploadArtifacts(artifacts, releaseId, url)
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toEqual(Error("Failed to upload artifact art1. error."))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
it('throws error from replace', async () => {
|
it('throws error from replace', async () => {
|
||||||
mockDeleteError()
|
mockDeleteError()
|
||||||
mockListWithAssets()
|
mockListWithAssets()
|
||||||
@@ -155,7 +170,7 @@ describe('ArtifactUploader', () => {
|
|||||||
expect(deleteMock).toBeCalledTimes(0)
|
expect(deleteMock).toBeCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
function createUploader(replaces: boolean): GithubArtifactUploader {
|
function createUploader(replaces: boolean, throws: boolean = false): GithubArtifactUploader {
|
||||||
const MockReleases = jest.fn<Releases, any>(() => {
|
const MockReleases = jest.fn<Releases, any>(() => {
|
||||||
return {
|
return {
|
||||||
create: jest.fn(),
|
create: jest.fn(),
|
||||||
@@ -167,7 +182,7 @@ describe('ArtifactUploader', () => {
|
|||||||
uploadArtifact: uploadMock
|
uploadArtifact: uploadMock
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return new GithubArtifactUploader(new MockReleases(), replaces)
|
return new GithubArtifactUploader(new MockReleases(), replaces, throws)
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockDeleteError(): any {
|
function mockDeleteError(): any {
|
||||||
@@ -194,14 +209,24 @@ describe('ArtifactUploader', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mockListWithoutAssets() {
|
function mockListWithoutAssets() {
|
||||||
listArtifactsMock.mockResolvedValue({ data: [] })
|
listArtifactsMock.mockResolvedValue({data: []})
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockUploadArtifact(status: number = 200, failures: number = 0) {
|
function mockUploadArtifact(status: number = 200, failures: number = 0) {
|
||||||
const error = new RequestError(`HTTP ${status}`, status, { headers: {}, request: { method: 'GET', url: '', headers: {} } })
|
const error = new RequestError(`HTTP ${status}`, status, {
|
||||||
|
headers: {},
|
||||||
|
request: {method: 'GET', url: '', headers: {}}
|
||||||
|
})
|
||||||
for (let index = 0; index < failures; index++) {
|
for (let index = 0; index < failures; index++) {
|
||||||
uploadMock.mockRejectedValueOnce(error)
|
uploadMock.mockRejectedValueOnce(error)
|
||||||
}
|
}
|
||||||
uploadMock.mockResolvedValue({})
|
uploadMock.mockResolvedValue({})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mockUploadError() {
|
||||||
|
uploadMock.mockRejectedValue({
|
||||||
|
message: "error",
|
||||||
|
status: 502
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -59,7 +59,28 @@ describe('Inputs', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('artifactErrorsFailBuild', () => {
|
||||||
|
it('returns false', () => {
|
||||||
|
expect(inputs.artifactErrorsFailBuild).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns true', () => {
|
||||||
|
mockGetInput.mockReturnValue('true')
|
||||||
|
expect(inputs.artifactErrorsFailBuild).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('artifacts', () => {
|
describe('artifacts', () => {
|
||||||
|
it('globber told to throw errors', () => {
|
||||||
|
mockGetInput.mockReturnValueOnce('art1')
|
||||||
|
.mockReturnValueOnce('contentType')
|
||||||
|
.mockReturnValueOnce('true')
|
||||||
|
|
||||||
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
|
expect(mockGlob).toBeCalledTimes(1)
|
||||||
|
expect(mockGlob).toBeCalledWith('art1', 'contentType', true)
|
||||||
|
})
|
||||||
|
|
||||||
it('returns empty artifacts', () => {
|
it('returns empty artifacts', () => {
|
||||||
mockGetInput.mockReturnValueOnce('')
|
mockGetInput.mockReturnValueOnce('')
|
||||||
.mockReturnValueOnce('')
|
.mockReturnValueOnce('')
|
||||||
@@ -71,28 +92,32 @@ describe('Inputs', () => {
|
|||||||
it('returns input.artifacts', () => {
|
it('returns input.artifacts', () => {
|
||||||
mockGetInput.mockReturnValueOnce('art1')
|
mockGetInput.mockReturnValueOnce('art1')
|
||||||
.mockReturnValueOnce('contentType')
|
.mockReturnValueOnce('contentType')
|
||||||
|
.mockReturnValueOnce('false')
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual(artifacts)
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
expect(mockGlob).toBeCalledTimes(1)
|
expect(mockGlob).toBeCalledTimes(1)
|
||||||
expect(mockGlob).toBeCalledWith('art1', 'contentType')
|
expect(mockGlob).toBeCalledWith('art1', 'contentType', false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns input.artifacts with default contentType', () => {
|
it('returns input.artifacts with default contentType', () => {
|
||||||
mockGetInput.mockReturnValueOnce('art1')
|
mockGetInput.mockReturnValueOnce('art1')
|
||||||
|
.mockReturnValueOnce('raw')
|
||||||
|
.mockReturnValueOnce('false')
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual(artifacts)
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
expect(mockGlob).toBeCalledTimes(1)
|
expect(mockGlob).toBeCalledTimes(1)
|
||||||
expect(mockGlob).toBeCalledWith('art1', 'raw')
|
expect(mockGlob).toBeCalledWith('art1', 'raw', false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns input.artifact', () => {
|
it('returns input.artifact', () => {
|
||||||
mockGetInput.mockReturnValueOnce('')
|
mockGetInput.mockReturnValueOnce('')
|
||||||
.mockReturnValueOnce('art2')
|
.mockReturnValueOnce('art2')
|
||||||
.mockReturnValueOnce('contentType')
|
.mockReturnValueOnce('contentType')
|
||||||
|
.mockReturnValueOnce('false')
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual(artifacts)
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
expect(mockGlob).toBeCalledTimes(1)
|
expect(mockGlob).toBeCalledTimes(1)
|
||||||
expect(mockGlob).toBeCalledWith('art2', 'contentType')
|
expect(mockGlob).toBeCalledWith('art2', 'contentType', false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -164,7 +189,7 @@ describe('Inputs', () => {
|
|||||||
expect(inputs.draft).toBe(true)
|
expect(inputs.draft).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('owner', () => {
|
describe('owner', () => {
|
||||||
it('returns owner from context', function () {
|
it('returns owner from context', function () {
|
||||||
process.env.GITHUB_REPOSITORY = "owner/repo"
|
process.env.GITHUB_REPOSITORY = "owner/repo"
|
||||||
@@ -175,7 +200,7 @@ describe('Inputs', () => {
|
|||||||
mockGetInput.mockReturnValue("owner")
|
mockGetInput.mockReturnValue("owner")
|
||||||
expect(inputs.owner).toBe("owner")
|
expect(inputs.owner).toBe("owner")
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('prerelase', () => {
|
describe('prerelase', () => {
|
||||||
it('returns false', () => {
|
it('returns false', () => {
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ describe.skip('Integration Test', () => {
|
|||||||
|
|
||||||
const inputs = getInputs()
|
const inputs = getInputs()
|
||||||
const releases = new GithubReleases(inputs, git)
|
const releases = new GithubReleases(inputs, git)
|
||||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts)
|
const uploader = new GithubArtifactUploader(
|
||||||
|
releases,
|
||||||
|
inputs.artifactErrorsFailBuild,
|
||||||
|
inputs.replacesArtifacts
|
||||||
|
)
|
||||||
action = new Action(inputs, releases, uploader)
|
action = new Action(inputs, releases, uploader)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -30,6 +34,7 @@ describe.skip('Integration Test', () => {
|
|||||||
const MockInputs = jest.fn<Inputs, any>(() => {
|
const MockInputs = jest.fn<Inputs, any>(() => {
|
||||||
return {
|
return {
|
||||||
allowUpdates: true,
|
allowUpdates: true,
|
||||||
|
artifactErrorsFailBuild: false,
|
||||||
artifacts: artifacts(),
|
artifacts: artifacts(),
|
||||||
createdReleaseBody: "This release was generated by release-action's integration test",
|
createdReleaseBody: "This release was generated by release-action's integration test",
|
||||||
createdReleaseName: "Releases Action Integration Test",
|
createdReleaseName: "Releases Action Integration Test",
|
||||||
@@ -47,12 +52,12 @@ describe.skip('Integration Test', () => {
|
|||||||
})
|
})
|
||||||
return new MockInputs();
|
return new MockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
function artifacts() {
|
function artifacts() {
|
||||||
const globber = new FileArtifactGlobber()
|
const globber = new FileArtifactGlobber()
|
||||||
const artifactPath = path.join(__dirname, 'Integration.test.ts')
|
const artifactPath = path.join(__dirname, 'Integration.test.ts')
|
||||||
const artifactString = `~/Desktop/test.txt,blarg.tx, ${artifactPath}`
|
const artifactString = `~/Desktop/test.txt,blarg.tx, ${artifactPath}`
|
||||||
return globber.globArtifactString(artifactString, "raw")
|
return globber.globArtifactString(artifactString, "raw", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getToken(): string {
|
function getToken(): string {
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ inputs:
|
|||||||
description: 'An optional flag which indicates if we should update a release if it already exists. Defaults to false.'
|
description: 'An optional flag which indicates if we should update a release if it already exists. Defaults to false.'
|
||||||
required: false
|
required: false
|
||||||
default: ''
|
default: ''
|
||||||
|
artifactErrorsFailBuild:
|
||||||
|
description: 'An optional flag which indicates if artifact read or upload errors should fail the build.'
|
||||||
|
required: false
|
||||||
|
default: ''
|
||||||
artifact:
|
artifact:
|
||||||
deprecationMessage: Use 'artifacts' instead.
|
deprecationMessage: Use 'artifacts' instead.
|
||||||
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)'
|
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)'
|
||||||
|
|||||||
@@ -80,8 +80,7 @@ class Action {
|
|||||||
}
|
}
|
||||||
createRelease() {
|
createRelease() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const response = yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.draft, this.inputs.createdReleaseName, this.inputs.prerelease);
|
return yield this.releases.create(this.inputs.tag, this.inputs.createdReleaseBody, this.inputs.commit, this.inputs.draft, this.inputs.createdReleaseName, this.inputs.prerelease);
|
||||||
return response;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,23 +31,31 @@ class FileArtifactGlobber {
|
|||||||
constructor(globber = new Globber_1.FileGlobber()) {
|
constructor(globber = new Globber_1.FileGlobber()) {
|
||||||
this.globber = globber;
|
this.globber = globber;
|
||||||
}
|
}
|
||||||
globArtifactString(artifact, contentType) {
|
globArtifactString(artifact, contentType, throwsWhenNoFiles) {
|
||||||
return artifact.split(',')
|
return artifact.split(',')
|
||||||
.map(path => FileArtifactGlobber.expandPath(path))
|
.map(path => FileArtifactGlobber.expandPath(path))
|
||||||
.map(pattern => this.globPattern(pattern))
|
.map(pattern => this.globPattern(pattern, throwsWhenNoFiles))
|
||||||
.reduce((accumulated, current) => accumulated.concat(current))
|
.reduce((accumulated, current) => accumulated.concat(current))
|
||||||
.map(path => new Artifact_1.Artifact(path, contentType));
|
.map(path => new Artifact_1.Artifact(path, contentType));
|
||||||
}
|
}
|
||||||
globPattern(pattern) {
|
globPattern(pattern, throwsWhenNoFiles) {
|
||||||
const paths = this.globber.glob(pattern);
|
const paths = this.globber.glob(pattern);
|
||||||
if (paths.length == 0) {
|
if (paths.length == 0) {
|
||||||
FileArtifactGlobber.reportGlobWarning(pattern);
|
if (throwsWhenNoFiles) {
|
||||||
|
FileArtifactGlobber.throwGlobError(pattern);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FileArtifactGlobber.reportGlobWarning(pattern);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
static reportGlobWarning(pattern) {
|
static reportGlobWarning(pattern) {
|
||||||
core.warning(`Artifact pattern :${pattern} did not match any files`);
|
core.warning(`Artifact pattern :${pattern} did not match any files`);
|
||||||
}
|
}
|
||||||
|
static throwGlobError(pattern) {
|
||||||
|
throw Error(`Artifact pattern :${pattern} did not match any files`);
|
||||||
|
}
|
||||||
static expandPath(path) {
|
static expandPath(path) {
|
||||||
return untildify_1.default(path);
|
return untildify_1.default(path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
exports.GithubArtifactUploader = void 0;
|
exports.GithubArtifactUploader = void 0;
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
class GithubArtifactUploader {
|
class GithubArtifactUploader {
|
||||||
constructor(releases, replacesExistingArtifacts = true) {
|
constructor(releases, replacesExistingArtifacts = true, throwsUploadErrors = false) {
|
||||||
this.releases = releases;
|
this.releases = releases;
|
||||||
this.replacesExistingArtifacts = replacesExistingArtifacts;
|
this.replacesExistingArtifacts = replacesExistingArtifacts;
|
||||||
|
this.throwsUploadErrors = throwsUploadErrors;
|
||||||
}
|
}
|
||||||
uploadArtifacts(artifacts, releaseId, uploadUrl) {
|
uploadArtifacts(artifacts, releaseId, uploadUrl) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
@@ -57,7 +58,12 @@ class GithubArtifactUploader {
|
|||||||
yield this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1);
|
yield this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
if (this.throwsUploadErrors) {
|
||||||
|
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,10 +42,14 @@ class CoreInputs {
|
|||||||
contentType = 'raw';
|
contentType = 'raw';
|
||||||
}
|
}
|
||||||
return this.artifactGlobber
|
return this.artifactGlobber
|
||||||
.globArtifactString(artifacts, contentType);
|
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
get artifactErrorsFailBuild() {
|
||||||
|
const allow = core.getInput('artifactErrorsFailBuild');
|
||||||
|
return allow == 'true';
|
||||||
|
}
|
||||||
get createdReleaseBody() {
|
get createdReleaseBody() {
|
||||||
if (CoreInputs.omitBody)
|
if (CoreInputs.omitBody)
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export class Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async createRelease(): Promise<CreateReleaseResponse> {
|
private async createRelease(): Promise<CreateReleaseResponse> {
|
||||||
const response = await this.releases.create(
|
return await this.releases.create(
|
||||||
this.inputs.tag,
|
this.inputs.tag,
|
||||||
this.inputs.createdReleaseBody,
|
this.inputs.createdReleaseBody,
|
||||||
this.inputs.commit,
|
this.inputs.commit,
|
||||||
@@ -86,7 +86,5 @@ export class Action {
|
|||||||
this.inputs.createdReleaseName,
|
this.inputs.createdReleaseName,
|
||||||
this.inputs.prerelease
|
this.inputs.prerelease
|
||||||
)
|
)
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {Artifact} from "./Artifact";
|
|||||||
import untildify from "untildify";
|
import untildify from "untildify";
|
||||||
|
|
||||||
export interface ArtifactGlobber {
|
export interface ArtifactGlobber {
|
||||||
globArtifactString(artifact: string, contentType: string): Artifact[]
|
globArtifactString(artifact: string, contentType: string, throwsWhenNoFiles: boolean): Artifact[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FileArtifactGlobber implements ArtifactGlobber {
|
export class FileArtifactGlobber implements ArtifactGlobber {
|
||||||
@@ -14,18 +14,22 @@ export class FileArtifactGlobber implements ArtifactGlobber {
|
|||||||
this.globber = globber
|
this.globber = globber
|
||||||
}
|
}
|
||||||
|
|
||||||
globArtifactString(artifact: string, contentType: string): Artifact[] {
|
globArtifactString(artifact: string, contentType: string, throwsWhenNoFiles: boolean): Artifact[] {
|
||||||
return artifact.split(',')
|
return artifact.split(',')
|
||||||
.map(path => FileArtifactGlobber.expandPath(path))
|
.map(path => FileArtifactGlobber.expandPath(path))
|
||||||
.map(pattern => this.globPattern(pattern))
|
.map(pattern => this.globPattern(pattern, throwsWhenNoFiles))
|
||||||
.reduce((accumulated, current) => accumulated.concat(current))
|
.reduce((accumulated, current) => accumulated.concat(current))
|
||||||
.map(path => new Artifact(path, contentType))
|
.map(path => new Artifact(path, contentType))
|
||||||
}
|
}
|
||||||
|
|
||||||
private globPattern(pattern: string): string[] {
|
private globPattern(pattern: string, throwsWhenNoFiles: boolean): string[] {
|
||||||
const paths = this.globber.glob(pattern)
|
const paths = this.globber.glob(pattern)
|
||||||
if (paths.length == 0) {
|
if (paths.length == 0) {
|
||||||
FileArtifactGlobber.reportGlobWarning(pattern)
|
if (throwsWhenNoFiles) {
|
||||||
|
FileArtifactGlobber.throwGlobError(pattern)
|
||||||
|
} else {
|
||||||
|
FileArtifactGlobber.reportGlobWarning(pattern)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
@@ -34,6 +38,10 @@ export class FileArtifactGlobber implements ArtifactGlobber {
|
|||||||
core.warning(`Artifact pattern :${pattern} did not match any files`)
|
core.warning(`Artifact pattern :${pattern} did not match any files`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static throwGlobError(pattern: string) {
|
||||||
|
throw Error(`Artifact pattern :${pattern} did not match any files`)
|
||||||
|
}
|
||||||
|
|
||||||
private static expandPath(path: string): string {
|
private static expandPath(path: string): string {
|
||||||
return untildify(path)
|
return untildify(path)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export class GithubArtifactUploader implements ArtifactUploader {
|
|||||||
constructor(
|
constructor(
|
||||||
private releases: Releases,
|
private releases: Releases,
|
||||||
private replacesExistingArtifacts: boolean = true,
|
private replacesExistingArtifacts: boolean = true,
|
||||||
|
private throwsUploadErrors: boolean = false,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +42,11 @@ export class GithubArtifactUploader implements ArtifactUploader {
|
|||||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}. Retrying...`)
|
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}. Retrying...`)
|
||||||
await this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1)
|
await this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1)
|
||||||
} else {
|
} else {
|
||||||
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
if (this.throwsUploadErrors) {
|
||||||
|
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||||
|
} else {
|
||||||
|
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {Artifact} from './Artifact';
|
|||||||
|
|
||||||
export interface Inputs {
|
export interface Inputs {
|
||||||
readonly allowUpdates: boolean
|
readonly allowUpdates: boolean
|
||||||
|
readonly artifactErrorsFailBuild: boolean
|
||||||
readonly artifacts: Artifact[]
|
readonly artifacts: Artifact[]
|
||||||
readonly commit: string
|
readonly commit: string
|
||||||
readonly createdReleaseBody?: string
|
readonly createdReleaseBody?: string
|
||||||
@@ -46,11 +47,16 @@ export class CoreInputs implements Inputs {
|
|||||||
contentType = 'raw'
|
contentType = 'raw'
|
||||||
}
|
}
|
||||||
return this.artifactGlobber
|
return this.artifactGlobber
|
||||||
.globArtifactString(artifacts, contentType)
|
.globArtifactString(artifacts, contentType, this.artifactErrorsFailBuild)
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get artifactErrorsFailBuild(): boolean {
|
||||||
|
const allow = core.getInput('artifactErrorsFailBuild')
|
||||||
|
return allow == 'true'
|
||||||
|
}
|
||||||
|
|
||||||
get createdReleaseBody(): string | undefined {
|
get createdReleaseBody(): string | undefined {
|
||||||
if (CoreInputs.omitBody) return undefined
|
if (CoreInputs.omitBody) return undefined
|
||||||
return this.body
|
return this.body
|
||||||
|
|||||||
Reference in New Issue
Block a user