Skip to content

Commit 4e7802f

Browse files
authored
feat(core): Add setCommits (#96)
Add the `setCommits` option implementation, analogously to what we have in the [webpack plugin](https://github.com/getsentry/sentry-webpack-plugin/blob/137503f3ac6fe423b16c5c50379859c86e689017/src/index.js#L495-L516). Add a few tests to check that this step in our release pipeline is working as expected. I'll make similar tests to the other steps in future PRs.
1 parent 8e47960 commit 4e7802f

File tree

5 files changed

+108
-10
lines changed

5 files changed

+108
-10
lines changed

packages/bundler-plugin-core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ const unplugin = createUnplugin<Options>((options, unpluginMetaContext) => {
287287
createNewRelease(internalOptions, ctx)
288288
.then(() => cleanArtifacts(internalOptions, ctx))
289289
.then(() => uploadSourceMaps(internalOptions, ctx))
290-
.then(() => setCommits(ctx)) // this is a noop for now
290+
.then(() => setCommits(internalOptions, ctx))
291291
.then(() => finalizeRelease(internalOptions, ctx))
292292
.then(() => addDeploy(ctx)) // this is a noop for now
293293
.then(() => {

packages/bundler-plugin-core/src/sentry/releasePipeline.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,31 @@ export async function cleanArtifacts(options: InternalOptions, ctx: BuildContext
100100
span?.finish();
101101
}
102102

103-
// TODO: Stuff we worry about later:
104-
105-
export async function setCommits(
106-
/* version: string, */
107-
ctx: BuildContext
108-
): Promise<string> {
103+
export async function setCommits(options: InternalOptions, ctx: BuildContext): Promise<void> {
109104
const span = addSpanToTransaction(ctx, "function.plugin.set_commits");
110105

106+
if (options.setCommits) {
107+
const { auto, repo, commit, previousCommit, ignoreMissing, ignoreEmpty } = options.setCommits;
108+
109+
if (auto || (repo && commit)) {
110+
await ctx.cli.releases.setCommits(options.release, {
111+
commit,
112+
previousCommit,
113+
repo,
114+
auto,
115+
ignoreMissing,
116+
ignoreEmpty,
117+
});
118+
ctx.logger.info("Successfully set commits.");
119+
} else {
120+
ctx.logger.error(
121+
"Couldn't set commits - neither the `auto` nor the `repo` and `commit` options were specified!",
122+
"Make sure to either set `auto` to `true` or to manually set `repo` and `commit`."
123+
);
124+
}
125+
}
126+
111127
span?.finish();
112-
return Promise.resolve("Noop");
113128
}
114129

115130
export async function addDeploy(

packages/bundler-plugin-core/src/types.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,14 @@ type SetCommitsOptions = {
277277
/**
278278
* The full repo name as defined in Sentry.
279279
*
280-
* Required if `auto` option is not `true`.
280+
* Required if `auto` option is not set to `true`.
281281
*/
282282
repo?: string;
283283

284284
/**
285285
* The current (last) commit in the release.
286286
*
287-
* Required if `auto` option is not `true`.
287+
* Required if `auto` option is not set to `true`.
288288
*/
289289
commit?: string;
290290

@@ -306,6 +306,14 @@ type SetCommitsOptions = {
306306
* Defaults to `false`.
307307
*/
308308
ignoreMissing?: boolean;
309+
310+
/**
311+
* If this flag is set, the setCommits step will not fail and just exit
312+
* silently if no new commits for a given release have been found.
313+
*
314+
* Defaults to `false`.
315+
*/
316+
ignoreEmpty?: boolean;
309317
};
310318

311319
type DeployOptions = {
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { InternalOptions } from "../src/options-mapping";
2+
import { setCommits } from "../src/sentry/releasePipeline";
3+
import { BuildContext } from "../src/types";
4+
5+
const mockedAddSpanToTxn = jest.fn();
6+
7+
jest.mock("../src/sentry/telemetry", () => {
8+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
9+
const original = jest.requireActual("../src/sentry/telemetry");
10+
11+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
12+
return {
13+
...original,
14+
addSpanToTransaction: () => {
15+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
16+
return mockedAddSpanToTxn();
17+
},
18+
};
19+
});
20+
21+
describe("Release Pipeline", () => {
22+
const mockedLogger = {
23+
debug: jest.fn(),
24+
info: jest.fn(),
25+
warn: jest.fn(),
26+
error: jest.fn(),
27+
};
28+
29+
const mockedCLI = {
30+
releases: {
31+
setCommits: jest.fn(),
32+
},
33+
};
34+
35+
const mockedChildSpan = { finish: jest.fn() };
36+
mockedAddSpanToTxn.mockImplementation(() => mockedChildSpan);
37+
38+
const ctx = { cli: mockedCLI, logger: mockedLogger };
39+
40+
describe("setCommits", () => {
41+
it("doesn't do anything if setCommits option is not specified", async () => {
42+
await setCommits({} as InternalOptions, ctx as unknown as BuildContext);
43+
44+
expect(mockedCLI.releases.setCommits).not.toHaveBeenCalled();
45+
expect(mockedAddSpanToTxn).toHaveBeenCalled();
46+
expect(mockedChildSpan.finish).toHaveBeenCalled();
47+
});
48+
49+
it("logs an error if neither `auto` nor `repo` && `commit` options are specified", async () => {
50+
await setCommits({ setCommits: {} } as InternalOptions, ctx as unknown as BuildContext);
51+
expect(mockedCLI.releases.setCommits).not.toHaveBeenCalled();
52+
expect(mockedLogger.error).toHaveBeenLastCalledWith(
53+
expect.stringMatching(/Couldn't set commits.*auto.*repo.*commit/),
54+
expect.stringMatching(/.*auto.*repo.*commit/)
55+
);
56+
expect(mockedAddSpanToTxn).toHaveBeenCalled();
57+
expect(mockedChildSpan.finish).toHaveBeenCalled();
58+
});
59+
60+
it("makes a call to Sentry CLI if the correct options are specified", async () => {
61+
await setCommits(
62+
{ setCommits: { auto: true }, release: "1.0.0" } as InternalOptions,
63+
ctx as unknown as BuildContext
64+
);
65+
66+
expect(mockedCLI.releases.setCommits).toHaveBeenCalledWith("1.0.0", { auto: true });
67+
expect(mockedAddSpanToTxn).toHaveBeenCalled();
68+
expect(mockedChildSpan.finish).toHaveBeenCalled();
69+
});
70+
});
71+
});

packages/playground/vite.config.smallNodeApp.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export default defineConfig({
2727
// ignore: ["out/*", "!out/vite-smallNodeApp/index.js.map"],
2828
ignore: ["!out/vite-smallNodeApp/index.js.map"],
2929
ignoreFile: ".sentryignore",
30+
setCommits: {
31+
auto: true,
32+
ignoreMissing: true,
33+
},
3034
}),
3135
],
3236
});

0 commit comments

Comments
 (0)