Add removeArtifacts (#109)

This commit is contained in:
Rosalie
2021-09-07 00:57:37 +02:00
committed by GitHub
parent a4f828a4e5
commit f597c8ad62
12 changed files with 81 additions and 6 deletions

View File

@@ -22,6 +22,7 @@ This action will create a GitHub release and optionally upload an artifact to it
This will preserve the existing prerelease state during updates. This will preserve the existing prerelease state during updates.
- **owner**: Optionally specify the owner of the repo where the release should be generated. Defaults to current repo's owner. - **owner**: Optionally specify the owner of the repo where the release should be generated. Defaults to current repo's owner.
- **prerelease**: Optionally marks this release as prerelease. Set to true to enable. - **prerelease**: Optionally marks this release as prerelease. Set to true to enable.
- **removeArtifacts**: Indicates if existing release artifacts should be removed. Defaults to `false`.
- **replacesArtifacts**: Indicates if existing release artifacts should be replaced. Defaults to `true`. - **replacesArtifacts**: Indicates if existing release artifacts should be replaced. Defaults to `true`.
- **repo**: Optionally specify the repo where the release should be generated. Defaults to current repo. - **repo**: Optionally specify the repo where the release should be generated. Defaults to current repo.
- **tag**: An optional tag for the release. If this is omitted the git ref will be used (if it is a tag). - **tag**: An optional tag for the release. If this is omitted the git ref will be used (if it is a tag).

View File

@@ -29,6 +29,7 @@ const createPrerelease = true
const updatePrerelease = false const updatePrerelease = false
const releaseId = 101 const releaseId = 101
const replacesArtifacts = true const replacesArtifacts = true
const removeArtifacts = false
const tag = 'tag' const tag = 'tag'
const token = 'token' const token = 'token'
const updateBody = 'updateBody' const updateBody = 'updateBody'
@@ -298,6 +299,7 @@ describe("Action", () => {
owner: "owner", owner: "owner",
createdPrerelease: createPrerelease, createdPrerelease: createPrerelease,
replacesArtifacts: replacesArtifacts, replacesArtifacts: replacesArtifacts,
removeArtifacts: removeArtifacts,
repo: "repo", repo: "repo",
tag: tag, tag: tag,
token: token, token: token,

View File

@@ -89,6 +89,25 @@ describe('ArtifactUploader', () => {
expect(deleteMock).toBeCalledWith(2) expect(deleteMock).toBeCalledWith(2)
}) })
it('removes all artifacts', async () => {
mockDeleteSuccess()
mockListWithAssets()
mockUploadArtifact()
const uploader = createUploader(false, true)
await uploader.uploadArtifacts(artifacts, releaseId, url)
expect(uploadMock).toBeCalledTimes(2)
expect(uploadMock)
.toBeCalledWith(url, contentLength, 'raw', fileContents, 'art1', releaseId)
expect(uploadMock)
.toBeCalledWith(url, contentLength, 'raw', fileContents, 'art2', releaseId)
expect(deleteMock).toBeCalledTimes(2)
expect(deleteMock).toBeCalledWith(1)
expect(deleteMock).toBeCalledWith(2)
})
it('replaces no artifacts when previous asset list empty', async () => { it('replaces no artifacts when previous asset list empty', async () => {
mockDeleteSuccess() mockDeleteSuccess()
mockListWithoutAssets() mockListWithoutAssets()
@@ -129,7 +148,7 @@ describe('ArtifactUploader', () => {
it('throws upload error when replacesExistingArtifacts is true', async () => { it('throws upload error when replacesExistingArtifacts is true', async () => {
mockListWithoutAssets() mockListWithoutAssets()
mockUploadError() mockUploadError()
const uploader = createUploader(true, true) const uploader = createUploader(true, false, true)
expect.hasAssertions() expect.hasAssertions()
try { try {
@@ -170,7 +189,7 @@ describe('ArtifactUploader', () => {
expect(deleteMock).toBeCalledTimes(0) expect(deleteMock).toBeCalledTimes(0)
}) })
function createUploader(replaces: boolean, throws: boolean = false): GithubArtifactUploader { function createUploader(replaces: boolean, removes: boolean = false, throws: boolean = false): GithubArtifactUploader {
const MockReleases = jest.fn<Releases, any>(() => { const MockReleases = jest.fn<Releases, any>(() => {
return { return {
create: jest.fn(), create: jest.fn(),
@@ -182,7 +201,7 @@ describe('ArtifactUploader', () => {
uploadArtifact: uploadMock uploadArtifact: uploadMock
} }
}) })
return new GithubArtifactUploader(new MockReleases(), replaces, throws) return new GithubArtifactUploader(new MockReleases(), replaces, removes, throws)
} }
function mockDeleteError(): any { function mockDeleteError(): any {

View File

@@ -236,6 +236,17 @@ describe('Inputs', () => {
}) })
}) })
describe('removeArtifacts', () => {
it('returns false', () => {
expect(inputs.removeArtifacts).toBe(false)
})
it('returns true', () => {
mockGetInput.mockReturnValue('true')
expect(inputs.removeArtifacts).toBe(true)
})
})
describe('repo', () => { describe('repo', () => {
it('returns repo from context', function () { it('returns repo from context', function () {
process.env.GITHUB_REPOSITORY = "owner/repo" process.env.GITHUB_REPOSITORY = "owner/repo"

View File

@@ -23,6 +23,7 @@ describe.skip('Integration Test', () => {
const uploader = new GithubArtifactUploader( const uploader = new GithubArtifactUploader(
releases, releases,
inputs.replacesArtifacts, inputs.replacesArtifacts,
inputs.removeArtifacts,
inputs.artifactErrorsFailBuild, inputs.artifactErrorsFailBuild,
) )
action = new Action(inputs, outputs, releases, uploader) action = new Action(inputs, outputs, releases, uploader)
@@ -46,6 +47,7 @@ describe.skip('Integration Test', () => {
owner: "ncipollo", owner: "ncipollo",
createdPrerelease: false, createdPrerelease: false,
replacesArtifacts: true, replacesArtifacts: true,
removeArtifacts: false,
repo: "actions-playground", repo: "actions-playground",
tag: "release-action-test", tag: "release-action-test",
token: getToken(), token: getToken(),

View File

@@ -75,6 +75,10 @@ inputs:
description: "Optionally marks this release as prerelease. Set to true to enable." description: "Optionally marks this release as prerelease. Set to true to enable."
required: false required: false
default: '' default: ''
removeArtifacts:
description: 'Indicates if existing release artifacts should be removed, Defaults to false.'
required: false
default: 'false'
replacesArtifacts: replacesArtifacts:
description: "Indicates if existing release artifacts should be replaced. Defaults to true." description: "Indicates if existing release artifacts should be replaced. Defaults to true."
required: false required: false

View File

@@ -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, throwsUploadErrors = false) { constructor(releases, replacesExistingArtifacts = true, removeArtifacts = false, throwsUploadErrors = false) {
this.releases = releases; this.releases = releases;
this.replacesExistingArtifacts = replacesExistingArtifacts; this.replacesExistingArtifacts = replacesExistingArtifacts;
this.removeArtifacts = removeArtifacts;
this.throwsUploadErrors = throwsUploadErrors; this.throwsUploadErrors = throwsUploadErrors;
} }
uploadArtifacts(artifacts, releaseId, uploadUrl) { uploadArtifacts(artifacts, releaseId, uploadUrl) {
@@ -41,6 +42,9 @@ class GithubArtifactUploader {
if (this.replacesExistingArtifacts) { if (this.replacesExistingArtifacts) {
yield this.deleteUpdatedArtifacts(artifacts, releaseId); yield this.deleteUpdatedArtifacts(artifacts, releaseId);
} }
if (this.removeArtifacts) {
yield this.deleteUploadedArtifacts(releaseId);
}
for (const artifact of artifacts) { for (const artifact of artifacts) {
yield this.uploadArtifact(artifact, releaseId, uploadUrl); yield this.uploadArtifact(artifact, releaseId, uploadUrl);
} }
@@ -84,5 +88,15 @@ class GithubArtifactUploader {
} }
}); });
} }
deleteUploadedArtifacts(releaseId) {
return __awaiter(this, void 0, void 0, function* () {
const releaseAssets = yield this.releases.listArtifactsForRelease(releaseId);
for (const artifact of releaseAssets) {
const asset = artifact;
core.debug(`Deleting existing artifact ${artifact.name}...`);
yield this.releases.deleteArtifact(asset.id);
}
});
}
} }
exports.GithubArtifactUploader = GithubArtifactUploader; exports.GithubArtifactUploader = GithubArtifactUploader;

View File

@@ -117,6 +117,10 @@ class CoreInputs {
return undefined; return undefined;
return this.createdPrerelease; return this.createdPrerelease;
} }
get removeArtifacts() {
const removes = core.getInput('removeArtifacts');
return removes == 'true';
}
get replacesArtifacts() { get replacesArtifacts() {
const replaces = core.getInput('replacesArtifacts'); const replaces = core.getInput('replacesArtifacts');
return replaces == 'true'; return replaces == 'true';

View File

@@ -57,7 +57,7 @@ function createAction() {
const inputs = new Inputs_1.CoreInputs(globber, context); const inputs = new Inputs_1.CoreInputs(globber, context);
const outputs = new Outputs_1.CoreOutputs(); const outputs = new Outputs_1.CoreOutputs();
const releases = new Releases_1.GithubReleases(inputs, git); const releases = new Releases_1.GithubReleases(inputs, git);
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild); const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.removeArtifacts, inputs.artifactErrorsFailBuild);
return new Action_1.Action(inputs, outputs, releases, uploader); return new Action_1.Action(inputs, outputs, releases, uploader);
} }
run(); run();

View File

@@ -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 removeArtifacts: boolean = false,
private throwsUploadErrors: boolean = false, private throwsUploadErrors: boolean = false,
) { ) {
} }
@@ -20,6 +21,9 @@ export class GithubArtifactUploader implements ArtifactUploader {
if (this.replacesExistingArtifacts) { if (this.replacesExistingArtifacts) {
await this.deleteUpdatedArtifacts(artifacts, releaseId) await this.deleteUpdatedArtifacts(artifacts, releaseId)
} }
if (this.removeArtifacts) {
await this.deleteUploadedArtifacts(releaseId)
}
for (const artifact of artifacts) { for (const artifact of artifacts) {
await this.uploadArtifact(artifact, releaseId, uploadUrl) await this.uploadArtifact(artifact, releaseId, uploadUrl)
} }
@@ -65,4 +69,13 @@ export class GithubArtifactUploader implements ArtifactUploader {
} }
} }
} }
private async deleteUploadedArtifacts(releaseId: number): Promise<void> {
const releaseAssets = await this.releases.listArtifactsForRelease(releaseId)
for (const artifact of releaseAssets) {
const asset = artifact
core.debug(`Deleting existing artifact ${artifact.name}...`)
await this.releases.deleteArtifact(asset.id)
}
}
} }

View File

@@ -15,6 +15,7 @@ export interface Inputs {
readonly draft: boolean readonly draft: boolean
readonly owner: string readonly owner: string
readonly createdPrerelease: boolean readonly createdPrerelease: boolean
readonly removeArtifacts: boolean
readonly replacesArtifacts: boolean readonly replacesArtifacts: boolean
readonly repo: string readonly repo: string
readonly tag: string readonly tag: string
@@ -138,6 +139,10 @@ export class CoreInputs implements Inputs {
if (CoreInputs.omitPrereleaseDuringUpdate) return undefined if (CoreInputs.omitPrereleaseDuringUpdate) return undefined
return this.createdPrerelease return this.createdPrerelease
} }
get removeArtifacts(): boolean {
const removes = core.getInput('removeArtifacts')
return removes == 'true'
}
get replacesArtifacts(): boolean { get replacesArtifacts(): boolean {
const replaces = core.getInput('replacesArtifacts') const replaces = core.getInput('replacesArtifacts')
return replaces == 'true' return replaces == 'true'

View File

@@ -27,7 +27,7 @@ function createAction(): Action {
const inputs = new CoreInputs(globber, context) const inputs = new CoreInputs(globber, context)
const outputs = new CoreOutputs() const outputs = new CoreOutputs()
const releases = new GithubReleases(inputs, git) const releases = new GithubReleases(inputs, git)
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild) const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.removeArtifacts, inputs.artifactErrorsFailBuild)
return new Action(inputs, outputs, releases, uploader) return new Action(inputs, outputs, releases, uploader)
} }