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
2 changes: 1 addition & 1 deletion packages/bundler-plugin-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ const unplugin = createUnplugin<Options>((options, unpluginMetaContext) => {
createNewRelease(internalOptions, ctx)
.then(() => cleanArtifacts(internalOptions, ctx))
.then(() => uploadSourceMaps(internalOptions, ctx))
.then(() => setCommits(ctx)) // this is a noop for now
.then(() => setCommits(internalOptions, ctx))
.then(() => finalizeRelease(internalOptions, ctx))
.then(() => addDeploy(ctx)) // this is a noop for now
.then(() => {
Expand Down
29 changes: 22 additions & 7 deletions packages/bundler-plugin-core/src/sentry/releasePipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,31 @@ export async function cleanArtifacts(options: InternalOptions, ctx: BuildContext
span?.finish();
}

// TODO: Stuff we worry about later:

export async function setCommits(
/* version: string, */
ctx: BuildContext
): Promise<string> {
export async function setCommits(options: InternalOptions, ctx: BuildContext): Promise<void> {
const span = addSpanToTransaction(ctx, "function.plugin.set_commits");

if (options.setCommits) {
const { auto, repo, commit, previousCommit, ignoreMissing, ignoreEmpty } = options.setCommits;

if (auto || (repo && commit)) {
await ctx.cli.releases.setCommits(options.release, {
commit,
previousCommit,
repo,
auto,
ignoreMissing,
ignoreEmpty,
});
ctx.logger.info("Successfully set commits.");
} else {
ctx.logger.error(
"Couldn't set commits - neither the `auto` nor the `repo` and `commit` options were specified!",
"Make sure to either set `auto` to `true` or to manually set `repo` and `commit`."
);
}
}

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

export async function addDeploy(
Expand Down
12 changes: 10 additions & 2 deletions packages/bundler-plugin-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,14 @@ type SetCommitsOptions = {
/**
* The full repo name as defined in Sentry.
*
* Required if `auto` option is not `true`.
* Required if `auto` option is not set to `true`.
*/
repo?: string;

/**
* The current (last) commit in the release.
*
* Required if `auto` option is not `true`.
* Required if `auto` option is not set to `true`.
*/
commit?: string;

Expand All @@ -306,6 +306,14 @@ type SetCommitsOptions = {
* Defaults to `false`.
*/
ignoreMissing?: boolean;

/**
* If this flag is set, the setCommits step will not fail and just exit
* silently if no new commits for a given release have been found.
*
* Defaults to `false`.
*/
ignoreEmpty?: boolean;
};

type DeployOptions = {
Expand Down
71 changes: 71 additions & 0 deletions packages/bundler-plugin-core/test/releasePipeline.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { InternalOptions } from "../src/options-mapping";
import { setCommits } from "../src/sentry/releasePipeline";
import { BuildContext } from "../src/types";

const mockedAddSpanToTxn = jest.fn();

jest.mock("../src/sentry/telemetry", () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const original = jest.requireActual("../src/sentry/telemetry");

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return {
...original,
addSpanToTransaction: () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return mockedAddSpanToTxn();
},
};
});

describe("Release Pipeline", () => {
const mockedLogger = {
debug: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
};

const mockedCLI = {
releases: {
setCommits: jest.fn(),
},
};

const mockedChildSpan = { finish: jest.fn() };
mockedAddSpanToTxn.mockImplementation(() => mockedChildSpan);

const ctx = { cli: mockedCLI, logger: mockedLogger };

describe("setCommits", () => {
it("doesn't do anything if setCommits option is not specified", async () => {
await setCommits({} as InternalOptions, ctx as unknown as BuildContext);

expect(mockedCLI.releases.setCommits).not.toHaveBeenCalled();
expect(mockedAddSpanToTxn).toHaveBeenCalled();
expect(mockedChildSpan.finish).toHaveBeenCalled();
});

it("logs an error if neither `auto` nor `repo` && `commit` options are specified", async () => {
await setCommits({ setCommits: {} } as InternalOptions, ctx as unknown as BuildContext);
expect(mockedCLI.releases.setCommits).not.toHaveBeenCalled();
expect(mockedLogger.error).toHaveBeenLastCalledWith(
expect.stringMatching(/Couldn't set commits.*auto.*repo.*commit/),
expect.stringMatching(/.*auto.*repo.*commit/)
);
expect(mockedAddSpanToTxn).toHaveBeenCalled();
expect(mockedChildSpan.finish).toHaveBeenCalled();
});

it("makes a call to Sentry CLI if the correct options are specified", async () => {
await setCommits(
{ setCommits: { auto: true }, release: "1.0.0" } as InternalOptions,
ctx as unknown as BuildContext
);

expect(mockedCLI.releases.setCommits).toHaveBeenCalledWith("1.0.0", { auto: true });
expect(mockedAddSpanToTxn).toHaveBeenCalled();
expect(mockedChildSpan.finish).toHaveBeenCalled();
});
});
});
4 changes: 4 additions & 0 deletions packages/playground/vite.config.smallNodeApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export default defineConfig({
// ignore: ["out/*", "!out/vite-smallNodeApp/index.js.map"],
ignore: ["!out/vite-smallNodeApp/index.js.map"],
ignoreFile: ".sentryignore",
setCommits: {
auto: true,
ignoreMissing: true,
},
}),
],
});