fix: Only pass urlPrefix to sentry-cli if it's not empty (#275)
* fix: Only passes `urlPrefix` to sentry-cli if it's not empty Also lets sentry-cli handle uploading source maps for multiple projects. * Update prettier settings and reformat
This commit is contained in:
+2
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"printWidth": 120,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"bracketSpacing": false,
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid",
|
||||
"overrides": [
|
||||
{
|
||||
|
||||
+18
-26
@@ -1,4 +1,4 @@
|
||||
import {execSync} from 'child_process';
|
||||
import { execSync } from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as process from 'process';
|
||||
import {
|
||||
@@ -29,9 +29,7 @@ describe('options', () => {
|
||||
|
||||
test('should throw an error when option type is not a boolean', () => {
|
||||
process.env['INPUT_FINALIZE'] = 'error';
|
||||
expect(() => getBooleanOption(option, defaultValue)).toThrow(
|
||||
errorMessage
|
||||
);
|
||||
expect(() => getBooleanOption(option, defaultValue)).toThrow(errorMessage);
|
||||
});
|
||||
|
||||
test('should return defaultValue if option is omitted', () => {
|
||||
@@ -84,8 +82,7 @@ describe('options', () => {
|
||||
});
|
||||
|
||||
describe('getStartedAt', () => {
|
||||
const errorMessage =
|
||||
'started_at not in valid format. Unix timestamp or ISO 8601 date expected';
|
||||
const errorMessage = 'started_at not in valid format. Unix timestamp or ISO 8601 date expected';
|
||||
afterEach(() => {
|
||||
delete process.env['INPUT_STARTED_AT'];
|
||||
});
|
||||
@@ -121,10 +118,10 @@ describe('options', () => {
|
||||
});
|
||||
|
||||
describe.each([
|
||||
{release: 'INPUT_RELEASE', prefix: 'INPUT_RELEASE_PREFIX'},
|
||||
{release: 'INPUT_VERSION', prefix: 'INPUT_VERSION_PREFIX'},
|
||||
{release: 'INPUT_RELEASE', prefix: 'INPUT_VERSION_PREFIX'},
|
||||
{release: 'INPUT_VERSION', prefix: 'INPUT_RELEASE_PREFIX'},
|
||||
{ release: 'INPUT_RELEASE', prefix: 'INPUT_RELEASE_PREFIX' },
|
||||
{ release: 'INPUT_VERSION', prefix: 'INPUT_VERSION_PREFIX' },
|
||||
{ release: 'INPUT_RELEASE', prefix: 'INPUT_VERSION_PREFIX' },
|
||||
{ release: 'INPUT_VERSION', prefix: 'INPUT_RELEASE_PREFIX' },
|
||||
])(`getRelease`, params => {
|
||||
const MOCK_VERSION = 'releases propose-version';
|
||||
|
||||
@@ -250,9 +247,7 @@ describe('options', () => {
|
||||
it('gets the working directory url and prefixes it with the `GITHUB_WORKSPACE`', () => {
|
||||
process.env['GITHUB_WORKSPACE'] = '/repo/root';
|
||||
process.env['INPUT_WORKING_DIRECTORY'] = '/some/working/directory';
|
||||
expect(getWorkingDirectory()).toEqual(
|
||||
'/repo/root/some/working/directory'
|
||||
);
|
||||
expect(getWorkingDirectory()).toEqual('/repo/root/some/working/directory');
|
||||
});
|
||||
|
||||
it('should default to `GITHUB_WORKSPACE` even if no direcotry is passed', () => {
|
||||
@@ -264,19 +259,16 @@ describe('options', () => {
|
||||
|
||||
// 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',
|
||||
},
|
||||
}
|
||||
);
|
||||
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());
|
||||
});
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ runs:
|
||||
INPUT_WORKING_DIRECTORY: ${{ inputs.working_directory }}
|
||||
INPUT_DISABLE_TELEMETRY: ${{ inputs.disable_telemetry }}
|
||||
INPUT_DISABLE_SAFE_DIRECTORY: ${{ inputs.disable_safe_directory }}
|
||||
uses: docker://ghcr.io/getsentry/action-release-image:master
|
||||
uses: docker://ghcr.io/getsentry/action-release-image:ab-avoid-sending-empty-urlPrefix
|
||||
|
||||
# For actions running on macos or windows runners, we use a composite
|
||||
# action approach which allows us to install the arch specific sentry-cli
|
||||
|
||||
Vendored
+14
-16
@@ -122771,17 +122771,19 @@ const telemetry_1 = __nccwpck_require__(12417);
|
||||
}
|
||||
yield (0, telemetry_1.traceStep)('upload-sourcemaps', () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
core.debug(`Adding sourcemaps`);
|
||||
const sourceMapsOptions = {
|
||||
include: sourcemaps,
|
||||
dist,
|
||||
stripCommonPrefix,
|
||||
};
|
||||
// only set the urlPrefix if it's not empty
|
||||
if (urlPrefix) {
|
||||
sourceMapsOptions.urlPrefix = urlPrefix;
|
||||
}
|
||||
// sentry-cli supports multiple projects, but only uploads sourcemaps for the
|
||||
// first project so we need to upload sourcemaps for each project individually
|
||||
yield Promise.all(projects.map((project) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
// upload source maps can only do one project at a time
|
||||
const localProjects = [project];
|
||||
const sourceMapOptions = {
|
||||
include: sourcemaps,
|
||||
projects: localProjects,
|
||||
dist,
|
||||
urlPrefix,
|
||||
stripCommonPrefix,
|
||||
};
|
||||
return (0, cli_1.getCLI)().uploadSourceMaps(release, sourceMapOptions);
|
||||
return (0, cli_1.getCLI)().uploadSourceMaps(release, Object.assign(Object.assign({}, sourceMapsOptions), { projects: [project] }));
|
||||
})));
|
||||
Sentry.setTag('sourcemaps-uploaded', true);
|
||||
}));
|
||||
@@ -123002,11 +123004,7 @@ exports.getSetCommitsOption = getSetCommitsOption;
|
||||
const checkEnvironmentVariables = () => {
|
||||
if (process.env['MOCK']) {
|
||||
// Set environment variables for mock runs if they aren't already
|
||||
for (const variable of [
|
||||
'SENTRY_AUTH_TOKEN',
|
||||
'SENTRY_ORG',
|
||||
'SENTRY_PROJECT',
|
||||
]) {
|
||||
for (const variable of ['SENTRY_AUTH_TOKEN', 'SENTRY_ORG', 'SENTRY_PROJECT']) {
|
||||
if (!(variable in process.env)) {
|
||||
process.env[variable] = variable;
|
||||
}
|
||||
@@ -123184,7 +123182,7 @@ exports.isSelfHosted = isSelfHosted;
|
||||
* Determine if telemetry should be enabled.
|
||||
*/
|
||||
function isTelemetryEnabled() {
|
||||
return (!ciOptions.getBooleanOption('disable_telemetry', false) && !isSelfHosted());
|
||||
return !ciOptions.getBooleanOption('disable_telemetry', false) && !isSelfHosted();
|
||||
}
|
||||
exports.isTelemetryEnabled = isTelemetryEnabled;
|
||||
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
import {getTraceData} from '@sentry/node';
|
||||
import SentryCli, {SentryCliReleases} from '@sentry/cli';
|
||||
import { getTraceData } from '@sentry/node';
|
||||
import SentryCli, { SentryCliReleases } from '@sentry/cli';
|
||||
// @ts-ignore
|
||||
import {version} from '../package.json';
|
||||
import { version } from '../package.json';
|
||||
|
||||
/**
|
||||
* CLI Singleton
|
||||
|
||||
+26
-24
@@ -1,9 +1,10 @@
|
||||
import * as Sentry from '@sentry/node';
|
||||
import * as core from '@actions/core';
|
||||
import {getCLI} from './cli';
|
||||
import { SentryCliUploadSourceMapsOptions } from '@sentry/cli';
|
||||
import { getCLI } from './cli';
|
||||
import * as options from './options';
|
||||
import * as process from 'process';
|
||||
import {isTelemetryEnabled, traceStep, withTelemetry} from './telemetry';
|
||||
import { isTelemetryEnabled, traceStep, withTelemetry } from './telemetry';
|
||||
|
||||
withTelemetry(
|
||||
{
|
||||
@@ -32,10 +33,7 @@ withTelemetry(
|
||||
const setCommitsOption = options.getSetCommitsOption();
|
||||
const projects = options.getProjects();
|
||||
const urlPrefix = options.getUrlPrefixOption();
|
||||
const stripCommonPrefix = options.getBooleanOption(
|
||||
'strip_common_prefix',
|
||||
false
|
||||
);
|
||||
const stripCommonPrefix = options.getBooleanOption('strip_common_prefix', false);
|
||||
const release = await options.getRelease();
|
||||
|
||||
if (projects.length === 1) {
|
||||
@@ -45,7 +43,7 @@ withTelemetry(
|
||||
}
|
||||
|
||||
core.debug(`Release version is ${release}`);
|
||||
await getCLI().new(release, {projects});
|
||||
await getCLI().new(release, { projects });
|
||||
|
||||
Sentry.setTag('set-commits', setCommitsOption);
|
||||
|
||||
@@ -68,28 +66,32 @@ withTelemetry(
|
||||
await traceStep('inject-debug-ids', async () => {
|
||||
core.debug(`Injecting Debug IDs`);
|
||||
// Unfortunately, @sentry/cli does not yet have an alias for inject
|
||||
await getCLI().execute(
|
||||
['sourcemaps', 'inject', ...sourcemaps],
|
||||
true
|
||||
);
|
||||
await getCLI().execute(['sourcemaps', 'inject', ...sourcemaps], true);
|
||||
});
|
||||
}
|
||||
|
||||
await traceStep('upload-sourcemaps', async () => {
|
||||
core.debug(`Adding sourcemaps`);
|
||||
const sourceMapsOptions: SentryCliUploadSourceMapsOptions = {
|
||||
include: sourcemaps,
|
||||
dist,
|
||||
stripCommonPrefix,
|
||||
};
|
||||
|
||||
// only set the urlPrefix if it's not empty
|
||||
if (urlPrefix) {
|
||||
sourceMapsOptions.urlPrefix = urlPrefix;
|
||||
}
|
||||
|
||||
// sentry-cli supports multiple projects, but only uploads sourcemaps for the
|
||||
// first project so we need to upload sourcemaps for each project individually
|
||||
await Promise.all(
|
||||
projects.map(async project => {
|
||||
// upload source maps can only do one project at a time
|
||||
const localProjects: [string] = [project];
|
||||
const sourceMapOptions = {
|
||||
include: sourcemaps,
|
||||
projects: localProjects,
|
||||
dist,
|
||||
urlPrefix,
|
||||
stripCommonPrefix,
|
||||
};
|
||||
return getCLI().uploadSourceMaps(release, sourceMapOptions);
|
||||
})
|
||||
projects.map(async (project: string) =>
|
||||
getCLI().uploadSourceMaps(release, {
|
||||
...sourceMapsOptions,
|
||||
projects: [project],
|
||||
} as SentryCliUploadSourceMapsOptions & { projects: string[] })
|
||||
)
|
||||
);
|
||||
|
||||
Sentry.setTag('sourcemaps-uploaded', true);
|
||||
@@ -101,7 +103,7 @@ withTelemetry(
|
||||
core.debug(`Adding deploy to release`);
|
||||
await getCLI().newDeploy(release, {
|
||||
env: environment,
|
||||
...(deployStartedAtOption && {started: deployStartedAtOption}),
|
||||
...(deployStartedAtOption && { started: deployStartedAtOption }),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
+7
-23
@@ -1,6 +1,6 @@
|
||||
import * as core from '@actions/core';
|
||||
import path from 'path';
|
||||
import {getCLI} from './cli';
|
||||
import { getCLI } from './cli';
|
||||
|
||||
/**
|
||||
* Get the release version string from parameter or propose one.
|
||||
@@ -69,9 +69,7 @@ export const getStartedAt = (): number | null => {
|
||||
}
|
||||
|
||||
if (!outputTimestamp || outputTimestamp < 0) {
|
||||
throw new Error(
|
||||
'started_at not in valid format. Unix timestamp or ISO 8601 date expected'
|
||||
);
|
||||
throw new Error('started_at not in valid format. Unix timestamp or ISO 8601 date expected');
|
||||
}
|
||||
|
||||
return outputTimestamp;
|
||||
@@ -109,10 +107,7 @@ export const getDist = (): string | undefined => {
|
||||
* @param defaultValue boolean
|
||||
* @returns boolean
|
||||
*/
|
||||
export const getBooleanOption = (
|
||||
input: string,
|
||||
defaultValue: boolean
|
||||
): boolean => {
|
||||
export const getBooleanOption = (input: string, defaultValue: boolean): boolean => {
|
||||
const option = core.getInput(input);
|
||||
if (!option) {
|
||||
return defaultValue;
|
||||
@@ -156,11 +151,7 @@ export const getSetCommitsOption = (): 'auto' | 'skip' => {
|
||||
export const checkEnvironmentVariables = (): void => {
|
||||
if (process.env['MOCK']) {
|
||||
// Set environment variables for mock runs if they aren't already
|
||||
for (const variable of [
|
||||
'SENTRY_AUTH_TOKEN',
|
||||
'SENTRY_ORG',
|
||||
'SENTRY_PROJECT',
|
||||
]) {
|
||||
for (const variable of ['SENTRY_AUTH_TOKEN', 'SENTRY_ORG', 'SENTRY_PROJECT']) {
|
||||
if (!(variable in process.env)) {
|
||||
process.env[variable] = variable;
|
||||
}
|
||||
@@ -168,14 +159,10 @@ export const checkEnvironmentVariables = (): void => {
|
||||
}
|
||||
|
||||
if (!process.env['SENTRY_ORG']) {
|
||||
throw Error(
|
||||
'Environment variable SENTRY_ORG is missing an organization slug'
|
||||
);
|
||||
throw Error('Environment variable SENTRY_ORG is missing an organization slug');
|
||||
}
|
||||
if (!process.env['SENTRY_AUTH_TOKEN']) {
|
||||
throw Error(
|
||||
'Environment variable SENTRY_AUTH_TOKEN is missing an auth token'
|
||||
);
|
||||
throw Error('Environment variable SENTRY_AUTH_TOKEN is missing an auth token');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -205,8 +192,5 @@ export const getWorkingDirectory = (): string => {
|
||||
// The action runs inside `github.action_path` and as such
|
||||
// doesn't automatically have access to the user's git
|
||||
// We prefix all paths with `GITHUB_WORKSPACE` which is at the top of the repo.
|
||||
return path.join(
|
||||
process.env.GITHUB_WORKSPACE || '',
|
||||
core.getInput('working_directory')
|
||||
);
|
||||
return path.join(process.env.GITHUB_WORKSPACE || '', core.getInput('working_directory'));
|
||||
};
|
||||
|
||||
+5
-12
@@ -8,10 +8,7 @@ const SENTRY_SAAS_HOSTNAME = 'sentry.io';
|
||||
* Initializes Sentry and wraps the given callback
|
||||
* in a span.
|
||||
*/
|
||||
export async function withTelemetry<F>(
|
||||
options: {enabled: boolean},
|
||||
callback: () => F | Promise<F>
|
||||
): Promise<F> {
|
||||
export async function withTelemetry<F>(options: { enabled: boolean }, callback: () => F | Promise<F>): Promise<F> {
|
||||
Sentry.initWithoutDefaultIntegrations({
|
||||
dsn: 'https://[email protected]/4508608809533441',
|
||||
enabled: options.enabled,
|
||||
@@ -27,7 +24,7 @@ export async function withTelemetry<F>(
|
||||
|
||||
const org = process.env['SENTRY_ORG'];
|
||||
|
||||
Sentry.setUser({id: org});
|
||||
Sentry.setUser({ id: org });
|
||||
Sentry.setTag('organization', org);
|
||||
Sentry.setTag('node', process.version);
|
||||
Sentry.setTag('platform', process.platform);
|
||||
@@ -68,7 +65,7 @@ export function updateProgress(step: string): void {
|
||||
*/
|
||||
export function traceStep<T>(step: string, callback: () => T): T {
|
||||
updateProgress(step);
|
||||
return Sentry.startSpan({name: step, op: 'action.step'}, () => callback());
|
||||
return Sentry.startSpan({ name: step, op: 'action.step' }, () => callback());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,9 +84,7 @@ export async function safeFlush(): Promise<void> {
|
||||
* Check whether the user is self-hosting Sentry.
|
||||
*/
|
||||
export function isSelfHosted(): boolean {
|
||||
const url = new URL(
|
||||
process.env['SENTRY_URL'] || `https://${SENTRY_SAAS_HOSTNAME}`
|
||||
);
|
||||
const url = new URL(process.env['SENTRY_URL'] || `https://${SENTRY_SAAS_HOSTNAME}`);
|
||||
|
||||
return url.hostname !== SENTRY_SAAS_HOSTNAME;
|
||||
}
|
||||
@@ -98,7 +93,5 @@ export function isSelfHosted(): boolean {
|
||||
* Determine if telemetry should be enabled.
|
||||
*/
|
||||
export function isTelemetryEnabled(): boolean {
|
||||
return (
|
||||
!ciOptions.getBooleanOption('disable_telemetry', false) && !isSelfHosted()
|
||||
);
|
||||
return !ciOptions.getBooleanOption('disable_telemetry', false) && !isSelfHosted();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user