Adds support for `dist` as input value for GitHub Action:
```yaml
- uses: getsentry/action-release@v1
with:
environment: 'production'
sourcemaps: './lib'
dist: ${{ github.sha }}
```
Note that this repo uses `@sentry/cli@^1.67.2` and there is a related fix in `2.3.1`:
> fix: move dist option to SentryCliUploadSourceMapsOptions (#1269) by @ikenfin
> [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#231)
The fix was to move the `dist` option from being under `SentryCliOptions` (incorrect) to be under `SentryCliUploadSourceMapsOptions` (correct)
This does not affect the GH action as those types are not referenced directly by the action.
Resolves getsentry/action-release#74
---------
Co-authored-by: Armen Zambrano G <[email protected]>
232 lines
7.0 KiB
TypeScript
232 lines
7.0 KiB
TypeScript
import {execSync} from 'child_process';
|
|
import * as path from 'path';
|
|
import * as process from 'process';
|
|
import {
|
|
getBooleanOption,
|
|
getDist,
|
|
getSourcemaps,
|
|
getStartedAt,
|
|
getVersion,
|
|
getSetCommitsOption,
|
|
getProjects,
|
|
getUrlPrefixOption,
|
|
} from '../src/options';
|
|
|
|
describe('options', () => {
|
|
beforeAll(() => {
|
|
process.env['MOCK'] = 'true';
|
|
});
|
|
|
|
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 option type is not a boolean', () => {
|
|
process.env['INPUT_FINALIZE'] = 'error';
|
|
expect(() => getBooleanOption(option, defaultValue)).toThrow(
|
|
errorMessage
|
|
);
|
|
});
|
|
|
|
test('should return defaultValue if option is omitted', () => {
|
|
expect(getBooleanOption(option, defaultValue)).toBe(true);
|
|
});
|
|
|
|
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(getBooleanOption(option, defaultValue)).toBe(false);
|
|
process.env['INPUT_FINALIZE'] = '0';
|
|
expect(getBooleanOption(option, defaultValue)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('getSourcemaps', () => {
|
|
afterEach(() => {
|
|
delete process.env['INPUT_SOURCEMAPS'];
|
|
});
|
|
|
|
test('should return empty list when sourcemaps is omitted', async () => {
|
|
expect(getSourcemaps()).toEqual([]);
|
|
});
|
|
|
|
test('should return array when sourcemaps is false', () => {
|
|
process.env['INPUT_SOURCEMAPS'] = './lib';
|
|
expect(getSourcemaps()).toEqual(['./lib']);
|
|
});
|
|
});
|
|
|
|
describe('getDist', () => {
|
|
afterEach(() => {
|
|
delete process.env['INPUT_DIST'];
|
|
});
|
|
|
|
test('should return null when dist is omitted', async () => {
|
|
expect(getDist()).toBeNull();
|
|
});
|
|
|
|
test('should return a string when dist is provided', () => {
|
|
process.env['INPUT_DIST'] = 'foo-dist';
|
|
expect(getDist()).toEqual('foo-dist');
|
|
});
|
|
});
|
|
|
|
describe('getStartedAt', () => {
|
|
const errorMessage =
|
|
'started_at not in valid format. Unix timestamp or ISO 8601 date expected';
|
|
afterEach(() => {
|
|
delete process.env['INPUT_STARTED_AT'];
|
|
});
|
|
|
|
test('should throw an error when started_at is negative', async () => {
|
|
process.env['INPUT_STARTED_AT'] = '-1';
|
|
expect(() => getStartedAt()).toThrow(errorMessage);
|
|
});
|
|
|
|
test('should throw an error when started_at is invalid', async () => {
|
|
process.env['INPUT_STARTED_AT'] = 'error';
|
|
expect(() => getStartedAt()).toThrow(errorMessage);
|
|
});
|
|
|
|
test('should return null when started_at is omitted', async () => {
|
|
expect(getStartedAt()).toBeNull();
|
|
});
|
|
|
|
test('should return an integer when started_at is an ISO8601 string.', async () => {
|
|
process.env['INPUT_STARTED_AT'] = '2017-07-13T19:40:00';
|
|
expect(getStartedAt()).toEqual(1500000000);
|
|
});
|
|
|
|
test('should return an integer when started_at is an truncated ISO8601 string.', async () => {
|
|
process.env['INPUT_STARTED_AT'] = '2017-07-13';
|
|
expect(getStartedAt()).toEqual(1499904000);
|
|
});
|
|
|
|
test('should return an integer when started_at is an integer.', async () => {
|
|
process.env['INPUT_STARTED_AT'] = '1500000000';
|
|
expect(getStartedAt()).toEqual(1500000000);
|
|
});
|
|
});
|
|
|
|
describe('getVersion', () => {
|
|
const MOCK_VERSION = 'releases propose-version';
|
|
afterEach(() => {
|
|
delete process.env['INPUT_VERSION'];
|
|
delete process.env['INPUT_VERSION_PREFIX'];
|
|
});
|
|
|
|
test('should strip refs from version', async () => {
|
|
process.env['INPUT_VERSION'] = 'refs/tags/v1.0.0';
|
|
expect(await getVersion()).toBe('v1.0.0');
|
|
});
|
|
|
|
test('should get version from inputs', async () => {
|
|
process.env['INPUT_VERSION'] = 'v1.0.0';
|
|
expect(await getVersion()).toBe('v1.0.0');
|
|
});
|
|
|
|
test('should propose-version when version is omitted', async () => {
|
|
expect(await getVersion()).toBe(MOCK_VERSION);
|
|
});
|
|
|
|
test('should include prefix in version', async () => {
|
|
process.env['INPUT_VERSION_PREFIX'] = 'prefix-';
|
|
expect(await getVersion()).toBe(`prefix-${MOCK_VERSION}`);
|
|
});
|
|
|
|
test('should include prefix in version with user provided version', async () => {
|
|
process.env['INPUT_VERSION'] = 'v1.0.0';
|
|
process.env['INPUT_VERSION_PREFIX'] = 'prefix-';
|
|
expect(await getVersion()).toBe(`prefix-v1.0.0`);
|
|
});
|
|
});
|
|
|
|
describe('getSetCommitsOption', () => {
|
|
afterEach(() => {
|
|
delete process.env['INPUT_SET_COMMITS'];
|
|
});
|
|
|
|
it('no option', () => {
|
|
expect(getSetCommitsOption()).toBe('auto');
|
|
});
|
|
it('auto', () => {
|
|
process.env['INPUT_SET_COMMITS'] = 'auto';
|
|
expect(getSetCommitsOption()).toBe('auto');
|
|
});
|
|
it('skip', () => {
|
|
process.env['INPUT_SET_COMMITS'] = 'skip';
|
|
expect(getSetCommitsOption()).toBe('skip');
|
|
});
|
|
it('bad option', () => {
|
|
const errorMessage = 'set_commits must be "auto" or "skip"';
|
|
process.env['INPUT_SET_COMMITS'] = 'bad';
|
|
expect(() => getSetCommitsOption()).toThrow(errorMessage);
|
|
});
|
|
});
|
|
|
|
describe('getProjects', () => {
|
|
afterEach(() => {
|
|
delete process.env['SENTRY_PROJECT'];
|
|
delete process.env['INPUT_PROJECTS'];
|
|
});
|
|
it('read from env variable', () => {
|
|
process.env['SENTRY_PROJECT'] = 'my-proj';
|
|
expect(getProjects()).toEqual(['my-proj']);
|
|
});
|
|
it('read from option', () => {
|
|
process.env['INPUT_PROJECTS'] = 'my-proj1 my-proj2';
|
|
expect(getProjects()).toEqual(['my-proj1', 'my-proj2']);
|
|
});
|
|
it('option overwites env variable', () => {
|
|
process.env['SENTRY_PROJECT'] = 'my-proj';
|
|
process.env['INPUT_PROJECTS'] = 'my-proj1 my-proj2';
|
|
expect(getProjects()).toEqual(['my-proj1', 'my-proj2']);
|
|
});
|
|
it('throws error if no project', () => {
|
|
expect(() => getProjects()).toThrowError(
|
|
'Environment variable SENTRY_PROJECT is missing a project slug and no projects are specified with the "projects" option'
|
|
);
|
|
});
|
|
});
|
|
|
|
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
|
|
test('test runs', () => {
|
|
const output = execSync(
|
|
`node ${path.join(__dirname, '..', 'dist', 'index.js')}`,
|
|
{
|
|
env: {
|
|
...process.env,
|
|
INPUT_ENVIRONMENT: 'production',
|
|
MOCK: 'true',
|
|
SENTRY_AUTH_TOKEN: 'test_token',
|
|
SENTRY_ORG: 'test_org',
|
|
SENTRY_PROJECT: 'test_project',
|
|
},
|
|
}
|
|
);
|
|
|
|
console.log(output.toString());
|
|
});
|