mirror of
https://github.com/actions/publish-action.git
synced 2025-02-24 16:22:31 +00:00
Add and configure ESLint and update configuration for Prettier (#26)
* Add ESLint and Prettier * Rebuild action * Update package.json * Update licenses * Fix review points
This commit is contained in:
parent
87579b14ff
commit
9169aa7609
6
.eslintignore
Normal file
6
.eslintignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Ignore list
|
||||||
|
/*
|
||||||
|
|
||||||
|
# Do not ignore these folders:
|
||||||
|
!__tests__/
|
||||||
|
!src/
|
49
.eslintrc.js
Normal file
49
.eslintrc.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:eslint-plugin-jest/recommended',
|
||||||
|
'eslint-config-prettier'
|
||||||
|
],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
plugins: ['@typescript-eslint', 'eslint-plugin-jest'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-require-imports': 'error',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
|
'@typescript-eslint/ban-ts-comment': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'ts-ignore': 'allow-with-description'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'no-console': 'error',
|
||||||
|
'yoda': 'error',
|
||||||
|
'prefer-const': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
destructuring: 'all'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'no-control-regex': 'off',
|
||||||
|
'no-constant-condition': ['error', {checkLoops: false}]
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['**/*{test,spec}.ts'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
|
'jest/no-standalone-expect': 'off',
|
||||||
|
'jest/no-conditional-expect': 'off',
|
||||||
|
'no-console': 'off',
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
es6: true,
|
||||||
|
'jest/globals': true
|
||||||
|
}
|
||||||
|
};
|
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
|
.licenses/** -diff linguist-generated=true
|
2
.github/workflows/basic-validation.yml
vendored
2
.github/workflows/basic-validation.yml
vendored
@ -9,4 +9,4 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
call-basic-validation:
|
call-basic-validation:
|
||||||
name: Basic validation
|
name: Basic validation
|
||||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
||||||
|
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@ -2,13 +2,13 @@ name: CodeQL analysis
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ main ]
|
branches: [main]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ main ]
|
branches: [main]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 3 * * 0'
|
- cron: '0 3 * * 0'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
call-codeQL-analysis:
|
call-codeQL-analysis:
|
||||||
name: CodeQL analysis
|
name: CodeQL analysis
|
||||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||||
|
2
.github/workflows/licensed.yml
vendored
2
.github/workflows/licensed.yml
vendored
@ -11,4 +11,4 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
call-licensed:
|
call-licensed:
|
||||||
name: Licensed
|
name: Licensed
|
||||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||||
|
14
.github/workflows/release-new-action-version.yml
vendored
14
.github/workflows/release-new-action-version.yml
vendored
@ -25,11 +25,11 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Update the ${{ env.TAG_NAME }} tag
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
id: update-major-tag
|
id: update-major-tag
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
source-tag: ${{ env.TAG_NAME }}
|
source-tag: ${{ env.TAG_NAME }}
|
||||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
|
BIN
.licenses/npm/semver.dep.yml
generated
BIN
.licenses/npm/semver.dep.yml
generated
Binary file not shown.
7
.prettierignore
Normal file
7
.prettierignore
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Ignore list
|
||||||
|
/*
|
||||||
|
|
||||||
|
# Do not ignore these folders:
|
||||||
|
!__tests__/
|
||||||
|
!.github/
|
||||||
|
!src/
|
10
.prettierrc.js
Normal file
10
.prettierrc.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
printWidth: 80,
|
||||||
|
tabWidth: 2,
|
||||||
|
useTabs: false,
|
||||||
|
semi: true,
|
||||||
|
singleQuote: true,
|
||||||
|
trailingComma: 'none',
|
||||||
|
bracketSpacing: false,
|
||||||
|
arrowParens: 'avoid'
|
||||||
|
};
|
@ -1,39 +1,43 @@
|
|||||||
import * as github from "@actions/github";
|
import * as github from '@actions/github';
|
||||||
import * as apiUtils from "../src/api-utils";
|
import * as apiUtils from '../src/api-utils';
|
||||||
|
|
||||||
const prereleaseData = require("./data/pre-release.json");
|
import prereleaseData from './data/pre-release.json';
|
||||||
const releaseData = require("./data/release.json");
|
import releaseData from './data/release.json';
|
||||||
|
|
||||||
const token = "faketoken";
|
const token = 'faketoken';
|
||||||
const octokitClient = github.getOctokit(token);
|
const octokitClient = github.getOctokit(token);
|
||||||
|
|
||||||
let getReleaseSpy: jest.SpyInstance;
|
let getReleaseSpy: jest.SpyInstance;
|
||||||
|
|
||||||
process.env.GITHUB_REPOSITORY = "test/repository";
|
process.env.GITHUB_REPOSITORY = 'test/repository';
|
||||||
|
|
||||||
describe("validateIfReleaseIsPublished", () => {
|
describe('validateIfReleaseIsPublished', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
getReleaseSpy = jest.spyOn(octokitClient.repos, "getReleaseByTag");
|
getReleaseSpy = jest.spyOn(octokitClient.repos, 'getReleaseByTag');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("throw if release is marked as pre-release", async () => {
|
it('throw if release is marked as pre-release', async () => {
|
||||||
getReleaseSpy.mockReturnValue(prereleaseData);
|
getReleaseSpy.mockReturnValue(prereleaseData);
|
||||||
|
|
||||||
expect.assertions(1);
|
|
||||||
await expect(apiUtils.validateIfReleaseIsPublished("v1.0.0", octokitClient)).rejects.toThrowError(
|
|
||||||
"The 'v1.0.0' release is marked as pre-release. Updating tags for pre-release is not supported"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("validate that release is published", async () => {
|
expect.assertions(1);
|
||||||
getReleaseSpy.mockReturnValue(releaseData);
|
await expect(
|
||||||
|
apiUtils.validateIfReleaseIsPublished('v1.0.0', octokitClient)
|
||||||
|
).rejects.toThrow(
|
||||||
|
"The 'v1.0.0' release is marked as pre-release. Updating tags for pre-release is not supported"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
expect.assertions(1);
|
it('validate that release is published', async () => {
|
||||||
await expect(apiUtils.validateIfReleaseIsPublished("v1.1.0", octokitClient)).resolves.not.toThrow();
|
getReleaseSpy.mockReturnValue(releaseData);
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
expect.assertions(1);
|
||||||
jest.resetAllMocks();
|
await expect(
|
||||||
jest.clearAllMocks();
|
apiUtils.validateIfReleaseIsPublished('v1.1.0', octokitClient)
|
||||||
});
|
).resolves.not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -1,69 +1,93 @@
|
|||||||
import * as versionUtils from "../src/version-utils";
|
import * as versionUtils from '../src/version-utils';
|
||||||
|
import stableSemver from './data/stable-semver.json';
|
||||||
|
import stableBuildSemver from './data/stable-build-semver.json';
|
||||||
|
import prereleaseSemver from './data/prerelease-semver.json';
|
||||||
|
import prereleaseBuildSemver from './data/prerelease-build-semver.json';
|
||||||
|
|
||||||
describe("isStableSemverVersion", () => {
|
describe('isStableSemverVersion', () => {
|
||||||
it("validate if a version is stable", () => {
|
it('validate if a version is stable', () => {
|
||||||
const semverVersion = require("./data/stable-semver.json");
|
expect(
|
||||||
expect(versionUtils.isStableSemverVersion(semverVersion)).toBeTruthy();
|
versionUtils.isStableSemverVersion(stableSemver as any)
|
||||||
});
|
).toBeTruthy();
|
||||||
|
});
|
||||||
it("validate if a version with build metadata is stable", () => {
|
|
||||||
const semverVersion = require("./data/stable-build-semver.json");
|
|
||||||
expect(versionUtils.isStableSemverVersion(semverVersion)).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("validate if a pre-release version is not stable", () => {
|
it('validate if a version with build metadata is stable', () => {
|
||||||
const semverVersion = require("./data/prerelease-semver.json");
|
expect(
|
||||||
expect(versionUtils.isStableSemverVersion(semverVersion)).toBeFalsy();
|
versionUtils.isStableSemverVersion(stableBuildSemver as any)
|
||||||
});
|
).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
it("validate if a pre-release version with build metadata is not stable", () => {
|
it('validate if a pre-release version is not stable', () => {
|
||||||
const semverVersion = require("./data/prerelease-build-semver.json");
|
expect(
|
||||||
expect(versionUtils.isStableSemverVersion(semverVersion)).toBeFalsy();
|
versionUtils.isStableSemverVersion(prereleaseSemver as any)
|
||||||
});
|
).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('validate if a pre-release version with build metadata is not stable', () => {
|
||||||
|
expect(
|
||||||
|
versionUtils.isStableSemverVersion(prereleaseBuildSemver as any)
|
||||||
|
).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("validateSemverVersionFromTag", () => {
|
describe('validateSemverVersionFromTag', () => {
|
||||||
it("validate a tag containing an valid semantic version", () => {
|
it('validate a tag containing a valid semantic version', () => {
|
||||||
expect(() => versionUtils.validateSemverVersionFromTag("1.0.0")).not.toThrow();
|
expect(() =>
|
||||||
});
|
versionUtils.validateSemverVersionFromTag('1.0.0')
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
it("validate a tag containing an valid semantic version with 'v' prefix", () => {
|
it("validate a tag containing a valid semantic version with 'v' prefix", () => {
|
||||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0")).not.toThrow();
|
expect(() =>
|
||||||
});
|
versionUtils.validateSemverVersionFromTag('v1.0.0')
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
it("validate a tag containing an valid semantic version with build metadata", () => {
|
it('validate a tag containing a valid semantic version with build metadata', () => {
|
||||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0+20130313144700")).not.toThrow();
|
expect(() =>
|
||||||
});
|
versionUtils.validateSemverVersionFromTag('v1.0.0+20130313144700')
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
it("throw when a tag contains an invalid semantic version", () => {
|
it('throw when a tag contains an invalid semantic version', () => {
|
||||||
expect(() => versionUtils.validateSemverVersionFromTag("1.0.0invalid")).toThrowError(
|
expect(() =>
|
||||||
"The '1.0.0invalid' doesn't satisfy semantic versioning specification"
|
versionUtils.validateSemverVersionFromTag('1.0.0invalid')
|
||||||
);
|
).toThrow(
|
||||||
});
|
"The '1.0.0invalid' doesn't satisfy semantic versioning specification"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("throw when a tag contains an valid unstable semantic version", () => {
|
it('throw when a tag contains a valid unstable semantic version', () => {
|
||||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0-beta.1")).toThrowError(
|
expect(() =>
|
||||||
"It is not allowed to specify pre-release version to update the major tag"
|
versionUtils.validateSemverVersionFromTag('v1.0.0-beta.1')
|
||||||
);
|
).toThrow(
|
||||||
});
|
'It is not allowed to specify pre-release version to update the major tag'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("throw when a tag contains an valid unstable semantic version with build metadata", () => {
|
it('throw when a tag contains a valid unstable semantic version with build metadata', () => {
|
||||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0-beta.1+20130313144700")).toThrowError(
|
expect(() =>
|
||||||
"It is not allowed to specify pre-release version to update the major tag"
|
versionUtils.validateSemverVersionFromTag('v1.0.0-beta.1+20130313144700')
|
||||||
);
|
).toThrow(
|
||||||
});
|
'It is not allowed to specify pre-release version to update the major tag'
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getMajorTagFromFullTag", () => {
|
describe('getMajorTagFromFullTag', () => {
|
||||||
describe("get a valid major tag from full tag", () => {
|
describe('get a valid major tag from full tag', () => {
|
||||||
it.each([
|
it.each([
|
||||||
["1.0.0", "1"],
|
['1.0.0', '1'],
|
||||||
["v1.0.0", "v1"],
|
['v1.0.0', 'v1'],
|
||||||
["v1.0.0-beta.1", "v1"],
|
['v1.0.0-beta.1', 'v1'],
|
||||||
["v1.0.0+20130313144700", "v1"],
|
['v1.0.0+20130313144700', 'v1']
|
||||||
] as [string, string][])("%s -> %s", (sourceTag: string, expectedMajorTag: string) => {
|
] as [string, string][])(
|
||||||
const resultantMajorTag = versionUtils.getMajorTagFromFullTag(sourceTag);
|
'%s -> %s',
|
||||||
expect(resultantMajorTag).toBe(expectedMajorTag);
|
(sourceTag: string, expectedMajorTag: string) => {
|
||||||
});
|
const resultantMajorTag =
|
||||||
});
|
versionUtils.getMajorTagFromFullTag(sourceTag);
|
||||||
});
|
expect(resultantMajorTag).toBe(expectedMajorTag);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
375
dist/index.js
vendored
375
dist/index.js
vendored
@ -5,104 +5,104 @@
|
|||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
if (k2 === undefined) k2 = k;
|
if (k2 === undefined) k2 = k;
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
}) : (function(o, m, k, k2) {
|
}) : (function(o, m, k, k2) {
|
||||||
if (k2 === undefined) k2 = k;
|
if (k2 === undefined) k2 = k;
|
||||||
o[k2] = m[k];
|
o[k2] = m[k];
|
||||||
}));
|
}));
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
}) : function(o, v) {
|
}) : function(o, v) {
|
||||||
o["default"] = v;
|
o["default"] = v;
|
||||||
});
|
});
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
if (mod && mod.__esModule) return mod;
|
if (mod && mod.__esModule) return mod;
|
||||||
var result = {};
|
var result = {};
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
__setModuleDefault(result, mod);
|
__setModuleDefault(result, mod);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.postMessageToSlack = exports.updateTag = exports.validateIfReleaseIsPublished = void 0;
|
exports.postMessageToSlack = exports.updateTag = exports.validateIfReleaseIsPublished = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const github_1 = __nccwpck_require__(5438);
|
const github_1 = __nccwpck_require__(5438);
|
||||||
const http_client_1 = __nccwpck_require__(9925);
|
const http_client_1 = __nccwpck_require__(9925);
|
||||||
async function findTag(tag, octokitClient) {
|
async function findTag(tag, octokitClient) {
|
||||||
try {
|
try {
|
||||||
const { data: foundTag } = await octokitClient.git.getRef({
|
const { data: foundTag } = await octokitClient.git.getRef({
|
||||||
...github_1.context.repo,
|
...github_1.context.repo,
|
||||||
ref: `tags/${tag}`
|
ref: `tags/${tag}`
|
||||||
});
|
});
|
||||||
return foundTag;
|
return foundTag;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (err.status === 404) {
|
if (err.status === 404) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new Error(`Retrieving refs failed with the following error: ${err}`);
|
throw new Error(`Retrieving refs failed with the following error: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function getTagSHA(tag, octokitClient) {
|
async function getTagSHA(tag, octokitClient) {
|
||||||
const foundTag = await findTag(tag, octokitClient);
|
const foundTag = await findTag(tag, octokitClient);
|
||||||
if (!foundTag) {
|
if (!foundTag) {
|
||||||
throw new Error(`The '${tag}' tag does not exist in the remote repository`);
|
throw new Error(`The '${tag}' tag does not exist in the remote repository`);
|
||||||
}
|
}
|
||||||
return foundTag.object.sha;
|
return foundTag.object.sha;
|
||||||
}
|
}
|
||||||
async function validateIfReleaseIsPublished(tag, octokitClient) {
|
async function validateIfReleaseIsPublished(tag, octokitClient) {
|
||||||
try {
|
try {
|
||||||
const { data: foundRelease } = await octokitClient.repos.getReleaseByTag({
|
const { data: foundRelease } = await octokitClient.repos.getReleaseByTag({
|
||||||
...github_1.context.repo,
|
...github_1.context.repo,
|
||||||
tag,
|
tag
|
||||||
});
|
});
|
||||||
if (foundRelease.prerelease) {
|
if (foundRelease.prerelease) {
|
||||||
throw new Error(`The '${foundRelease.name}' release is marked as pre-release. Updating tags for pre-release is not supported`);
|
throw new Error(`The '${foundRelease.name}' release is marked as pre-release. Updating tags for pre-release is not supported`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (err.status === 404) {
|
if (err.status === 404) {
|
||||||
throw new Error(`No GitHub release found for the ${tag} tag`);
|
throw new Error(`No GitHub release found for the ${tag} tag`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new Error(`Retrieving releases failed with the following error: ${err}`);
|
throw new Error(`Retrieving releases failed with the following error: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.validateIfReleaseIsPublished = validateIfReleaseIsPublished;
|
exports.validateIfReleaseIsPublished = validateIfReleaseIsPublished;
|
||||||
async function updateTag(sourceTag, targetTag, octokitClient) {
|
async function updateTag(sourceTag, targetTag, octokitClient) {
|
||||||
const sourceTagSHA = await getTagSHA(sourceTag, octokitClient);
|
const sourceTagSHA = await getTagSHA(sourceTag, octokitClient);
|
||||||
const foundTargetTag = await findTag(targetTag, octokitClient);
|
const foundTargetTag = await findTag(targetTag, octokitClient);
|
||||||
const refName = `tags/${targetTag}`;
|
const refName = `tags/${targetTag}`;
|
||||||
if (foundTargetTag) {
|
if (foundTargetTag) {
|
||||||
core.info(`Updating the '${targetTag}' tag to point to the '${sourceTag}' tag`);
|
core.info(`Updating the '${targetTag}' tag to point to the '${sourceTag}' tag`);
|
||||||
await octokitClient.git.updateRef({
|
await octokitClient.git.updateRef({
|
||||||
...github_1.context.repo,
|
...github_1.context.repo,
|
||||||
ref: refName,
|
ref: refName,
|
||||||
sha: sourceTagSHA,
|
sha: sourceTagSHA,
|
||||||
force: true
|
force: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.info(`Creating the '${targetTag}' tag from the '${sourceTag}' tag`);
|
core.info(`Creating the '${targetTag}' tag from the '${sourceTag}' tag`);
|
||||||
await octokitClient.git.createRef({
|
await octokitClient.git.createRef({
|
||||||
...github_1.context.repo,
|
...github_1.context.repo,
|
||||||
ref: `refs/${refName}`,
|
ref: `refs/${refName}`,
|
||||||
sha: sourceTagSHA
|
sha: sourceTagSHA
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.updateTag = updateTag;
|
exports.updateTag = updateTag;
|
||||||
async function postMessageToSlack(slackWebhook, message) {
|
async function postMessageToSlack(slackWebhook, message) {
|
||||||
const jsonData = { text: message };
|
const jsonData = { text: message };
|
||||||
const http = new http_client_1.HttpClient();
|
const http = new http_client_1.HttpClient();
|
||||||
await http.postJson(slackWebhook, jsonData);
|
await http.postJson(slackWebhook, jsonData);
|
||||||
}
|
}
|
||||||
exports.postMessageToSlack = postMessageToSlack;
|
exports.postMessageToSlack = postMessageToSlack;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -111,60 +111,59 @@ exports.postMessageToSlack = postMessageToSlack;
|
|||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
if (k2 === undefined) k2 = k;
|
if (k2 === undefined) k2 = k;
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
}) : (function(o, m, k, k2) {
|
}) : (function(o, m, k, k2) {
|
||||||
if (k2 === undefined) k2 = k;
|
if (k2 === undefined) k2 = k;
|
||||||
o[k2] = m[k];
|
o[k2] = m[k];
|
||||||
}));
|
}));
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
}) : function(o, v) {
|
}) : function(o, v) {
|
||||||
o["default"] = v;
|
o["default"] = v;
|
||||||
});
|
});
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
if (mod && mod.__esModule) return mod;
|
if (mod && mod.__esModule) return mod;
|
||||||
var result = {};
|
var result = {};
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
__setModuleDefault(result, mod);
|
__setModuleDefault(result, mod);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const github = __importStar(__nccwpck_require__(5438));
|
const github = __importStar(__nccwpck_require__(5438));
|
||||||
const github_1 = __nccwpck_require__(5438);
|
const github_1 = __nccwpck_require__(5438);
|
||||||
const api_utils_1 = __nccwpck_require__(2430);
|
const api_utils_1 = __nccwpck_require__(2430);
|
||||||
const version_utils_1 = __nccwpck_require__(1534);
|
const version_utils_1 = __nccwpck_require__(1534);
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
const token = core.getInput('token');
|
const token = core.getInput('token');
|
||||||
const octokitClient = github.getOctokit(token);
|
const octokitClient = github.getOctokit(token);
|
||||||
const sourceTagName = core.getInput('source-tag');
|
const sourceTagName = core.getInput('source-tag');
|
||||||
version_utils_1.validateSemverVersionFromTag(sourceTagName);
|
version_utils_1.validateSemverVersionFromTag(sourceTagName);
|
||||||
await api_utils_1.validateIfReleaseIsPublished(sourceTagName, octokitClient);
|
await api_utils_1.validateIfReleaseIsPublished(sourceTagName, octokitClient);
|
||||||
const majorTag = version_utils_1.getMajorTagFromFullTag(sourceTagName);
|
const majorTag = version_utils_1.getMajorTagFromFullTag(sourceTagName);
|
||||||
await api_utils_1.updateTag(sourceTagName, majorTag, octokitClient);
|
await api_utils_1.updateTag(sourceTagName, majorTag, octokitClient);
|
||||||
core.setOutput('major-tag', majorTag);
|
core.setOutput('major-tag', majorTag);
|
||||||
core.info(`The '${majorTag}' major tag now points to the '${sourceTagName}' tag`);
|
core.info(`The '${majorTag}' major tag now points to the '${sourceTagName}' tag`);
|
||||||
const slackMessage = `The ${majorTag} tag has been successfully updated for the ${github_1.context.repo.repo} action to include changes from ${sourceTagName}`;
|
const slackMessage = `The ${majorTag} tag has been successfully updated for the ${github_1.context.repo.repo} action to include changes from ${sourceTagName}`;
|
||||||
await reportStatusToSlack(slackMessage);
|
await reportStatusToSlack(slackMessage);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
const slackMessage = `Failed to update a major tag for the ${github_1.context.repo.repo} action`;
|
const slackMessage = `Failed to update a major tag for the ${github_1.context.repo.repo} action`;
|
||||||
await reportStatusToSlack(slackMessage);
|
await reportStatusToSlack(slackMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
async function reportStatusToSlack(message) {
|
||||||
async function reportStatusToSlack(message) {
|
const slackWebhook = core.getInput('slack-webhook');
|
||||||
const slackWebhook = core.getInput('slack-webhook');
|
if (slackWebhook) {
|
||||||
if (slackWebhook) {
|
await api_utils_1.postMessageToSlack(slackWebhook, message);
|
||||||
await api_utils_1.postMessageToSlack(slackWebhook, message);
|
}
|
||||||
}
|
}
|
||||||
}
|
run();
|
||||||
run();
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -173,31 +172,31 @@ run();
|
|||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.validateSemverVersionFromTag = exports.getMajorTagFromFullTag = exports.isStableSemverVersion = void 0;
|
exports.validateSemverVersionFromTag = exports.getMajorTagFromFullTag = exports.isStableSemverVersion = void 0;
|
||||||
const parse_1 = __importDefault(__nccwpck_require__(5925));
|
const parse_1 = __importDefault(__nccwpck_require__(5925));
|
||||||
function isStableSemverVersion(version) {
|
function isStableSemverVersion(version) {
|
||||||
return version.prerelease.length === 0;
|
return version.prerelease.length === 0;
|
||||||
}
|
}
|
||||||
exports.isStableSemverVersion = isStableSemverVersion;
|
exports.isStableSemverVersion = isStableSemverVersion;
|
||||||
function getMajorTagFromFullTag(fullTag) {
|
function getMajorTagFromFullTag(fullTag) {
|
||||||
return fullTag.split('.')[0];
|
return fullTag.split('.')[0];
|
||||||
}
|
}
|
||||||
exports.getMajorTagFromFullTag = getMajorTagFromFullTag;
|
exports.getMajorTagFromFullTag = getMajorTagFromFullTag;
|
||||||
function validateSemverVersionFromTag(tag) {
|
function validateSemverVersionFromTag(tag) {
|
||||||
const semverVersion = parse_1.default(tag);
|
const semverVersion = parse_1.default(tag);
|
||||||
if (!semverVersion) {
|
if (!semverVersion) {
|
||||||
throw new Error(`The '${tag}' doesn't satisfy semantic versioning specification`);
|
throw new Error(`The '${tag}' doesn't satisfy semantic versioning specification`);
|
||||||
}
|
}
|
||||||
if (!isStableSemverVersion(semverVersion)) {
|
if (!isStableSemverVersion(semverVersion)) {
|
||||||
throw new Error('It is not allowed to specify pre-release version to update the major tag');
|
throw new Error('It is not allowed to specify pre-release version to update the major tag');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.validateSemverVersionFromTag = validateSemverVersionFromTag;
|
exports.validateSemverVersionFromTag = validateSemverVersionFromTag;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -9593,7 +9592,7 @@ class SemVer {
|
|||||||
if (identifier) {
|
if (identifier) {
|
||||||
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
|
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
|
||||||
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
|
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
|
||||||
if (this.prerelease[0] === identifier) {
|
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
|
||||||
if (isNaN(this.prerelease[1])) {
|
if (isNaN(this.prerelease[1])) {
|
||||||
this.prerelease = [identifier, 0]
|
this.prerelease = [identifier, 0]
|
||||||
}
|
}
|
||||||
@ -9620,7 +9619,7 @@ module.exports = SemVer
|
|||||||
/***/ 5925:
|
/***/ 5925:
|
||||||
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
const {MAX_LENGTH} = __nccwpck_require__(2293)
|
const { MAX_LENGTH } = __nccwpck_require__(2293)
|
||||||
const { re, t } = __nccwpck_require__(9523)
|
const { re, t } = __nccwpck_require__(9523)
|
||||||
const SemVer = __nccwpck_require__(8088)
|
const SemVer = __nccwpck_require__(8088)
|
||||||
|
|
||||||
@ -9666,7 +9665,7 @@ const SEMVER_SPEC_VERSION = '2.0.0'
|
|||||||
|
|
||||||
const MAX_LENGTH = 256
|
const MAX_LENGTH = 256
|
||||||
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
|
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
|
||||||
/* istanbul ignore next */ 9007199254740991
|
/* istanbul ignore next */ 9007199254740991
|
||||||
|
|
||||||
// Max safe segment length for coercion.
|
// Max safe segment length for coercion.
|
||||||
const MAX_SAFE_COMPONENT_LENGTH = 16
|
const MAX_SAFE_COMPONENT_LENGTH = 16
|
||||||
@ -9675,7 +9674,7 @@ module.exports = {
|
|||||||
SEMVER_SPEC_VERSION,
|
SEMVER_SPEC_VERSION,
|
||||||
MAX_LENGTH,
|
MAX_LENGTH,
|
||||||
MAX_SAFE_INTEGER,
|
MAX_SAFE_INTEGER,
|
||||||
MAX_SAFE_COMPONENT_LENGTH
|
MAX_SAFE_COMPONENT_LENGTH,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -9721,7 +9720,7 @@ const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a)
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
compareIdentifiers,
|
compareIdentifiers,
|
||||||
rcompareIdentifiers
|
rcompareIdentifiers,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -9736,9 +9735,9 @@ const opts = ['includePrerelease', 'loose', 'rtl']
|
|||||||
const parseOptions = options =>
|
const parseOptions = options =>
|
||||||
!options ? {}
|
!options ? {}
|
||||||
: typeof options !== 'object' ? { loose: true }
|
: typeof options !== 'object' ? { loose: true }
|
||||||
: opts.filter(k => options[k]).reduce((options, k) => {
|
: opts.filter(k => options[k]).reduce((o, k) => {
|
||||||
options[k] = true
|
o[k] = true
|
||||||
return options
|
return o
|
||||||
}, {})
|
}, {})
|
||||||
module.exports = parseOptions
|
module.exports = parseOptions
|
||||||
|
|
||||||
@ -9760,7 +9759,7 @@ let R = 0
|
|||||||
|
|
||||||
const createToken = (name, value, isGlobal) => {
|
const createToken = (name, value, isGlobal) => {
|
||||||
const index = R++
|
const index = R++
|
||||||
debug(index, value)
|
debug(name, index, value)
|
||||||
t[name] = index
|
t[name] = index
|
||||||
src[index] = value
|
src[index] = value
|
||||||
re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
|
re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
|
||||||
@ -9928,8 +9927,8 @@ createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
|
|||||||
// Star ranges basically just allow anything at all.
|
// Star ranges basically just allow anything at all.
|
||||||
createToken('STAR', '(<|>)?=?\\s*\\*')
|
createToken('STAR', '(<|>)?=?\\s*\\*')
|
||||||
// >=0.0.0 is like a star
|
// >=0.0.0 is like a star
|
||||||
createToken('GTE0', '^\\s*>=\\s*0\.0\.0\\s*$')
|
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$')
|
||||||
createToken('GTE0PRE', '^\\s*>=\\s*0\.0\.0-0\\s*$')
|
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$')
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
1979
package-lock.json
generated
1979
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@ -6,8 +6,10 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc && ncc build",
|
"build": "tsc && ncc build",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"format-check": "echo \"Fake command that does nothing. It is used in reusable workflows\"",
|
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write **/*.{ts,yml,yaml}",
|
||||||
"lint": "echo \"Fake command that does nothing. It is used in reusable workflows\""
|
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check **/*.{ts,yml,yaml}",
|
||||||
|
"lint": "eslint --config ./.eslintrc.js **/*.ts",
|
||||||
|
"lint:fix": "eslint --config ./.eslintrc.js **/*.ts --fix"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -25,16 +27,22 @@
|
|||||||
"homepage": "https://github.com/actions/publish-action#readme",
|
"homepage": "https://github.com/actions/publish-action#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.2.7",
|
"@actions/core": "^1.2.7",
|
||||||
"@actions/http-client": "^1.0.11",
|
|
||||||
"@actions/github": "^4.0.0",
|
"@actions/github": "^4.0.0",
|
||||||
|
"@actions/http-client": "^1.0.11",
|
||||||
"semver": "^7.3.5"
|
"semver": "^7.3.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/semver": "^7.3.6",
|
"@types/semver": "^7.3.6",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
||||||
|
"@typescript-eslint/parser": "^5.54.0",
|
||||||
"@vercel/ncc": "^0.28.5",
|
"@vercel/ncc": "^0.28.5",
|
||||||
|
"eslint": "^8.35.0",
|
||||||
|
"eslint-config-prettier": "^8.6.0",
|
||||||
|
"eslint-plugin-jest": "^27.2.1",
|
||||||
"jest": "^27.2.5",
|
"jest": "^27.2.5",
|
||||||
"jest-circus": "^27.2.5",
|
"jest-circus": "^27.2.5",
|
||||||
|
"prettier": "^2.8.4",
|
||||||
"ts-jest": "^27.0.5",
|
"ts-jest": "^27.0.5",
|
||||||
"typescript": "^4.2.4"
|
"typescript": "^4.2.4"
|
||||||
}
|
}
|
||||||
|
171
src/api-utils.ts
171
src/api-utils.ts
@ -1,114 +1,115 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import { context } from '@actions/github';
|
import {context} from '@actions/github';
|
||||||
import { GitHub } from '@actions/github/lib/utils';
|
import {GitHub} from '@actions/github/lib/utils';
|
||||||
import { HttpClient } from '@actions/http-client';
|
import {HttpClient} from '@actions/http-client';
|
||||||
|
|
||||||
interface GitRef {
|
interface GitRef {
|
||||||
ref: string;
|
ref: string;
|
||||||
node_id: string;
|
node_id: string;
|
||||||
|
url: string;
|
||||||
|
object: {
|
||||||
|
type: string;
|
||||||
|
sha: string;
|
||||||
url: string;
|
url: string;
|
||||||
object: {
|
};
|
||||||
type: string;
|
|
||||||
sha: string;
|
|
||||||
url: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findTag(
|
async function findTag(
|
||||||
tag: string,
|
tag: string,
|
||||||
octokitClient: InstanceType<typeof GitHub>
|
octokitClient: InstanceType<typeof GitHub>
|
||||||
): Promise<GitRef | null> {
|
): Promise<GitRef | null> {
|
||||||
try {
|
try {
|
||||||
const { data: foundTag } = await octokitClient.git.getRef({
|
const {data: foundTag} = await octokitClient.git.getRef({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
ref: `tags/${tag}`
|
ref: `tags/${tag}`
|
||||||
});
|
});
|
||||||
|
|
||||||
return foundTag;
|
return foundTag;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.status === 404) {
|
if (err.status === 404) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Retrieving refs failed with the following error: ${err}`
|
`Retrieving refs failed with the following error: ${err}`
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getTagSHA(
|
async function getTagSHA(
|
||||||
tag: string,
|
tag: string,
|
||||||
octokitClient: InstanceType<typeof GitHub>
|
octokitClient: InstanceType<typeof GitHub>
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const foundTag = await findTag(tag, octokitClient);
|
const foundTag = await findTag(tag, octokitClient);
|
||||||
if (!foundTag) {
|
if (!foundTag) {
|
||||||
throw new Error(
|
throw new Error(`The '${tag}' tag does not exist in the remote repository`);
|
||||||
`The '${tag}' tag does not exist in the remote repository`
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return foundTag.object.sha;
|
return foundTag.object.sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function validateIfReleaseIsPublished(
|
export async function validateIfReleaseIsPublished(
|
||||||
tag: string,
|
tag: string,
|
||||||
octokitClient: InstanceType<typeof GitHub>
|
octokitClient: InstanceType<typeof GitHub>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const { data: foundRelease } = await octokitClient.repos.getReleaseByTag({
|
const {data: foundRelease} = await octokitClient.repos.getReleaseByTag({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
tag,
|
tag
|
||||||
});
|
});
|
||||||
|
|
||||||
if (foundRelease.prerelease) {
|
if (foundRelease.prerelease) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The '${foundRelease.name}' release is marked as pre-release. Updating tags for pre-release is not supported`
|
`The '${foundRelease.name}' release is marked as pre-release. Updating tags for pre-release is not supported`
|
||||||
);
|
);
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (err.status === 404) {
|
|
||||||
throw new Error(
|
|
||||||
`No GitHub release found for the ${tag} tag`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`Retrieving releases failed with the following error: ${err}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.status === 404) {
|
||||||
|
throw new Error(`No GitHub release found for the ${tag} tag`);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Retrieving releases failed with the following error: ${err}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateTag(
|
export async function updateTag(
|
||||||
sourceTag: string,
|
sourceTag: string,
|
||||||
targetTag: string,
|
targetTag: string,
|
||||||
octokitClient: InstanceType<typeof GitHub>
|
octokitClient: InstanceType<typeof GitHub>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const sourceTagSHA = await getTagSHA(sourceTag, octokitClient);
|
const sourceTagSHA = await getTagSHA(sourceTag, octokitClient);
|
||||||
const foundTargetTag = await findTag(targetTag, octokitClient);
|
const foundTargetTag = await findTag(targetTag, octokitClient);
|
||||||
const refName = `tags/${targetTag}`;
|
const refName = `tags/${targetTag}`;
|
||||||
|
|
||||||
if (foundTargetTag) {
|
if (foundTargetTag) {
|
||||||
core.info(`Updating the '${targetTag}' tag to point to the '${sourceTag}' tag`);
|
core.info(
|
||||||
|
`Updating the '${targetTag}' tag to point to the '${sourceTag}' tag`
|
||||||
|
);
|
||||||
|
|
||||||
await octokitClient.git.updateRef({
|
await octokitClient.git.updateRef({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
ref: refName,
|
ref: refName,
|
||||||
sha: sourceTagSHA,
|
sha: sourceTagSHA,
|
||||||
force: true
|
force: true
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
core.info(`Creating the '${targetTag}' tag from the '${sourceTag}' tag`);
|
core.info(`Creating the '${targetTag}' tag from the '${sourceTag}' tag`);
|
||||||
|
|
||||||
await octokitClient.git.createRef({
|
await octokitClient.git.createRef({
|
||||||
...context.repo,
|
...context.repo,
|
||||||
ref: `refs/${refName}`,
|
ref: `refs/${refName}`,
|
||||||
sha: sourceTagSHA
|
sha: sourceTagSHA
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postMessageToSlack(slackWebhook: string, message: string): Promise<void> {
|
export async function postMessageToSlack(
|
||||||
const jsonData = {text: message}
|
slackWebhook: string,
|
||||||
const http = new HttpClient();
|
message: string
|
||||||
await http.postJson(slackWebhook, jsonData);
|
): Promise<void> {
|
||||||
}
|
const jsonData = {text: message};
|
||||||
|
const http = new HttpClient();
|
||||||
|
await http.postJson(slackWebhook, jsonData);
|
||||||
|
}
|
||||||
|
65
src/main.ts
65
src/main.ts
@ -1,40 +1,49 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as github from '@actions/github';
|
import * as github from '@actions/github';
|
||||||
import { context } from '@actions/github';
|
import {context} from '@actions/github';
|
||||||
import { updateTag, validateIfReleaseIsPublished, postMessageToSlack } from './api-utils';
|
import {
|
||||||
import { validateSemverVersionFromTag, getMajorTagFromFullTag } from './version-utils';
|
updateTag,
|
||||||
|
validateIfReleaseIsPublished,
|
||||||
|
postMessageToSlack
|
||||||
|
} from './api-utils';
|
||||||
|
import {
|
||||||
|
validateSemverVersionFromTag,
|
||||||
|
getMajorTagFromFullTag
|
||||||
|
} from './version-utils';
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const token = core.getInput('token');
|
const token = core.getInput('token');
|
||||||
const octokitClient = github.getOctokit(token);
|
const octokitClient = github.getOctokit(token);
|
||||||
const sourceTagName = core.getInput('source-tag');
|
const sourceTagName = core.getInput('source-tag');
|
||||||
|
|
||||||
validateSemverVersionFromTag(sourceTagName);
|
validateSemverVersionFromTag(sourceTagName);
|
||||||
|
|
||||||
await validateIfReleaseIsPublished(sourceTagName, octokitClient);
|
await validateIfReleaseIsPublished(sourceTagName, octokitClient);
|
||||||
|
|
||||||
const majorTag = getMajorTagFromFullTag(sourceTagName);
|
const majorTag = getMajorTagFromFullTag(sourceTagName);
|
||||||
await updateTag(sourceTagName, majorTag, octokitClient);
|
await updateTag(sourceTagName, majorTag, octokitClient);
|
||||||
|
|
||||||
core.setOutput('major-tag', majorTag);
|
core.setOutput('major-tag', majorTag);
|
||||||
core.info(`The '${majorTag}' major tag now points to the '${sourceTagName}' tag`);
|
core.info(
|
||||||
|
`The '${majorTag}' major tag now points to the '${sourceTagName}' tag`
|
||||||
|
);
|
||||||
|
|
||||||
const slackMessage = `The ${majorTag} tag has been successfully updated for the ${context.repo.repo} action to include changes from ${sourceTagName}`;
|
const slackMessage = `The ${majorTag} tag has been successfully updated for the ${context.repo.repo} action to include changes from ${sourceTagName}`;
|
||||||
await reportStatusToSlack(slackMessage);
|
await reportStatusToSlack(slackMessage);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed((error as Error).message);
|
core.setFailed((error as Error).message);
|
||||||
|
|
||||||
const slackMessage = `Failed to update a major tag for the ${context.repo.repo} action`;
|
const slackMessage = `Failed to update a major tag for the ${context.repo.repo} action`;
|
||||||
await reportStatusToSlack(slackMessage);
|
await reportStatusToSlack(slackMessage);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
async function reportStatusToSlack(message: string): Promise<void> {
|
|
||||||
const slackWebhook = core.getInput('slack-webhook');
|
|
||||||
if (slackWebhook) {
|
|
||||||
await postMessageToSlack(slackWebhook, message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run();
|
async function reportStatusToSlack(message: string): Promise<void> {
|
||||||
|
const slackWebhook = core.getInput('slack-webhook');
|
||||||
|
if (slackWebhook) {
|
||||||
|
await postMessageToSlack(slackWebhook, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
|
@ -2,24 +2,24 @@ import semverParse from 'semver/functions/parse';
|
|||||||
import SemVer from 'semver/classes/semver';
|
import SemVer from 'semver/classes/semver';
|
||||||
|
|
||||||
export function isStableSemverVersion(version: SemVer): boolean {
|
export function isStableSemverVersion(version: SemVer): boolean {
|
||||||
return version.prerelease.length === 0
|
return version.prerelease.length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMajorTagFromFullTag(fullTag: string): string {
|
export function getMajorTagFromFullTag(fullTag: string): string {
|
||||||
return fullTag.split('.')[0];
|
return fullTag.split('.')[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateSemverVersionFromTag(tag: string): void {
|
export function validateSemverVersionFromTag(tag: string): void {
|
||||||
const semverVersion = semverParse(tag);
|
const semverVersion = semverParse(tag);
|
||||||
if (!semverVersion) {
|
if (!semverVersion) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The '${tag}' doesn't satisfy semantic versioning specification`
|
`The '${tag}' doesn't satisfy semantic versioning specification`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isStableSemverVersion(semverVersion)) {
|
if (!isStableSemverVersion(semverVersion)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'It is not allowed to specify pre-release version to update the major tag'
|
'It is not allowed to specify pre-release version to update the major tag'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
|
Loading…
Reference in New Issue
Block a user