Skip to content

Commit 484a719

Browse files
chore: add release discovery (#21)
* chore: add release discovery * chore: update release name in gh action * Update packages/unplugin/test/getReleaseName.test.ts Co-authored-by: Lukas Stracke <[email protected]> Co-authored-by: Lukas Stracke <[email protected]>
1 parent b2afba1 commit 484a719

File tree

4 files changed

+138
-5
lines changed

4 files changed

+138
-5
lines changed

Diff for: .github/workflows/checks.yml

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77

88
env:
99
DEFAULT_NODE_VERSION: "16.15.1"
10+
SENTRY_RELEASE: "default_release_name"
1011

1112
jobs:
1213
build:

Diff for: packages/unplugin/src/getReleaseName.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import * as child_process from "child_process";
2+
import * as fs from "fs";
3+
import * as path from "path";
4+
5+
function isGit(dir: string) {
6+
return fs.existsSync(path.join(dir, ".git"));
7+
}
8+
9+
function getBranchHead() {
10+
return child_process.execSync("git rev-parse HEAD").toString().trim();
11+
}
12+
13+
export function getReleaseName(releaseName?: string): string {
14+
if (releaseName) {
15+
return releaseName;
16+
}
17+
18+
const ENV_VARS = [
19+
"SENTRY_RELEASE",
20+
"SOURCE_VERSION", // Heroku #1 https://devcenter.heroku.com/changelog-items/630
21+
"HEROKU_SLUG_COMMIT", // Heroku #2: https://docs.sentry.io/product/integrations/deployment/heroku/#configure-releases
22+
"CODEBUILD_RESOLVED_SOURCE_VERSION", // AWS CodeBuild: https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
23+
"CIRCLE_SHA1", // CircleCI: https://circleci.com/docs/2.0/env-vars/
24+
"VERCEL_GIT_COMMIT_SHA", // Vercel docs: https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables
25+
];
26+
27+
const releaseFromEnvironmentVar = ENV_VARS.find((key) => Object.keys(process.env).includes(key));
28+
29+
if (releaseFromEnvironmentVar) {
30+
return process.env[releaseFromEnvironmentVar] as string;
31+
}
32+
33+
if (isGit(process.cwd())) {
34+
return getBranchHead();
35+
} else {
36+
throw new Error("Could not return a release name");
37+
}
38+
}

Diff for: packages/unplugin/src/index.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createUnplugin } from "unplugin";
22
import MagicString from "magic-string";
3+
import { getReleaseName } from "./getReleaseName";
34
import * as path from "path";
45

56
function generateGlobalInjectorCode({ release }: { release: string }) {
@@ -16,11 +17,6 @@ function generateGlobalInjectorCode({ release }: { release: string }) {
1617
_global.SENTRY_RELEASE={id:"${release}"};`;
1718
}
1819

19-
// TODO: Replace this function with actual logic
20-
function getReleaseName() {
21-
return "default";
22-
}
23-
2420
export interface Options {
2521
debugLogging?: boolean;
2622
}

Diff for: packages/unplugin/test/getReleaseName.test.ts

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { getReleaseName } from "../src/getReleaseName";
2+
import * as fs from "fs";
3+
import * as child_process from "child_process";
4+
jest.mock("fs");
5+
jest.mock("child_process");
6+
7+
const mockedFs = fs;
8+
const mockedChildProcess = child_process;
9+
10+
describe("environmental getReleaseName", () => {
11+
const OLD_ENV = process.env;
12+
13+
beforeEach(() => {
14+
jest.resetModules();
15+
process.env = { ...OLD_ENV };
16+
});
17+
18+
afterEach(() => {
19+
(mockedChildProcess.execSync as jest.Mock).mockRestore();
20+
});
21+
22+
afterAll(() => {
23+
process.env = OLD_ENV;
24+
});
25+
26+
it("adheres to HEAD when git is present", () => {
27+
(mockedFs.existsSync as jest.Mock).mockReturnValueOnce(true);
28+
const sha = "c3f235fc86f1c4007e3a218ec82d666586e73cbf";
29+
(mockedChildProcess.execSync as jest.Mock).mockReturnValue(sha);
30+
31+
expect(getReleaseName()).toBe(sha);
32+
});
33+
34+
it("throws an error if no release information could be found", () => {
35+
(mockedFs.existsSync as jest.Mock).mockReturnValueOnce(false);
36+
37+
expect(getReleaseName).toThrow("Could not return a release name");
38+
});
39+
40+
it("adheres to user defined release name", () => {
41+
const releaseName = "USER_DEFINED_this-is-my-custom-release";
42+
43+
expect(getReleaseName(releaseName)).toBe(releaseName);
44+
});
45+
46+
it("adheres to process.env.SENTRY_RELEASE", () => {
47+
const releaseName = "SENTRY_RELEASE_string";
48+
process.env["SENTRY_RELEASE"] = releaseName;
49+
50+
expect(getReleaseName()).toBe(releaseName);
51+
});
52+
53+
it("adheres to Heroku: process.env.SOURCE_VERSION", () => {
54+
const releaseName = "SOURCE_VERSION_string";
55+
process.env["SOURCE_VERSION"] = releaseName;
56+
57+
expect(getReleaseName()).toBe(releaseName);
58+
});
59+
60+
it("adheres to Heroku: process.env.HEROKU_SLUG_COMMIT", () => {
61+
const releaseName = "HEROKU_SLUG_COMMIT_string";
62+
process.env["HEROKU_SLUG_COMMIT"] = releaseName;
63+
64+
expect(getReleaseName()).toBe(releaseName);
65+
});
66+
67+
it("adheres to AWS: process.env.CODEBUILD_RESOLVED_SOURCE_VERSION", () => {
68+
const releaseName = "CODEBUILD_RESOLVED_SOURCE_VERSION_string";
69+
process.env["CODEBUILD_RESOLVED_SOURCE_VERSION"] = releaseName;
70+
71+
expect(getReleaseName()).toBe(releaseName);
72+
});
73+
74+
it("adheres to Vercel: process.env.VERCEL_GIT_COMMIT_SHA", () => {
75+
const releaseName = "VERCEL_GIT_COMMIT_SHA_string";
76+
process.env["VERCEL_GIT_COMMIT_SHA"] = releaseName;
77+
78+
expect(getReleaseName()).toBe(releaseName);
79+
});
80+
81+
it("allows SENTRY_RELEASE to take precedence over other env vars", () => {
82+
const vercelReleaseName = "VERCEL_GIT_COMMIT_SHA_string";
83+
const sentryReleaseName = "SENTRY_RELEASE_string";
84+
process.env["VERCEL_GIT_COMMIT_SHA"] = vercelReleaseName;
85+
process.env["SENTRY_RELEASE"] = sentryReleaseName;
86+
87+
expect(getReleaseName()).toBe(sentryReleaseName);
88+
});
89+
90+
it("allows custom release name to take precedence over other env vars", () => {
91+
const vercelReleaseName = "VERCEL_GIT_COMMIT_SHA_string";
92+
const sentryReleaseName = "SENTRY_RELEASE_string";
93+
process.env["VERCEL_GIT_COMMIT_SHA"] = vercelReleaseName;
94+
process.env["SENTRY_RELEASE"] = sentryReleaseName;
95+
96+
expect(getReleaseName("cutom_release_name")).toBe("cutom_release_name");
97+
});
98+
});

0 commit comments

Comments
 (0)