Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions packages/unplugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { createUnplugin } from "unplugin";
import MagicString from "magic-string";
import { getReleaseName } from "./getReleaseName";
import { Options } from "./types";
import { makeSentryFacade } from "./sentry/facade";
import { Options, BuildContext } from "./types";
import {
createNewRelease,
cleanArtifacts,
addDeploy,
finalizeRelease,
setCommits,
uploadSourceMaps,
} from "./sentry/releasePipeline";
import "@sentry/tracing";
import { addSpanToTransaction, captureMinimalError, makeSentryClient } from "./sentry/telemetry";
import { Span, Transaction } from "@sentry/types";
Expand Down Expand Up @@ -132,8 +139,7 @@ const unplugin = createUnplugin<Options>((originalOptions, unpluginMetaContext)
name: "plugin-execution",
});
releaseInjectionSpan = addSpanToTransaction(
sentryHub,
transaction,
{ hub: sentryHub, parentSpan: transaction },
"release-injection",
"release-injection"
);
Expand Down Expand Up @@ -272,11 +278,9 @@ const unplugin = createUnplugin<Options>((originalOptions, unpluginMetaContext)
buildEnd() {
releaseInjectionSpan?.finish();
const releasePipelineSpan =
sentryHub &&
transaction &&
addSpanToTransaction(
sentryHub,
transaction,
{ hub: sentryHub, parentSpan: transaction },
"release-creation",
"release-creation-pipeline"
);
Expand All @@ -294,15 +298,14 @@ const unplugin = createUnplugin<Options>((originalOptions, unpluginMetaContext)
// That's good for them but a hassle for us. Let's try to normalize this into one data type
// (I vote IncludeEntry[]) and continue with that down the line

const sentryFacade = makeSentryFacade(release, options, sentryHub);
const ctx: BuildContext = { hub: sentryHub, parentSpan: releasePipelineSpan };

sentryFacade
.createNewRelease()
.then(() => sentryFacade.cleanArtifacts())
.then(() => sentryFacade.uploadSourceMaps())
.then(() => sentryFacade.setCommits()) // this is a noop for now
.then(() => sentryFacade.finalizeRelease())
.then(() => sentryFacade.addDeploy()) // this is a noop for now
createNewRelease(release, options, ctx)
.then(() => cleanArtifacts(release, options, ctx))
.then(() => uploadSourceMaps(release, options, ctx))
.then(() => setCommits(ctx)) // this is a noop for now
.then(() => finalizeRelease(release, options, ctx))
.then(() => addDeploy(ctx)) // this is a noop for now
.catch((e) => {
//TODO: invoke error handler here
// https://github.com/getsentry/sentry-webpack-plugin/blob/137503f3ac6fe423b16c5c50379859c86e689017/src/index.js#L540-L547
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,17 @@
// - huge download
// - unnecessary functionality

import { Hub } from "@sentry/node";
import { Span } from "@sentry/types";
import { Options } from "../types";
import { Options, BuildContext } from "../types";
import { createRelease, deleteAllReleaseArtifacts, uploadReleaseFile, updateRelease } from "./api";
import { getFiles } from "./sourcemaps";
import { addSpanToTransaction } from "./telemetry";

export type SentryFacade = {
createNewRelease: () => Promise<string>;
cleanArtifacts: () => Promise<string>;
uploadSourceMaps: () => Promise<string>;
setCommits: () => Promise<string>;
finalizeRelease: () => Promise<string>;
addDeploy: () => Promise<string>;
};

/**
* Factory function that provides all necessary Sentry functionality for creating
* a release on Sentry. This includes uploading source maps and finalizing the release
*/
export function makeSentryFacade(release: string, options: Options, sentryHub: Hub): SentryFacade {
const span = sentryHub.getScope()?.getSpan();
return {
createNewRelease: () => createNewRelease(release, options, sentryHub, span),
cleanArtifacts: () => cleanArtifacts(release, options, sentryHub, span),
uploadSourceMaps: () => uploadSourceMaps(release, options, sentryHub, span),
setCommits: () => setCommits(/* release, */ sentryHub, span),
finalizeRelease: () => finalizeRelease(release, options, sentryHub, span),
addDeploy: () => addDeploy(/* release, */ sentryHub, span),
};
}

async function createNewRelease(
export async function createNewRelease(
release: string,
options: Options,
sentryHub: Hub,
parentSpan?: Span
ctx: BuildContext
): Promise<string> {
const span = addSpanToTransaction(sentryHub, parentSpan, "create-new-release");
const span = addSpanToTransaction(ctx, "create-new-release");

// TODO: pull these checks out of here and simplify them
if (options.authToken === undefined) {
Expand All @@ -71,7 +43,7 @@ async function createNewRelease(
org: options.org,
project: options.project,
sentryUrl: options.url,
sentryHub,
sentryHub: ctx.hub,
});

// eslint-disable-next-line no-console
Expand All @@ -81,13 +53,12 @@ async function createNewRelease(
return Promise.resolve("nothing to do here");
}

async function uploadSourceMaps(
export async function uploadSourceMaps(
release: string,
options: Options,
sentryHub: Hub,
parentSpan?: Span
ctx: BuildContext
): Promise<string> {
const span = addSpanToTransaction(sentryHub, parentSpan, "upload-sourceMaps");
const span = addSpanToTransaction(ctx, "upload-sourceMaps");
// This is what Sentry CLI does:
// TODO: 0. Preprocess source maps
// - (Out of scope for now)
Expand Down Expand Up @@ -160,7 +131,7 @@ async function uploadSourceMaps(
sentryUrl: url,
filename: file.name,
fileContent: file.content,
sentryHub,
sentryHub: ctx.hub,
})
)
).then(() => {
Expand All @@ -171,13 +142,12 @@ async function uploadSourceMaps(
});
}

async function finalizeRelease(
export async function finalizeRelease(
release: string,
options: Options,
sentryHub: Hub,
parentSpan?: Span
ctx: BuildContext
): Promise<string> {
const span = addSpanToTransaction(sentryHub, parentSpan, "finalize-release");
const span = addSpanToTransaction(ctx, "finalize-release");

if (options.finalize) {
const { authToken, org, url, project } = options;
Expand All @@ -195,7 +165,7 @@ async function finalizeRelease(
release,
sentryUrl: url,
project,
sentryHub,
sentryHub: ctx.hub,
});
// eslint-disable-next-line no-console
console.log("[Sentry-plugin] Successfully finalized release.");
Expand All @@ -205,13 +175,12 @@ async function finalizeRelease(
return Promise.resolve("nothing to do here");
}

async function cleanArtifacts(
export async function cleanArtifacts(
release: string,
options: Options,
sentryHub: Hub,
parentSpan?: Span
ctx: BuildContext
): Promise<string> {
const span = addSpanToTransaction(sentryHub, parentSpan, "clean-artifacts");
const span = addSpanToTransaction(ctx, "clean-artifacts");

if (options.cleanArtifacts) {
// TODO: pull these checks out of here and simplify them
Expand Down Expand Up @@ -247,7 +216,7 @@ async function cleanArtifacts(
release,
sentryUrl: options.url,
project: options.project,
sentryHub,
sentryHub: ctx.hub,
});

// eslint-disable-next-line no-console
Expand All @@ -260,23 +229,21 @@ async function cleanArtifacts(

// TODO: Stuff we worry about later:

async function setCommits(
export async function setCommits(
/* version: string, */
sentryHub: Hub,
parentSpan?: Span
ctx: BuildContext
): Promise<string> {
const span = addSpanToTransaction(sentryHub, parentSpan, "set-commits");
const span = addSpanToTransaction(ctx, "set-commits");

span?.finish();
return Promise.resolve("Noop");
}

async function addDeploy(
export async function addDeploy(
/* version: string, */
sentryHub: Hub,
parentSpan?: Span
ctx: BuildContext
): Promise<string> {
const span = addSpanToTransaction(sentryHub, parentSpan, "add-deploy");
const span = addSpanToTransaction(ctx, "add-deploy");

span?.finish();
return Promise.resolve("Noop");
Expand Down
9 changes: 5 additions & 4 deletions packages/unplugin/src/sentry/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { Span } from "@sentry/tracing";
import { AxiosError } from "axios";
import { version as unpluginVersion } from "../../package.json";
import { BuildContext } from "../types";

export function makeSentryClient(
dsn: string,
Expand Down Expand Up @@ -48,14 +49,14 @@ export function makeSentryClient(
* Adds a span to the passed parentSpan or to the current transaction that's on the passed hub's scope.
*/
export function addSpanToTransaction(
sentryHub: Hub,
parentSpan?: Span,
ctx: BuildContext,
op?: string,
description?: string
): Span | undefined {
const actualSpan = parentSpan || sentryHub.getScope()?.getTransaction();
const { hub, parentSpan } = ctx;
const actualSpan = parentSpan || hub.getScope()?.getTransaction();
const span = actualSpan?.startChild({ op, description });
sentryHub.configureScope((scope) => scope.setSpan(span));
hub.configureScope((scope) => scope.setSpan(span));

return span;
}
Expand Down
13 changes: 13 additions & 0 deletions packages/unplugin/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
//TODO: JsDoc for all properties

import { Hub } from "@sentry/hub";
import { Span } from "@sentry/tracing";

//TODO: compare types w/ webpack plugin (and sentry-cli?)
export type Options = {
debugLogging?: boolean;
Expand Down Expand Up @@ -84,3 +88,12 @@ type IncludeEntry = {
//TODO: what about the other entries??
};
*/

/**
* Holds data for internal purposes
* (e.g. telemetry and logging)
*/
export type BuildContext = {
hub: Hub;
parentSpan?: Span;
};