Fixes #267 Add ActionSkipper
This commit is contained in:
@@ -37,6 +37,7 @@ This action will create a GitHub release and optionally upload an artifact to it
|
|||||||
| removeArtifacts | Indicates if existing release artifacts should be removed. | false | false |
|
| removeArtifacts | Indicates if existing release artifacts should be removed. | false | false |
|
||||||
| replacesArtifacts | Indicates if existing release artifacts should be replaced. | false | true |
|
| replacesArtifacts | Indicates if existing release artifacts should be replaced. | false | true |
|
||||||
| repo | Optionally specify the repo where the release should be generated. | false | current repo |
|
| repo | Optionally specify the repo where the release should be generated. | false | current repo |
|
||||||
|
| skipIfReleaseExists | When skipIfReleaseExists is enabled the action will be skipped if a non-draft release already exists for the provided tag. | false | current repo |
|
||||||
| tag | An optional tag for the release. If this is omitted the git ref will be used (if it is a tag). | false | "" |
|
| tag | An optional tag for the release. If this is omitted the git ref will be used (if it is a tag). | false | "" |
|
||||||
| token | The GitHub token. This will default to the GitHub app token. This is primarily useful if you want to use your personal token (for targeting other repos, etc). If you are using a personal access token it should have access to the `repo` scope. | false | github.token |
|
| token | The GitHub token. This will default to the GitHub app token. This is primarily useful if you want to use your personal token (for targeting other repos, etc). If you are using a personal access token it should have access to the `repo` scope. | false | github.token |
|
||||||
| updateOnlyUnreleased | When allowUpdates is enabled, this will fail the action if the release it is updating is not a draft or a prerelease. | false | false |
|
| updateOnlyUnreleased | When allowUpdates is enabled, this will fail the action if the release it is updating is not a draft or a prerelease. | false | false |
|
||||||
@@ -71,8 +72,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
artifacts: "release.tar.gz,foo/*.txt"
|
artifacts: "release.tar.gz,foo/*.txt"
|
||||||
bodyFile: "body.md"
|
bodyFile: "body.md"
|
||||||
token: ${{ secrets.YOUR_GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|||||||
@@ -5,16 +5,18 @@ import {Releases} from "../src/Releases";
|
|||||||
import {ArtifactUploader} from "../src/ArtifactUploader";
|
import {ArtifactUploader} from "../src/ArtifactUploader";
|
||||||
import {Outputs} from "../src/Outputs";
|
import {Outputs} from "../src/Outputs";
|
||||||
import {ArtifactDestroyer} from "../src/ArtifactDestroyer";
|
import {ArtifactDestroyer} from "../src/ArtifactDestroyer";
|
||||||
|
import {ActionSkipper} from "../src/ActionSkipper";
|
||||||
|
|
||||||
const applyReleaseDataMock = jest.fn()
|
const applyReleaseDataMock = jest.fn()
|
||||||
|
const artifactDestroyMock = jest.fn()
|
||||||
const createMock = jest.fn()
|
const createMock = jest.fn()
|
||||||
const deleteMock = jest.fn()
|
const deleteMock = jest.fn()
|
||||||
const getMock = jest.fn()
|
const getMock = jest.fn()
|
||||||
const listArtifactsMock = jest.fn()
|
const listArtifactsMock = jest.fn()
|
||||||
const listMock = jest.fn()
|
const listMock = jest.fn()
|
||||||
|
const shouldSkipMock = jest.fn()
|
||||||
const updateMock = jest.fn()
|
const updateMock = jest.fn()
|
||||||
const uploadMock = jest.fn()
|
const uploadMock = jest.fn()
|
||||||
const artifactDestroyMock = jest.fn()
|
|
||||||
|
|
||||||
const artifacts = [
|
const artifacts = [
|
||||||
new Artifact('a/art1'),
|
new Artifact('a/art1'),
|
||||||
@@ -45,6 +47,7 @@ describe("Action", () => {
|
|||||||
createMock.mockClear()
|
createMock.mockClear()
|
||||||
getMock.mockClear()
|
getMock.mockClear()
|
||||||
listMock.mockClear()
|
listMock.mockClear()
|
||||||
|
shouldSkipMock.mockClear()
|
||||||
updateMock.mockClear()
|
updateMock.mockClear()
|
||||||
uploadMock.mockClear()
|
uploadMock.mockClear()
|
||||||
})
|
})
|
||||||
@@ -150,6 +153,16 @@ describe("Action", () => {
|
|||||||
assertOutputApplied()
|
assertOutputApplied()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('skips action', async () => {
|
||||||
|
const action = createAction(false, false, false)
|
||||||
|
shouldSkipMock.mockResolvedValue(true)
|
||||||
|
|
||||||
|
await action.perform()
|
||||||
|
|
||||||
|
expect(createMock).not.toBeCalled()
|
||||||
|
expect(updateMock).not.toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
it('throws error when create fails', async () => {
|
it('throws error when create fails', async () => {
|
||||||
const action = createAction(false, true)
|
const action = createAction(false, true)
|
||||||
createMock.mockRejectedValue("error")
|
createMock.mockRejectedValue("error")
|
||||||
@@ -353,6 +366,7 @@ describe("Action", () => {
|
|||||||
listMock.mockResolvedValue({
|
listMock.mockResolvedValue({
|
||||||
data: []
|
data: []
|
||||||
})
|
})
|
||||||
|
shouldSkipMock.mockResolvedValue(false)
|
||||||
updateMock.mockResolvedValue({
|
updateMock.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
id: releaseId,
|
id: releaseId,
|
||||||
@@ -377,6 +391,7 @@ describe("Action", () => {
|
|||||||
replacesArtifacts: replacesArtifacts,
|
replacesArtifacts: replacesArtifacts,
|
||||||
removeArtifacts: removeArtifacts,
|
removeArtifacts: removeArtifacts,
|
||||||
repo: "repo",
|
repo: "repo",
|
||||||
|
skipIfReleaseExists: false,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
token: token,
|
token: token,
|
||||||
updatedDraft: updateDraft,
|
updatedDraft: updateDraft,
|
||||||
@@ -402,12 +417,19 @@ describe("Action", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const MockActionSkipper = jest.fn<ActionSkipper, any>(() => {
|
||||||
|
return {
|
||||||
|
shouldSkip: shouldSkipMock
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const inputs = new MockInputs()
|
const inputs = new MockInputs()
|
||||||
const outputs = new MockOutputs()
|
const outputs = new MockOutputs()
|
||||||
const releases = new MockReleases()
|
const releases = new MockReleases()
|
||||||
const uploader = new MockUploader()
|
const uploader = new MockUploader()
|
||||||
const artifactDestroyer = new MockArtifactDestroyer()
|
const artifactDestroyer = new MockArtifactDestroyer()
|
||||||
|
const actionSkipper = new MockActionSkipper()
|
||||||
|
|
||||||
return new Action(inputs, outputs, releases, uploader, artifactDestroyer)
|
return new Action(inputs, outputs, releases, uploader, artifactDestroyer, actionSkipper)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
44
__tests__/ActionSkipper.test.ts
Normal file
44
__tests__/ActionSkipper.test.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import {ActionSkipper, ReleaseActionSkipper} from "../src/ActionSkipper";
|
||||||
|
import {Releases} from "../src/Releases";
|
||||||
|
|
||||||
|
describe("shouldSkip", () => {
|
||||||
|
const getMock = jest.fn()
|
||||||
|
const tag = "tag"
|
||||||
|
const MockReleases = jest.fn<Releases, any>(() => {
|
||||||
|
return {
|
||||||
|
create: jest.fn(),
|
||||||
|
deleteArtifact: jest.fn(),
|
||||||
|
getByTag: getMock,
|
||||||
|
listArtifactsForRelease: jest.fn(),
|
||||||
|
listReleases: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
uploadArtifact: jest.fn()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return false when skipIfReleaseExists is false', async () => {
|
||||||
|
const actionSkipper = new ReleaseActionSkipper(false, MockReleases(), tag)
|
||||||
|
expect(await actionSkipper.shouldSkip()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return false when error occurs', async () => {
|
||||||
|
getMock.mockRejectedValue(new Error())
|
||||||
|
|
||||||
|
const actionSkipper = new ReleaseActionSkipper(true, MockReleases(), tag)
|
||||||
|
expect(await actionSkipper.shouldSkip()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return false when release does not exist', async () => {
|
||||||
|
getMock.mockResolvedValue({})
|
||||||
|
|
||||||
|
const actionSkipper = new ReleaseActionSkipper(true, MockReleases(), tag)
|
||||||
|
expect(await actionSkipper.shouldSkip()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return true when release does exist', async () => {
|
||||||
|
getMock.mockResolvedValue({data: {}})
|
||||||
|
|
||||||
|
const actionSkipper = new ReleaseActionSkipper(true, MockReleases(), tag)
|
||||||
|
expect(await actionSkipper.shouldSkip()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
const mockGetInput = jest.fn();
|
const mockGetInput = jest.fn();
|
||||||
|
const mockGetBooleanInput = jest.fn();
|
||||||
const mockGlob = jest.fn()
|
const mockGlob = jest.fn()
|
||||||
const mockReadFileSync = jest.fn();
|
const mockReadFileSync = jest.fn();
|
||||||
const mockStatSync = jest.fn();
|
const mockStatSync = jest.fn();
|
||||||
@@ -14,7 +15,10 @@ const artifacts = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
jest.mock('@actions/core', () => {
|
jest.mock('@actions/core', () => {
|
||||||
return {getInput: mockGetInput};
|
return {
|
||||||
|
getInput: mockGetInput,
|
||||||
|
getBooleanInput: mockGetBooleanInput
|
||||||
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.mock('fs', () => {
|
jest.mock('fs', () => {
|
||||||
@@ -278,6 +282,18 @@ describe('Inputs', () => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('skipIfReleaseExists', () => {
|
||||||
|
it('returns false', () => {
|
||||||
|
mockGetBooleanInput.mockReturnValue(false)
|
||||||
|
expect(inputs.skipIfReleaseExists).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns true', () => {
|
||||||
|
mockGetBooleanInput.mockReturnValue(true)
|
||||||
|
expect(inputs.skipIfReleaseExists).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('tag', () => {
|
describe('tag', () => {
|
||||||
it('returns input tag', () => {
|
it('returns input tag', () => {
|
||||||
mockGetInput.mockReturnValue('tag')
|
mockGetInput.mockReturnValue('tag')
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import * as path from "path";
|
|||||||
import {FileArtifactGlobber} from "../src/ArtifactGlobber";
|
import {FileArtifactGlobber} from "../src/ArtifactGlobber";
|
||||||
import {Outputs} from "../src/Outputs";
|
import {Outputs} from "../src/Outputs";
|
||||||
import {GithubArtifactDestroyer} from "../src/ArtifactDestroyer";
|
import {GithubArtifactDestroyer} from "../src/ArtifactDestroyer";
|
||||||
|
import {ReleaseActionSkipper} from "../src/ActionSkipper";
|
||||||
|
|
||||||
// This test is currently intended to be manually run during development. To run:
|
// This test is currently intended to be manually run during development. To run:
|
||||||
// - Make sure you have an environment variable named GITHUB_TOKEN assigned to your token
|
// - Make sure you have an environment variable named GITHUB_TOKEN assigned to your token
|
||||||
@@ -27,8 +28,9 @@ describe.skip('Integration Test', () => {
|
|||||||
inputs.artifactErrorsFailBuild,
|
inputs.artifactErrorsFailBuild,
|
||||||
)
|
)
|
||||||
const artifactDestroyer = new GithubArtifactDestroyer(releases)
|
const artifactDestroyer = new GithubArtifactDestroyer(releases)
|
||||||
|
const actionSkipper = new ReleaseActionSkipper(inputs.skipIfReleaseExists, releases, inputs.tag)
|
||||||
|
|
||||||
action = new Action(inputs, outputs, releases, uploader, artifactDestroyer)
|
action = new Action(inputs, outputs, releases, uploader, artifactDestroyer, actionSkipper)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Performs action', async () => {
|
it('Performs action', async () => {
|
||||||
@@ -52,10 +54,11 @@ describe.skip('Integration Test', () => {
|
|||||||
replacesArtifacts: true,
|
replacesArtifacts: true,
|
||||||
removeArtifacts: false,
|
removeArtifacts: false,
|
||||||
repo: "actions-playground",
|
repo: "actions-playground",
|
||||||
|
skipIfReleaseExists: false,
|
||||||
tag: "release-action-test",
|
tag: "release-action-test",
|
||||||
token: getToken(),
|
token: getToken(),
|
||||||
updatedDraft: false,
|
updatedDraft: false,
|
||||||
updatedReleaseBody: "This release was generated by release-action's integration test",
|
updatedReleaseBody: "This release was updated by release-action's integration test",
|
||||||
updatedReleaseName: "Releases Action Integration Test",
|
updatedReleaseName: "Releases Action Integration Test",
|
||||||
updatedPrerelease: false,
|
updatedPrerelease: false,
|
||||||
updateOnlyUnreleased: false
|
updateOnlyUnreleased: false
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ inputs:
|
|||||||
description: "Optionally specify the repo where the release should be generated. Defaults to current repo"
|
description: "Optionally specify the repo where the release should be generated. Defaults to current repo"
|
||||||
required: false
|
required: false
|
||||||
default: ''
|
default: ''
|
||||||
|
skipIfReleaseExists:
|
||||||
|
description: "When skipIfReleaseExists is enabled the action will be skipped if a non-draft release already exists for the provided tag."
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
tag:
|
tag:
|
||||||
description: 'An optional tag for the release. If this is omitted the git ref will be used (if it is a tag).'
|
description: 'An optional tag for the release. If this is omitted the git ref will be used (if it is a tag).'
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
82
dist/index.js
vendored
82
dist/index.js
vendored
@@ -6,6 +6,29 @@ require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
@@ -17,19 +40,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.Action = void 0;
|
exports.Action = void 0;
|
||||||
|
const core = __importStar(__nccwpck_require__(2559));
|
||||||
const GithubError_1 = __nccwpck_require__(7433);
|
const GithubError_1 = __nccwpck_require__(7433);
|
||||||
const ReleaseValidator_1 = __nccwpck_require__(7579);
|
const ReleaseValidator_1 = __nccwpck_require__(7579);
|
||||||
class Action {
|
class Action {
|
||||||
constructor(inputs, outputs, releases, uploader, artifactDestroyer) {
|
constructor(inputs, outputs, releases, uploader, artifactDestroyer, skipper) {
|
||||||
this.inputs = inputs;
|
this.inputs = inputs;
|
||||||
this.outputs = outputs;
|
this.outputs = outputs;
|
||||||
this.releases = releases;
|
this.releases = releases;
|
||||||
this.uploader = uploader;
|
this.uploader = uploader;
|
||||||
this.artifactDestroyer = artifactDestroyer;
|
this.artifactDestroyer = artifactDestroyer;
|
||||||
|
this.skipper = skipper;
|
||||||
this.releaseValidator = new ReleaseValidator_1.ReleaseValidator(inputs.updateOnlyUnreleased);
|
this.releaseValidator = new ReleaseValidator_1.ReleaseValidator(inputs.updateOnlyUnreleased);
|
||||||
}
|
}
|
||||||
perform() {
|
perform() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (yield this.skipper.shouldSkip()) {
|
||||||
|
core.notice("Skipping action, release already exists and skipIfReleaseExists is enabled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const releaseResponse = yield this.createOrUpdateRelease();
|
const releaseResponse = yield this.createOrUpdateRelease();
|
||||||
const releaseData = releaseResponse.data;
|
const releaseData = releaseResponse.data;
|
||||||
const releaseId = releaseData.id;
|
const releaseId = releaseData.id;
|
||||||
@@ -111,6 +140,50 @@ class Action {
|
|||||||
exports.Action = Action;
|
exports.Action = Action;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 2746:
|
||||||
|
/***/ (function(__unused_webpack_module, exports) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
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) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ReleaseActionSkipper = void 0;
|
||||||
|
class ReleaseActionSkipper {
|
||||||
|
constructor(skipIfReleaseExists, releases, tag) {
|
||||||
|
this.skipIfReleaseExists = skipIfReleaseExists;
|
||||||
|
this.releases = releases;
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
shouldSkip() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!this.skipIfReleaseExists) {
|
||||||
|
// Bail if skip flag isn't set.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const getResponse = yield this.releases.getByTag(this.tag);
|
||||||
|
return getResponse.data != null;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
// There is either no release or something else went wrong. Either way, run the action.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ReleaseActionSkipper = ReleaseActionSkipper;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 8568:
|
/***/ 8568:
|
||||||
@@ -728,6 +801,9 @@ class CoreInputs {
|
|||||||
}
|
}
|
||||||
return this.context.repo.repo;
|
return this.context.repo.repo;
|
||||||
}
|
}
|
||||||
|
get skipIfReleaseExists() {
|
||||||
|
return core.getBooleanInput("skipIfReleaseExists");
|
||||||
|
}
|
||||||
get tag() {
|
get tag() {
|
||||||
const tag = core.getInput('tag');
|
const tag = core.getInput('tag');
|
||||||
if (tag) {
|
if (tag) {
|
||||||
@@ -1037,6 +1113,7 @@ const ArtifactGlobber_1 = __nccwpck_require__(8924);
|
|||||||
const GithubError_1 = __nccwpck_require__(7433);
|
const GithubError_1 = __nccwpck_require__(7433);
|
||||||
const Outputs_1 = __nccwpck_require__(6650);
|
const Outputs_1 = __nccwpck_require__(6650);
|
||||||
const ArtifactDestroyer_1 = __nccwpck_require__(1770);
|
const ArtifactDestroyer_1 = __nccwpck_require__(1770);
|
||||||
|
const ActionSkipper_1 = __nccwpck_require__(2746);
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
@@ -1057,9 +1134,10 @@ 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 skipper = new ActionSkipper_1.ReleaseActionSkipper(inputs.skipIfReleaseExists, releases, inputs.tag);
|
||||||
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild);
|
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild);
|
||||||
const artifactDestroyer = new ArtifactDestroyer_1.GithubArtifactDestroyer(releases);
|
const artifactDestroyer = new ArtifactDestroyer_1.GithubArtifactDestroyer(releases);
|
||||||
return new Action_1.Action(inputs, outputs, releases, uploader, artifactDestroyer);
|
return new Action_1.Action(inputs, outputs, releases, uploader, artifactDestroyer, skipper);
|
||||||
}
|
}
|
||||||
run();
|
run();
|
||||||
|
|
||||||
|
|||||||
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -1,4 +1,27 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
@@ -10,19 +33,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Action = void 0;
|
exports.Action = void 0;
|
||||||
|
const core = __importStar(require("@actions/core"));
|
||||||
const GithubError_1 = require("./GithubError");
|
const GithubError_1 = require("./GithubError");
|
||||||
const ReleaseValidator_1 = require("./ReleaseValidator");
|
const ReleaseValidator_1 = require("./ReleaseValidator");
|
||||||
class Action {
|
class Action {
|
||||||
constructor(inputs, outputs, releases, uploader, artifactDestroyer) {
|
constructor(inputs, outputs, releases, uploader, artifactDestroyer, skipper) {
|
||||||
this.inputs = inputs;
|
this.inputs = inputs;
|
||||||
this.outputs = outputs;
|
this.outputs = outputs;
|
||||||
this.releases = releases;
|
this.releases = releases;
|
||||||
this.uploader = uploader;
|
this.uploader = uploader;
|
||||||
this.artifactDestroyer = artifactDestroyer;
|
this.artifactDestroyer = artifactDestroyer;
|
||||||
|
this.skipper = skipper;
|
||||||
this.releaseValidator = new ReleaseValidator_1.ReleaseValidator(inputs.updateOnlyUnreleased);
|
this.releaseValidator = new ReleaseValidator_1.ReleaseValidator(inputs.updateOnlyUnreleased);
|
||||||
}
|
}
|
||||||
perform() {
|
perform() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (yield this.skipper.shouldSkip()) {
|
||||||
|
core.notice("Skipping action, release already exists and skipIfReleaseExists is enabled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const releaseResponse = yield this.createOrUpdateRelease();
|
const releaseResponse = yield this.createOrUpdateRelease();
|
||||||
const releaseData = releaseResponse.data;
|
const releaseData = releaseResponse.data;
|
||||||
const releaseId = releaseData.id;
|
const releaseId = releaseData.id;
|
||||||
|
|||||||
36
lib/ActionSkipper.js
Normal file
36
lib/ActionSkipper.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
"use strict";
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
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) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ReleaseActionSkipper = void 0;
|
||||||
|
class ReleaseActionSkipper {
|
||||||
|
constructor(skipIfReleaseExists, releases, tag) {
|
||||||
|
this.skipIfReleaseExists = skipIfReleaseExists;
|
||||||
|
this.releases = releases;
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
shouldSkip() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!this.skipIfReleaseExists) {
|
||||||
|
// Bail if skip flag isn't set.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const getResponse = yield this.releases.getByTag(this.tag);
|
||||||
|
return getResponse.data != null;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
// There is either no release or something else went wrong. Either way, run the action.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ReleaseActionSkipper = ReleaseActionSkipper;
|
||||||
@@ -136,6 +136,9 @@ class CoreInputs {
|
|||||||
}
|
}
|
||||||
return this.context.repo.repo;
|
return this.context.repo.repo;
|
||||||
}
|
}
|
||||||
|
get skipIfReleaseExists() {
|
||||||
|
return core.getBooleanInput("skipIfReleaseExists");
|
||||||
|
}
|
||||||
get tag() {
|
get tag() {
|
||||||
const tag = core.getInput('tag');
|
const tag = core.getInput('tag');
|
||||||
if (tag) {
|
if (tag) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const ArtifactGlobber_1 = require("./ArtifactGlobber");
|
|||||||
const GithubError_1 = require("./GithubError");
|
const GithubError_1 = require("./GithubError");
|
||||||
const Outputs_1 = require("./Outputs");
|
const Outputs_1 = require("./Outputs");
|
||||||
const ArtifactDestroyer_1 = require("./ArtifactDestroyer");
|
const ArtifactDestroyer_1 = require("./ArtifactDestroyer");
|
||||||
|
const ActionSkipper_1 = require("./ActionSkipper");
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
@@ -62,8 +63,9 @@ 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 skipper = new ActionSkipper_1.ReleaseActionSkipper(inputs.skipIfReleaseExists, releases, inputs.tag);
|
||||||
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild);
|
const uploader = new ArtifactUploader_1.GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild);
|
||||||
const artifactDestroyer = new ArtifactDestroyer_1.GithubArtifactDestroyer(releases);
|
const artifactDestroyer = new ArtifactDestroyer_1.GithubArtifactDestroyer(releases);
|
||||||
return new Action_1.Action(inputs, outputs, releases, uploader, artifactDestroyer);
|
return new Action_1.Action(inputs, outputs, releases, uploader, artifactDestroyer, skipper);
|
||||||
}
|
}
|
||||||
run();
|
run();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
import {Inputs} from "./Inputs";
|
import {Inputs} from "./Inputs";
|
||||||
import {
|
import {
|
||||||
CreateOrUpdateReleaseResponse,
|
CreateOrUpdateReleaseResponse,
|
||||||
@@ -11,6 +12,7 @@ import {GithubError} from "./GithubError";
|
|||||||
import {Outputs} from "./Outputs";
|
import {Outputs} from "./Outputs";
|
||||||
import {ArtifactDestroyer} from "./ArtifactDestroyer";
|
import {ArtifactDestroyer} from "./ArtifactDestroyer";
|
||||||
import {ReleaseValidator} from "./ReleaseValidator";
|
import {ReleaseValidator} from "./ReleaseValidator";
|
||||||
|
import {ActionSkipper} from "./ActionSkipper";
|
||||||
|
|
||||||
export class Action {
|
export class Action {
|
||||||
private inputs: Inputs
|
private inputs: Inputs
|
||||||
@@ -18,6 +20,7 @@ export class Action {
|
|||||||
private releases: Releases
|
private releases: Releases
|
||||||
private uploader: ArtifactUploader
|
private uploader: ArtifactUploader
|
||||||
private artifactDestroyer: ArtifactDestroyer
|
private artifactDestroyer: ArtifactDestroyer
|
||||||
|
private skipper: ActionSkipper
|
||||||
|
|
||||||
private releaseValidator: ReleaseValidator
|
private releaseValidator: ReleaseValidator
|
||||||
|
|
||||||
@@ -25,16 +28,23 @@ export class Action {
|
|||||||
outputs: Outputs,
|
outputs: Outputs,
|
||||||
releases: Releases,
|
releases: Releases,
|
||||||
uploader: ArtifactUploader,
|
uploader: ArtifactUploader,
|
||||||
artifactDestroyer: ArtifactDestroyer) {
|
artifactDestroyer: ArtifactDestroyer,
|
||||||
|
skipper: ActionSkipper) {
|
||||||
this.inputs = inputs
|
this.inputs = inputs
|
||||||
this.outputs = outputs
|
this.outputs = outputs
|
||||||
this.releases = releases
|
this.releases = releases
|
||||||
this.uploader = uploader
|
this.uploader = uploader
|
||||||
this.artifactDestroyer = artifactDestroyer
|
this.artifactDestroyer = artifactDestroyer
|
||||||
|
this.skipper = skipper
|
||||||
this.releaseValidator = new ReleaseValidator(inputs.updateOnlyUnreleased)
|
this.releaseValidator = new ReleaseValidator(inputs.updateOnlyUnreleased)
|
||||||
}
|
}
|
||||||
|
|
||||||
async perform() {
|
async perform() {
|
||||||
|
if (await this.skipper.shouldSkip()) {
|
||||||
|
core.notice("Skipping action, release already exists and skipIfReleaseExists is enabled.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const releaseResponse = await this.createOrUpdateRelease();
|
const releaseResponse = await this.createOrUpdateRelease();
|
||||||
const releaseData = releaseResponse.data
|
const releaseData = releaseResponse.data
|
||||||
const releaseId = releaseData.id
|
const releaseId = releaseData.id
|
||||||
|
|||||||
27
src/ActionSkipper.ts
Normal file
27
src/ActionSkipper.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import {Releases} from "./Releases";
|
||||||
|
|
||||||
|
export interface ActionSkipper {
|
||||||
|
shouldSkip(): Promise<boolean>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ReleaseActionSkipper {
|
||||||
|
constructor(private skipIfReleaseExists: boolean,
|
||||||
|
private releases: Releases,
|
||||||
|
private tag: string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
async shouldSkip(): Promise<boolean> {
|
||||||
|
if (!this.skipIfReleaseExists) {
|
||||||
|
// Bail if skip flag isn't set.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const getResponse = await this.releases.getByTag(this.tag)
|
||||||
|
return getResponse.data != null
|
||||||
|
} catch (error: any) {
|
||||||
|
// There is either no release or something else went wrong. Either way, run the action.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ export interface Inputs {
|
|||||||
readonly removeArtifacts: boolean
|
readonly removeArtifacts: boolean
|
||||||
readonly replacesArtifacts: boolean
|
readonly replacesArtifacts: boolean
|
||||||
readonly repo: string
|
readonly repo: string
|
||||||
|
readonly skipIfReleaseExists: boolean
|
||||||
readonly tag: string
|
readonly tag: string
|
||||||
readonly token: string
|
readonly token: string
|
||||||
readonly updatedDraft?: boolean
|
readonly updatedDraft?: boolean
|
||||||
@@ -160,6 +161,10 @@ export class CoreInputs implements Inputs {
|
|||||||
return this.context.repo.repo
|
return this.context.repo.repo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get skipIfReleaseExists(): boolean {
|
||||||
|
return core.getBooleanInput("skipIfReleaseExists")
|
||||||
|
}
|
||||||
|
|
||||||
get tag(): string {
|
get tag(): string {
|
||||||
const tag = core.getInput('tag')
|
const tag = core.getInput('tag')
|
||||||
if (tag) {
|
if (tag) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {FileArtifactGlobber} from './ArtifactGlobber';
|
|||||||
import {GithubError} from './GithubError';
|
import {GithubError} from './GithubError';
|
||||||
import {CoreOutputs} from "./Outputs";
|
import {CoreOutputs} from "./Outputs";
|
||||||
import {GithubArtifactDestroyer} from "./ArtifactDestroyer";
|
import {GithubArtifactDestroyer} from "./ArtifactDestroyer";
|
||||||
|
import {ActionSkipper, ReleaseActionSkipper} from "./ActionSkipper";
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
@@ -28,10 +29,11 @@ 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 skipper = new ReleaseActionSkipper(inputs.skipIfReleaseExists, releases, inputs.tag)
|
||||||
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild)
|
const uploader = new GithubArtifactUploader(releases, inputs.replacesArtifacts, inputs.artifactErrorsFailBuild)
|
||||||
const artifactDestroyer = new GithubArtifactDestroyer(releases)
|
const artifactDestroyer = new GithubArtifactDestroyer(releases)
|
||||||
|
|
||||||
return new Action(inputs, outputs, releases, uploader, artifactDestroyer)
|
return new Action(inputs, outputs, releases, uploader, artifactDestroyer, skipper)
|
||||||
}
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
|||||||
Reference in New Issue
Block a user