Skip to content

Commit

Permalink
feat: Add support for new ignoreMissing and ignoreOptions options (#63)
Browse files Browse the repository at this point in the history
* feat: Add ignore_missing and ignore_options

* ref: Rename validate.ts to options.ts to be more descriptive

* feat: Add stripCommonPrefix option

* Update src/options.ts

Co-authored-by: Abhijeet Prasad <aprasad@sentry.io>

Co-authored-by: Abhijeet Prasad <aprasad@sentry.io>
  • Loading branch information
kamilogorek and AbhiPrasad authored Jul 23, 2021
1 parent a38cf32 commit 62ef65f
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 108 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,16 @@ The following are all _required_.
|---|---|---|
|`environment`|Set the environment for this release. E.g. "production" or "staging". Omit to skip adding deploy to release.|-|
|`finalize`|When false, omit marking the release as finalized and released.|`true`|
|`ignore_missing`|When the flag is set and the previous release commit was not found in the repository, will create a release with the default commits count instead of failing the command.|`false`|
|`ignore_empty`|When the flag is set, command will not fail and just exit silently if no new commits for a given release have been found.|`false`|
|`sourcemaps`|Space-separated list of paths to JavaScript sourcemaps. Omit to skip uploading sourcemaps.|-|
|`started_at`|Unix timestamp of the release start date. Omit for current time.|-|
|`version`|Identifier that uniquely identifies the releases. _Note: the `refs/tags/` prefix is automatically stripped when `version` is `github.ref`._|<code>${{&nbsp;github.sha&nbsp;}}</code>|
|`version_prefix`|Value prepended to auto-generated version. For example "v".|-|
|`set_commits`|Specify whether to set commits for the release. Either "auto" or "skip".|"auto"|
|`projects`|Space-separated list of paths of projects. When omitted, falls back to the environment variable `SENTRY_PROJECT` to determine the project.|-|
|`url_prefix`|Adds a prefix to source map urls after stripping them.|-|
|`strip_common_prefix`|Will remove a common prefix from uploaded filenames. Useful for removing a path that is build-machine-specific.|`false`|

### Examples
- Create a new Sentry release for the `production` environment and upload JavaScript source maps from the `./lib` directory.
Expand Down
43 changes: 30 additions & 13 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,52 @@ import {execSync} from 'child_process';
import * as path from 'path';
import * as process from 'process';
import {
getShouldFinalize,
getBooleanOption,
getSourcemaps,
getStartedAt,
getVersion,
getSetCommitsOption,
getProjects,
getUrlPrefixOption,
} from '../src/validate';
} from '../src/options';

describe('validate', () => {
describe('options', () => {
beforeAll(() => {
process.env['MOCK'] = 'true';
});

describe('getShouldFinalize', () => {
const errorMessage = 'finalize is not a boolean';
describe('getBooleanOption', () => {
const option = 'finalize';
const defaultValue = true;
const errorMessage = `${option} is not a boolean`;

afterEach(() => {
delete process.env['INPUT_FINALIZE'];
});

test('should throw an error when finalize is invalid', async () => {
test('should throw an error when option type is not a boolean', () => {
process.env['INPUT_FINALIZE'] = 'error';
expect(() => getShouldFinalize()).toThrow(errorMessage);
expect(() => getBooleanOption(option, defaultValue)).toThrow(
errorMessage
);
});

test('should return true when finalize is omitted', async () => {
expect(getShouldFinalize()).toBe(true);
test('should return defaultValue if option is omitted', () => {
expect(getBooleanOption(option, defaultValue)).toBe(true);
});

test('should return false when finalize is false', () => {
test('should return true when option is true or 1', () => {
process.env['INPUT_FINALIZE'] = 'true';
expect(getBooleanOption(option, defaultValue)).toBe(true);
process.env['INPUT_FINALIZE'] = '1';
expect(getBooleanOption(option, defaultValue)).toBe(true);
});

test('should return false when option is false or 0', () => {
process.env['INPUT_FINALIZE'] = 'false';
expect(getShouldFinalize()).toBe(false);
expect(getBooleanOption(option, defaultValue)).toBe(false);
process.env['INPUT_FINALIZE'] = '0';
expect(getBooleanOption(option, defaultValue)).toBe(false);
});
});

Expand Down Expand Up @@ -121,6 +135,7 @@ describe('validate', () => {
expect(await getVersion()).toBe(`prefix-v1.0.0`);
});
});

describe('getSetCommitsOption', () => {
afterEach(() => {
delete process.env['INPUT_SET_COMMITS'];
Expand All @@ -143,6 +158,7 @@ describe('validate', () => {
expect(() => getSetCommitsOption()).toThrow(errorMessage);
});
});

describe('getProjects', () => {
afterEach(() => {
delete process.env['SENTRY_PROJECT'];
Expand All @@ -167,15 +183,16 @@ describe('validate', () => {
);
});
});

describe('getUrlPrefixOption', () => {
afterEach(() => {
delete process.env['URL_PREFIX'];
});
it('get url prefix', () => {
process.env['INPUT_URL_PREFIX'] = 'build';
expect(getUrlPrefixOption()).toEqual('build');
})
})
});
});
});

// shows how the runner will run a javascript action with env / stdout protocol
Expand Down
9 changes: 9 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ inputs:
finalize:
description: 'When false, omit marking the release as finalized and released.'
default: true
ignore_missing:
description: 'When the flag is set and the previous release commit was not found in the repository, will create a release with the default commits count instead of failing the command.'
required: false
ignore_empty:
description: 'When the flag is set, command will not fail and just exit silently if no new commits for a given release have been found.'
required: false
started_at:
description: 'Unix timestamp of the release start date. Omit for current time.'
required: false
Expand All @@ -29,6 +35,9 @@ inputs:
url_prefix:
description: 'Adds a prefix to source map urls after stripping them.'
required: false
strip_common_prefix:
description: 'Will remove a common prefix from uploaded filenames. Useful for removing a path that is build-machine-specific.'
required: false
runs:
using: 'docker'
image: 'docker://sentryintegrations/sentry-github-action-release:latest'
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
"license": "MIT",
"dependencies": {
"@actions/core": "^1.2.4",
"@sentry/cli": "^1.59.0",
"@sentry/types": "^5.17.0"
"@sentry/cli": "^1.67.2"
},
"devDependencies": {
"@types/jest": "^26.0.0",
Expand Down
6 changes: 3 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import SentryCli, {Releases} from '@sentry/cli';
import SentryCli, {SentryCliReleases} from '@sentry/cli';
// @ts-ignore
import {version} from '../package.json';

Expand All @@ -7,8 +7,8 @@ import {version} from '../package.json';
*
* When the `MOCK` environment variable is set, stub out network calls.
*/
let cli: Releases;
export const getCLI = (): Releases => {
let cli: SentryCliReleases;
export const getCLI = (): SentryCliReleases => {
// Set the User-Agent string.
process.env['SENTRY_PIPELINE'] = `github-action-release/${version}`;

Expand Down
35 changes: 23 additions & 12 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import * as core from '@actions/core';
import {getCLI} from './cli';
import * as validate from './validate';
import * as options from './options';

(async () => {
try {
const cli = getCLI();

// Validate parameters first so we can fail early.
validate.checkEnvironmentVariables();
const environment = validate.getEnvironment();
const sourcemaps = validate.getSourcemaps();
const shouldFinalize = validate.getShouldFinalize();
const deployStartedAtOption = validate.getStartedAt();
const setCommitsOption = validate.getSetCommitsOption();
const projects = validate.getProjects();
const urlPrefix = validate.getUrlPrefixOption();
// Validate options first so we can fail early.
options.checkEnvironmentVariables();

const version = await validate.getVersion();
const environment = options.getEnvironment();
const sourcemaps = options.getSourcemaps();
const shouldFinalize = options.getBooleanOption('finalize', true);
const ignoreMissing = options.getBooleanOption('ignore_missing', false);
const ignoreEmpty = options.getBooleanOption('ignore_empty', false);
const deployStartedAtOption = options.getStartedAt();
const setCommitsOption = options.getSetCommitsOption();
const projects = options.getProjects();
const urlPrefix = options.getUrlPrefixOption();
const stripCommonPrefix = options.getBooleanOption(
'strip_common_prefix',
false
);
const version = await options.getVersion();

core.debug(`Version is ${version}`);
await cli.new(version, {projects});

if (setCommitsOption !== 'skip') {
core.debug(`Setting commits with option '${setCommitsOption}'`);
await cli.setCommits(version, {auto: true});
await cli.setCommits(version, {
auto: true,
ignoreMissing,
ignoreEmpty,
});
}

if (sourcemaps.length) {
Expand All @@ -36,6 +46,7 @@ import * as validate from './validate';
include: sourcemaps,
projects: localProjects,
urlPrefix,
stripCommonPrefix,
};
return cli.uploadSourceMaps(version, sourceMapOptions);
})
Expand Down
25 changes: 15 additions & 10 deletions src/validate.ts → src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {getCLI} from './cli';
export const getVersion = async (): Promise<string> => {
const versionOption: string = core.getInput('version');
const versionPrefixOption: string = core.getInput('version_prefix');
let version = ''
let version = '';
if (versionOption) {
// If the users passes in `${{github.ref}}, then it will have an unwanted prefix.
version = versionOption.replace(/^(refs\/tags\/)/, '');
Expand Down Expand Up @@ -82,17 +82,22 @@ export const getSourcemaps = (): string[] => {
};

/**
* Find out from input if we should finalize the release.
* Fetch boolean option from input. Throws error if option value is not a boolean.
* @param input string
* @param defaultValue boolean
* @returns boolean
*/
export const getShouldFinalize = (): boolean => {
const finalizeOption = core.getInput('finalize');
if (!finalizeOption) {
return true;
export const getBooleanOption = (
input: string,
defaultValue: boolean
): boolean => {
const option = core.getInput(input);
if (!option) {
return defaultValue;
}

const finalize = finalizeOption.trim().toLowerCase();
switch (finalize) {
const value = option.trim().toLowerCase();
switch (value) {
case 'true':
case '1':
return true;
Expand All @@ -102,7 +107,7 @@ export const getShouldFinalize = (): boolean => {
return false;
}

throw Error('finalize is not a boolean');
throw Error(`${input} is not a boolean`);
};

export const getSetCommitsOption = (): 'auto' | 'skip' => {
Expand Down Expand Up @@ -159,4 +164,4 @@ export const getProjects = (): string[] => {

export const getUrlPrefixOption = (): string => {
return core.getInput('url_prefix');
}
};
54 changes: 0 additions & 54 deletions src/sentry-cli.d.ts

This file was deleted.

Loading

0 comments on commit 62ef65f

Please sign in to comment.