Add and configure ESLint and update configuration for Prettier (#26)
* Add ESLint and Prettier * Rebuild action * Update package.json * Update licenses * Fix review pointspull/27/head
parent
87579b14ff
commit
9169aa7609
@ -0,0 +1,6 @@
|
||||
# Ignore list
|
||||
/*
|
||||
|
||||
# Do not ignore these folders:
|
||||
!__tests__/
|
||||
!src/
|
@ -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
|
||||
}
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
* text=auto eol=lf
|
||||
.licenses/** -diff linguist-generated=true
|
@ -0,0 +1,7 @@
|
||||
# Ignore list
|
||||
/*
|
||||
|
||||
# Do not ignore these folders:
|
||||
!__tests__/
|
||||
!.github/
|
||||
!src/
|
@ -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 apiUtils from "../src/api-utils";
|
||||
import * as github from '@actions/github';
|
||||
import * as apiUtils from '../src/api-utils';
|
||||
|
||||
const prereleaseData = require("./data/pre-release.json");
|
||||
const releaseData = require("./data/release.json");
|
||||
import prereleaseData from './data/pre-release.json';
|
||||
import releaseData from './data/release.json';
|
||||
|
||||
const token = "faketoken";
|
||||
const token = 'faketoken';
|
||||
const octokitClient = github.getOctokit(token);
|
||||
|
||||
let getReleaseSpy: jest.SpyInstance;
|
||||
|
||||
process.env.GITHUB_REPOSITORY = "test/repository";
|
||||
|
||||
describe("validateIfReleaseIsPublished", () => {
|
||||
beforeEach(() => {
|
||||
getReleaseSpy = jest.spyOn(octokitClient.repos, "getReleaseByTag");
|
||||
});
|
||||
|
||||
it("throw if release is marked as pre-release", async () => {
|
||||
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 () => {
|
||||
getReleaseSpy.mockReturnValue(releaseData);
|
||||
|
||||
expect.assertions(1);
|
||||
await expect(apiUtils.validateIfReleaseIsPublished("v1.1.0", octokitClient)).resolves.not.toThrow();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
process.env.GITHUB_REPOSITORY = 'test/repository';
|
||||
|
||||
describe('validateIfReleaseIsPublished', () => {
|
||||
beforeEach(() => {
|
||||
getReleaseSpy = jest.spyOn(octokitClient.repos, 'getReleaseByTag');
|
||||
});
|
||||
|
||||
it('throw if release is marked as pre-release', async () => {
|
||||
getReleaseSpy.mockReturnValue(prereleaseData);
|
||||
|
||||
expect.assertions(1);
|
||||
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"
|
||||
);
|
||||
});
|
||||
|
||||
it('validate that release is published', async () => {
|
||||
getReleaseSpy.mockReturnValue(releaseData);
|
||||
|
||||
expect.assertions(1);
|
||||
await expect(
|
||||
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", () => {
|
||||
it("validate if a version is stable", () => {
|
||||
const semverVersion = require("./data/stable-semver.json");
|
||||
expect(versionUtils.isStableSemverVersion(semverVersion)).toBeTruthy();
|
||||
});
|
||||
describe('isStableSemverVersion', () => {
|
||||
it('validate if a version is stable', () => {
|
||||
expect(
|
||||
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 version with build metadata is stable', () => {
|
||||
expect(
|
||||
versionUtils.isStableSemverVersion(stableBuildSemver as any)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it("validate if a pre-release version is not stable", () => {
|
||||
const semverVersion = require("./data/prerelease-semver.json");
|
||||
expect(versionUtils.isStableSemverVersion(semverVersion)).toBeFalsy();
|
||||
});
|
||||
it('validate if a pre-release version is not stable', () => {
|
||||
expect(
|
||||
versionUtils.isStableSemverVersion(prereleaseSemver as any)
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it("validate if a pre-release version with build metadata is not stable", () => {
|
||||
const semverVersion = require("./data/prerelease-build-semver.json");
|
||||
expect(versionUtils.isStableSemverVersion(semverVersion)).toBeFalsy();
|
||||
});
|
||||
it('validate if a pre-release version with build metadata is not stable', () => {
|
||||
expect(
|
||||
versionUtils.isStableSemverVersion(prereleaseBuildSemver as any)
|
||||
).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("validateSemverVersionFromTag", () => {
|
||||
it("validate a tag containing an valid semantic version", () => {
|
||||
expect(() => versionUtils.validateSemverVersionFromTag("1.0.0")).not.toThrow();
|
||||
});
|
||||
describe('validateSemverVersionFromTag', () => {
|
||||
it('validate a tag containing a valid semantic version', () => {
|
||||
expect(() =>
|
||||
versionUtils.validateSemverVersionFromTag('1.0.0')
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it("validate a tag containing an valid semantic version with 'v' prefix", () => {
|
||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0")).not.toThrow();
|
||||
});
|
||||
it("validate a tag containing a valid semantic version with 'v' prefix", () => {
|
||||
expect(() =>
|
||||
versionUtils.validateSemverVersionFromTag('v1.0.0')
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it("validate a tag containing an valid semantic version with build metadata", () => {
|
||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0+20130313144700")).not.toThrow();
|
||||
});
|
||||
it('validate a tag containing a valid semantic version with build metadata', () => {
|
||||
expect(() =>
|
||||
versionUtils.validateSemverVersionFromTag('v1.0.0+20130313144700')
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it("throw when a tag contains an invalid semantic version", () => {
|
||||
expect(() => versionUtils.validateSemverVersionFromTag("1.0.0invalid")).toThrowError(
|
||||
"The '1.0.0invalid' doesn't satisfy semantic versioning specification"
|
||||
);
|
||||
});
|
||||
it('throw when a tag contains an invalid semantic version', () => {
|
||||
expect(() =>
|
||||
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", () => {
|
||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0-beta.1")).toThrowError(
|
||||
"It is not allowed to specify pre-release version to update the major tag"
|
||||
);
|
||||
});
|
||||
it('throw when a tag contains a valid unstable semantic version', () => {
|
||||
expect(() =>
|
||||
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", () => {
|
||||
expect(() => versionUtils.validateSemverVersionFromTag("v1.0.0-beta.1+20130313144700")).toThrowError(
|
||||
"It is not allowed to specify pre-release version to update the major tag"
|
||||
);
|
||||
});
|
||||
it('throw when a tag contains a valid unstable semantic version with build metadata', () => {
|
||||
expect(() =>
|
||||
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("get a valid major tag from full tag", () => {
|
||||
it.each([
|
||||
["1.0.0", "1"],
|
||||
["v1.0.0", "v1"],
|
||||
["v1.0.0-beta.1", "v1"],
|
||||
["v1.0.0+20130313144700", "v1"],
|
||||
] as [string, string][])("%s -> %s", (sourceTag: string, expectedMajorTag: string) => {
|
||||
const resultantMajorTag = versionUtils.getMajorTagFromFullTag(sourceTag);
|
||||
expect(resultantMajorTag).toBe(expectedMajorTag);
|
||||
});
|
||||
});
|
||||
describe('getMajorTagFromFullTag', () => {
|
||||
describe('get a valid major tag from full tag', () => {
|
||||
it.each([
|
||||
['1.0.0', '1'],
|
||||
['v1.0.0', 'v1'],
|
||||
['v1.0.0-beta.1', 'v1'],
|
||||
['v1.0.0+20130313144700', 'v1']
|
||||
] as [string, string][])(
|
||||
'%s -> %s',
|
||||
(sourceTag: string, expectedMajorTag: string) => {
|
||||
const resultantMajorTag =
|
||||
versionUtils.getMajorTagFromFullTag(sourceTag);
|
||||
expect(resultantMajorTag).toBe(expectedMajorTag);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
File diff suppressed because it is too large
Load Diff
@ -1,114 +1,115 @@
|
||||
import * as core from '@actions/core';
|
||||
import { context } from '@actions/github';
|
||||
import { GitHub } from '@actions/github/lib/utils';
|
||||
import { HttpClient } from '@actions/http-client';
|
||||
import {context} from '@actions/github';
|
||||
import {GitHub} from '@actions/github/lib/utils';
|
||||
import {HttpClient} from '@actions/http-client';
|
||||
|
||||
interface GitRef {
|
||||
ref: string;
|
||||
node_id: string;
|
||||
ref: string;
|
||||
node_id: string;
|
||||
url: string;
|
||||
object: {
|
||||
type: string;
|
||||
sha: string;
|
||||
url: string;
|
||||
object: {
|
||||
type: string;
|
||||
sha: string;
|
||||
url: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
async function findTag(
|
||||
tag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
tag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
): Promise<GitRef | null> {
|
||||
try {
|
||||
const { data: foundTag } = await octokitClient.git.getRef({
|
||||
...context.repo,
|
||||
ref: `tags/${tag}`
|
||||
});
|
||||
try {
|
||||
const {data: foundTag} = await octokitClient.git.getRef({
|
||||
...context.repo,
|
||||
ref: `tags/${tag}`
|
||||
});
|
||||
|
||||
return foundTag;
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
return null;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Retrieving refs failed with the following error: ${err}`
|
||||
);
|
||||
}
|
||||
return foundTag;
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
return null;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Retrieving refs failed with the following error: ${err}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getTagSHA(
|
||||
tag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
tag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
): Promise<string> {
|
||||
const foundTag = await findTag(tag, octokitClient);
|
||||
if (!foundTag) {
|
||||
throw new Error(
|
||||
`The '${tag}' tag does not exist in the remote repository`
|
||||
);
|
||||
}
|
||||
const foundTag = await findTag(tag, octokitClient);
|
||||
if (!foundTag) {
|
||||
throw new Error(`The '${tag}' tag does not exist in the remote repository`);
|
||||
}
|
||||
|
||||
return foundTag.object.sha;
|
||||
return foundTag.object.sha;
|
||||
}
|
||||
|
||||
export async function validateIfReleaseIsPublished(
|
||||
tag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
tag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
): Promise<void> {
|
||||
try {
|
||||
const { data: foundRelease } = await octokitClient.repos.getReleaseByTag({
|
||||
...context.repo,
|
||||
tag,
|
||||
});
|
||||
try {
|
||||
const {data: foundRelease} = await octokitClient.repos.getReleaseByTag({
|
||||
...context.repo,
|
||||
tag
|
||||
});
|
||||
|
||||
if (foundRelease.prerelease) {
|
||||
throw new Error(
|
||||
`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}`
|
||||
);
|
||||
}
|
||||
if (foundRelease.prerelease) {
|
||||
throw new Error(
|
||||
`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}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateTag(
|
||||
sourceTag: string,
|
||||
targetTag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
sourceTag: string,
|
||||
targetTag: string,
|
||||
octokitClient: InstanceType<typeof GitHub>
|
||||
): Promise<void> {
|
||||
const sourceTagSHA = await getTagSHA(sourceTag, octokitClient);
|
||||
const foundTargetTag = await findTag(targetTag, octokitClient);
|
||||
const refName = `tags/${targetTag}`;
|
||||
const sourceTagSHA = await getTagSHA(sourceTag, octokitClient);
|
||||
const foundTargetTag = await findTag(targetTag, octokitClient);
|
||||
const refName = `tags/${targetTag}`;
|
||||
|
||||
if (foundTargetTag) {
|
||||
core.info(`Updating the '${targetTag}' tag to point to the '${sourceTag}' tag`);
|
||||
if (foundTargetTag) {
|
||||
core.info(
|
||||
`Updating the '${targetTag}' tag to point to the '${sourceTag}' tag`
|
||||
);
|
||||
|
||||
await octokitClient.git.updateRef({
|
||||
...context.repo,
|
||||
ref: refName,
|
||||
sha: sourceTagSHA,
|
||||
force: true
|
||||
});
|
||||
} else {
|
||||
core.info(`Creating the '${targetTag}' tag from the '${sourceTag}' tag`);
|
||||
await octokitClient.git.updateRef({
|
||||
...context.repo,
|
||||
ref: refName,
|
||||
sha: sourceTagSHA,
|
||||
force: true
|
||||
});
|
||||
} else {
|
||||
core.info(`Creating the '${targetTag}' tag from the '${sourceTag}' tag`);
|
||||
|
||||
await octokitClient.git.createRef({
|
||||
...context.repo,
|
||||
ref: `refs/${refName}`,
|
||||
sha: sourceTagSHA
|
||||
});
|
||||
}
|
||||
await octokitClient.git.createRef({
|
||||
...context.repo,
|
||||
ref: `refs/${refName}`,
|
||||
sha: sourceTagSHA
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function postMessageToSlack(slackWebhook: string, message: string): Promise<void> {
|
||||
const jsonData = {text: message}
|
||||
const http = new HttpClient();
|
||||
await http.postJson(slackWebhook, jsonData);
|
||||
export async function postMessageToSlack(
|
||||
slackWebhook: string,
|
||||
message: string
|
||||
): Promise<void> {
|
||||
const jsonData = {text: message};
|
||||
const http = new HttpClient();
|
||||
await http.postJson(slackWebhook, jsonData);
|
||||
}
|
@ -1,40 +1,49 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as github from '@actions/github';
|
||||
import { context } from '@actions/github';
|
||||
import { updateTag, validateIfReleaseIsPublished, postMessageToSlack } from './api-utils';
|
||||
import { validateSemverVersionFromTag, getMajorTagFromFullTag } from './version-utils';
|
||||
import {context} from '@actions/github';
|
||||
import {
|
||||
updateTag,
|
||||
validateIfReleaseIsPublished,
|
||||
postMessageToSlack
|
||||
} from './api-utils';
|
||||
import {
|
||||
validateSemverVersionFromTag,
|
||||
getMajorTagFromFullTag
|
||||
} from './version-utils';
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const token = core.getInput('token');
|
||||
const octokitClient = github.getOctokit(token);
|
||||
const sourceTagName = core.getInput('source-tag');
|
||||
try {
|
||||
const token = core.getInput('token');
|
||||
const octokitClient = github.getOctokit(token);
|
||||
const sourceTagName = core.getInput('source-tag');
|
||||
|
||||
validateSemverVersionFromTag(sourceTagName);
|
||||
validateSemverVersionFromTag(sourceTagName);
|
||||
|
||||
await validateIfReleaseIsPublished(sourceTagName, octokitClient);
|
||||
await validateIfReleaseIsPublished(sourceTagName, octokitClient);
|
||||
|
||||
const majorTag = getMajorTagFromFullTag(sourceTagName);
|
||||
await updateTag(sourceTagName, majorTag, octokitClient);
|
||||
const majorTag = getMajorTagFromFullTag(sourceTagName);
|
||||
await updateTag(sourceTagName, majorTag, octokitClient);
|
||||
|
||||
core.setOutput('major-tag', majorTag);
|
||||
core.info(`The '${majorTag}' major tag now points to the '${sourceTagName}' tag`);
|
||||
core.setOutput('major-tag', majorTag);
|
||||
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}`;
|
||||
await reportStatusToSlack(slackMessage);
|
||||
} catch (error) {
|
||||
core.setFailed((error as Error).message);
|
||||
const slackMessage = `The ${majorTag} tag has been successfully updated for the ${context.repo.repo} action to include changes from ${sourceTagName}`;
|
||||
await reportStatusToSlack(slackMessage);
|
||||
} catch (error) {
|
||||
core.setFailed((error as Error).message);
|
||||
|
||||
const slackMessage = `Failed to update a major tag for the ${context.repo.repo} action`;
|
||||
await reportStatusToSlack(slackMessage);
|
||||
}
|
||||
};
|
||||
const slackMessage = `Failed to update a major tag for the ${context.repo.repo} action`;
|
||||
await reportStatusToSlack(slackMessage);
|
||||
}
|
||||
}
|
||||
|
||||
async function reportStatusToSlack(message: string): Promise<void> {
|
||||
const slackWebhook = core.getInput('slack-webhook');
|
||||
if (slackWebhook) {
|
||||
await postMessageToSlack(slackWebhook, message);
|
||||
}
|
||||
const slackWebhook = core.getInput('slack-webhook');
|
||||
if (slackWebhook) {
|
||||
await postMessageToSlack(slackWebhook, message);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
Loading…
Reference in New Issue