Fixes #12 Artifacts will now be replaced
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Inputs } from "./Inputs";
|
||||
import { Releases } from "./Releases";
|
||||
import { ReposCreateReleaseResponse } from "@octokit/rest";
|
||||
import { ArtifactUploader } from "./ArtifactUploader";
|
||||
import { ErrorMessage } from "./ErrorMessage";
|
||||
|
||||
@@ -15,15 +16,17 @@ export class Action {
|
||||
}
|
||||
|
||||
async perform() {
|
||||
const uploadUrl = await this.createOrUpdateRelease()
|
||||
const releaseResponse = await this.createOrUpdateRelease();
|
||||
const releaseId = releaseResponse.id
|
||||
const uploadUrl = releaseResponse.upload_url
|
||||
|
||||
const artifacts = this.inputs.artifacts
|
||||
if (artifacts.length > 0) {
|
||||
await this.uploader.uploadArtifacts(artifacts, uploadUrl)
|
||||
await this.uploader.uploadArtifacts(artifacts, releaseId, uploadUrl)
|
||||
}
|
||||
}
|
||||
|
||||
private async createOrUpdateRelease(): Promise<string> {
|
||||
private async createOrUpdateRelease(): Promise<ReposCreateReleaseResponse> {
|
||||
if (this.inputs.allowUpdates) {
|
||||
try {
|
||||
const getResponse = await this.releases.getByTag(this.inputs.tag)
|
||||
@@ -40,7 +43,7 @@ export class Action {
|
||||
}
|
||||
}
|
||||
|
||||
private async updateRelease(id: number): Promise<string> {
|
||||
private async updateRelease(id: number): Promise<ReposCreateReleaseResponse> {
|
||||
const response = await this.releases.update(
|
||||
id,
|
||||
this.inputs.tag,
|
||||
@@ -51,7 +54,7 @@ export class Action {
|
||||
this.inputs.prerelease
|
||||
)
|
||||
|
||||
return response.data.upload_url
|
||||
return response.data
|
||||
}
|
||||
|
||||
private noPublishedRelease(error: any): boolean {
|
||||
@@ -59,7 +62,7 @@ export class Action {
|
||||
return errorMessage.status == 404
|
||||
}
|
||||
|
||||
private async updateDraftOrCreateRelease(): Promise<string> {
|
||||
private async updateDraftOrCreateRelease(): Promise<ReposCreateReleaseResponse> {
|
||||
const draftReleaseId = await this.findMatchingDraftReleaseId()
|
||||
if (draftReleaseId) {
|
||||
return await this.updateRelease(draftReleaseId)
|
||||
@@ -77,7 +80,7 @@ export class Action {
|
||||
return draftRelease?.id
|
||||
}
|
||||
|
||||
private async createRelease(): Promise<string> {
|
||||
private async createRelease(): Promise<ReposCreateReleaseResponse> {
|
||||
const response = await this.releases.create(
|
||||
this.inputs.tag,
|
||||
this.inputs.body,
|
||||
@@ -87,6 +90,6 @@ export class Action {
|
||||
this.inputs.prerelease
|
||||
)
|
||||
|
||||
return response.data.upload_url
|
||||
return response.data
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,56 @@
|
||||
import * as core from '@actions/core';
|
||||
import { Artifact } from "./Artifact";
|
||||
import { Releases } from "./Releases";
|
||||
import { ReposListAssetsForReleaseResponseItem } from "@octokit/rest";
|
||||
import { ErrorMessage } from './ErrorMessage';
|
||||
|
||||
export interface ArtifactUploader {
|
||||
uploadArtifacts(artifacts: Artifact[], uploadUrl: string): Promise<void>
|
||||
uploadArtifacts(artifacts: Artifact[], releaseId: number, uploadUrl: string): Promise<void>
|
||||
}
|
||||
|
||||
export class GithubArtifactUploader implements ArtifactUploader {
|
||||
private releases: Releases
|
||||
private replacesExistingArtifacts: boolean = true
|
||||
|
||||
constructor(releases: Releases) {
|
||||
constructor(releases: Releases, replacesExistingArtifacts: boolean) {
|
||||
this.releases = releases
|
||||
this.replacesExistingArtifacts = replacesExistingArtifacts
|
||||
}
|
||||
|
||||
async uploadArtifacts(artifacts: Artifact[], uploadUrl: string) {
|
||||
artifacts.forEach(async artifact => {
|
||||
async uploadArtifacts(artifacts: Artifact[],
|
||||
releaseId: number,
|
||||
uploadUrl: string): Promise<void> {
|
||||
if(this.replacesExistingArtifacts) {
|
||||
await this.deleteUpdatedArtifacts(artifacts, releaseId)
|
||||
}
|
||||
|
||||
for (const artifact of artifacts) {
|
||||
try {
|
||||
await this.releases.uploadArtifact(uploadUrl,
|
||||
artifact.contentLength,
|
||||
artifact.contentType,
|
||||
artifact.readFile(),
|
||||
artifact.name)
|
||||
} catch(error) {
|
||||
} catch (error) {
|
||||
const message = `Failed to upload artifact ${artifact.name}. Does it already exist?`
|
||||
core.warning(message)
|
||||
}
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
async deleteUpdatedArtifacts(artifacts: Artifact[], releaseId: number) {
|
||||
const response = await this.releases.listArtifactsForRelease(releaseId)
|
||||
const releaseAssets = response.data
|
||||
const assetByName = new Map<string, ReposListAssetsForReleaseResponseItem>()
|
||||
releaseAssets.forEach(asset => {
|
||||
assetByName[asset.name] = asset
|
||||
});
|
||||
for (const artifact of artifacts) {
|
||||
const asset = assetByName[artifact.name]
|
||||
if (asset) {
|
||||
await this.releases.deleteArtifact(asset.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ export interface Inputs {
|
||||
readonly draft: boolean
|
||||
readonly name: string
|
||||
readonly prerelease: boolean
|
||||
readonly replacesArtifacts: boolean
|
||||
readonly tag: string
|
||||
readonly token: string
|
||||
}
|
||||
@@ -79,8 +80,13 @@ export class CoreInputs implements Inputs {
|
||||
}
|
||||
|
||||
get prerelease(): boolean {
|
||||
const draft = core.getInput('prerelease')
|
||||
return draft == 'true'
|
||||
const preRelease = core.getInput('prerelease')
|
||||
return preRelease == 'true'
|
||||
}
|
||||
|
||||
get replacesArtifacts(): boolean {
|
||||
const replaces = core.getInput('replacesArtifacts')
|
||||
return replaces == 'true'
|
||||
}
|
||||
|
||||
get tag(): string {
|
||||
|
||||
@@ -25,7 +25,7 @@ function createAction(): Action {
|
||||
|
||||
const inputs = new CoreInputs(globber, context)
|
||||
const releases = new GithubReleases(context, git)
|
||||
const uploader = new GithubArtifactUploader(releases)
|
||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts)
|
||||
return new Action(inputs, releases, uploader)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Context } from "@actions/github/lib/context";
|
||||
import { GitHub } from "@actions/github";
|
||||
import { AnyResponse, Response, ReposCreateReleaseResponse, ReposGetReleaseByTagResponse, ReposListReleasesResponse } from "@octokit/rest";
|
||||
import { AnyResponse, Response, ReposDeleteReleaseAssetResponse, ReposListAssetsForReleaseResponse, ReposCreateReleaseResponse, ReposGetReleaseByTagResponse, ReposListReleasesResponse } from "@octokit/rest";
|
||||
|
||||
export interface Releases {
|
||||
create(
|
||||
@@ -12,8 +12,12 @@ export interface Releases {
|
||||
prerelease?: boolean
|
||||
): Promise<Response<ReposCreateReleaseResponse>>
|
||||
|
||||
deleteArtifact(assetId: number): Promise<Response<ReposDeleteReleaseAssetResponse>>
|
||||
|
||||
getByTag(tag: string): Promise<Response<ReposGetReleaseByTagResponse>>
|
||||
|
||||
listArtifactsForRelease(releaseId: number): Promise<Response<ReposListAssetsForReleaseResponse>>
|
||||
|
||||
listReleases(): Promise<Response<ReposListReleasesResponse>>
|
||||
|
||||
update(
|
||||
@@ -64,6 +68,26 @@ export class GithubReleases implements Releases {
|
||||
})
|
||||
}
|
||||
|
||||
async deleteArtifact(
|
||||
assetId: number
|
||||
): Promise<Response<ReposDeleteReleaseAssetResponse>> {
|
||||
return this.git.repos.deleteReleaseAsset({
|
||||
asset_id: assetId,
|
||||
owner: this.context.repo.owner,
|
||||
repo: this.context.repo.repo
|
||||
})
|
||||
}
|
||||
|
||||
async listArtifactsForRelease(
|
||||
releaseId: number
|
||||
): Promise<Response<ReposListAssetsForReleaseResponse>> {
|
||||
return this.git.repos.listAssetsForRelease({
|
||||
owner: this.context.repo.owner,
|
||||
release_id: releaseId,
|
||||
repo: this.context.repo.repo
|
||||
})
|
||||
}
|
||||
|
||||
async listReleases(): Promise<Response<ReposListReleasesResponse>> {
|
||||
return this.git.repos.listReleases({
|
||||
owner: this.context.repo.owner,
|
||||
|
||||
Reference in New Issue
Block a user