From fd4fcb79c568a66790f84ee68c386c259b0db865 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Thu, 5 Dec 2024 09:33:28 -0400 Subject: [PATCH 01/23] refactor how we define and access the plugin name and version --- .../__tests__/astroBundleAnalysisPlugin.test.ts | 7 +++++++ .../astroBundleAnalysisPlugin.ts | 13 +++++-------- packages/astro-plugin/src/index.ts | 17 ++++++++++++++--- packages/bundler-plugin-core/src/types.ts | 2 ++ packages/nextjs-webpack-plugin/src/index.ts | 7 +++++++ .../nextJSWebpackBundleAnalysisPlugin.test.ts | 7 +++++++ .../nextJSWebpackBundleAnalysisPlugin.ts | 17 ++++++----------- packages/nuxt-plugin/src/index.ts | 16 +++++++++++++--- .../__tests__/nuxtBundleAnalysisPlugin.test.ts | 7 +++++++ .../nuxtBundleAnalysisPlugin.ts | 13 +++++-------- packages/remix-vite-plugin/src/index.ts | 17 +++++++++++++++-- .../__tests__/remixBundleAnalysisPlugin.test.ts | 7 +++++++ .../remixBundleAnalysisPlugin.ts | 13 +++++-------- packages/rollup-plugin/src/index.ts | 7 +++++++ .../rollupBundleAnalysisPlugin.test.ts | 7 +++++++ .../rollupBundleAnalysisPlugin.ts | 13 +++++-------- packages/solidstart-plugin/src/index.ts | 17 +++++++++++++++-- .../solidstartBundleAnalysisPlugin.test.ts | 7 +++++++ .../solidstartBundleAnalysisPlugin.ts | 13 +++++-------- packages/sveltekit-plugin/src/index.ts | 17 +++++++++++++++-- .../sveltekitBundleAnalysisPlugin.test.ts | 8 ++++++++ .../sveltekitBundleAnalysisPlugin.ts | 13 +++++-------- packages/vite-plugin/src/index.ts | 15 ++++++++++++++- .../__tests__/viteBundleAnalysisPlugin.test.ts | 7 +++++++ .../viteBundleAnalysisPlugin.ts | 13 +++++-------- packages/webpack-plugin/src/index.ts | 7 +++++++ .../webpackBundleAnalysisPlugin.test.ts | 7 +++++++ .../webpackBundleAnalysisPlugin.ts | 17 +++++++---------- 28 files changed, 221 insertions(+), 90 deletions(-) diff --git a/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts b/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts index df7b397a..1959ebe7 100644 --- a/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts +++ b/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { astroBundleAnalysisPlugin } from "../astroBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("astroBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -16,6 +21,8 @@ describe("astroBundleAnalysisPlugin", () => { retryCount: 1, uploadToken: "test-token", }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/astro-plugin/src/astro-bundle-analysis/astroBundleAnalysisPlugin.ts b/packages/astro-plugin/src/astro-bundle-analysis/astroBundleAnalysisPlugin.ts index 4ca18e43..dc72b9ca 100644 --- a/packages/astro-plugin/src/astro-bundle-analysis/astroBundleAnalysisPlugin.ts +++ b/packages/astro-plugin/src/astro-bundle-analysis/astroBundleAnalysisPlugin.ts @@ -5,11 +5,6 @@ import { } from "@codecov/bundler-plugin-core"; import { getBundleName } from "./getBundleName"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - interface AstroBundleAnalysisArgs extends BundleAnalysisUploadPluginArgs { target: "client" | "server"; } @@ -21,10 +16,12 @@ type AstroBundleAnalysisPlugin = ( export const astroBundleAnalysisPlugin: AstroBundleAnalysisPlugin = ({ output, target, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, vite: { generateBundle(this, options) { // TODO - remove this once we hard fail on not having a bundle name @@ -46,7 +43,7 @@ export const astroBundleAnalysisPlugin: AstroBundleAnalysisPlugin = ({ output.lockBundleName(); // manually set this to avoid resetting in the vite plugin - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, }, }); diff --git a/packages/astro-plugin/src/index.ts b/packages/astro-plugin/src/index.ts index ee6191a2..7aced8cd 100644 --- a/packages/astro-plugin/src/index.ts +++ b/packages/astro-plugin/src/index.ts @@ -12,8 +12,10 @@ import { type PluginOption } from "vite"; import { astroBundleAnalysisPlugin } from "./astro-bundle-analysis/astroBundleAnalysisPlugin"; -// @ts-expect-error - This is a placeholder for the package name. +// @ts-expect-error this value is being replaced by rollup const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; interface AstroPluginFactoryOptions extends Options { // type can be found from the AstroIntegration type @@ -41,8 +43,17 @@ const astroPluginFactory = createVitePlugin( const options = normalizedOptions.options; if (options.enableBundleAnalysis) { plugins.push( - astroBundleAnalysisPlugin({ output, target }), - _internal_viteBundleAnalysisPlugin({ output }), + astroBundleAnalysisPlugin({ + output, + target, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), + _internal_viteBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), ); } diff --git a/packages/bundler-plugin-core/src/types.ts b/packages/bundler-plugin-core/src/types.ts index 131c26c2..58cf6cff 100644 --- a/packages/bundler-plugin-core/src/types.ts +++ b/packages/bundler-plugin-core/src/types.ts @@ -51,6 +51,8 @@ export interface OutputPayload { export interface BundleAnalysisUploadPluginArgs { output: Output; + pluginName: string; + pluginVersion: string; } export interface ExtendedBAUploadArgs diff --git a/packages/nextjs-webpack-plugin/src/index.ts b/packages/nextjs-webpack-plugin/src/index.ts index a0e7351c..238e479c 100644 --- a/packages/nextjs-webpack-plugin/src/index.ts +++ b/packages/nextjs-webpack-plugin/src/index.ts @@ -15,6 +15,11 @@ import { import { nextJSWebpackBundleAnalysisPlugin } from "./nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + interface NextPluginOptions extends Options { webpack: typeof webpack | null; } @@ -47,6 +52,8 @@ const codecovNextJSWebpackPluginFactory = createWebpackPlugin< options: { webpack: userOptions.webpack, }, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }), ); } diff --git a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts index 65551ab6..031c758c 100644 --- a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts +++ b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts @@ -3,6 +3,11 @@ import { describe, it, expect } from "vitest"; import * as webpack from "webpack"; import { nextJSWebpackBundleAnalysisPlugin } from "../nextJSWebpackBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("webpackBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -19,6 +24,8 @@ describe("webpackBundleAnalysisPlugin", () => { options: { webpack: webpack, }, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts index c6ad3305..1ccd91fc 100644 --- a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts +++ b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts @@ -7,20 +7,15 @@ import { _internal_processModules as processModules, } from "@codecov/webpack-plugin"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ webpack: typeof webpack | null; -}> = ({ output, options: { webpack } }) => ({ +}> = ({ output, pluginName, pluginVersion }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, buildStart: () => { output.start(); - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, buildEnd: () => { output.end(); @@ -29,7 +24,7 @@ export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ await output.write(); }, webpack(compiler) { - compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => { + compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { if (!webpack) { red( "Unable to run bundle analysis, Webpack wasn't passed successfully.", @@ -39,7 +34,7 @@ export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ compilation.hooks.processAssets.tapPromise( { - name: PLUGIN_NAME, + name: pluginName, stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT, }, async () => { diff --git a/packages/nuxt-plugin/src/index.ts b/packages/nuxt-plugin/src/index.ts index 83794fc5..e2b8a223 100644 --- a/packages/nuxt-plugin/src/index.ts +++ b/packages/nuxt-plugin/src/index.ts @@ -13,8 +13,10 @@ import { addVitePlugin, defineNuxtModule } from "@nuxt/kit"; import { nuxtBundleAnalysisPlugin } from "./nuxt-bundle-analysis/nuxtBundleAnalysisPlugin"; import { type NuxtModule } from "nuxt/schema"; -// @ts-expect-error - This is a placeholder for the package name. +// @ts-expect-error this value is being replaced by rollup const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; const codecovNuxtPluginFactory = createVitePlugin( (userOptions, unpluginMetaContext) => { @@ -37,8 +39,16 @@ const codecovNuxtPluginFactory = createVitePlugin( const options = normalizedOptions.options; if (options.enableBundleAnalysis) { plugins.push( - nuxtBundleAnalysisPlugin({ output }), - _internal_viteBundleAnalysisPlugin({ output }), + nuxtBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), + _internal_viteBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), ); } diff --git a/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts b/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts index 092df0e3..ee04d0a7 100644 --- a/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts +++ b/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { nuxtBundleAnalysisPlugin } from "../nuxtBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("nuxtBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -15,6 +20,8 @@ describe("nuxtBundleAnalysisPlugin", () => { retryCount: 1, uploadToken: "test-token", }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/nuxt-plugin/src/nuxt-bundle-analysis/nuxtBundleAnalysisPlugin.ts b/packages/nuxt-plugin/src/nuxt-bundle-analysis/nuxtBundleAnalysisPlugin.ts index b96707d4..604b92b1 100644 --- a/packages/nuxt-plugin/src/nuxt-bundle-analysis/nuxtBundleAnalysisPlugin.ts +++ b/packages/nuxt-plugin/src/nuxt-bundle-analysis/nuxtBundleAnalysisPlugin.ts @@ -4,17 +4,14 @@ import { } from "@codecov/bundler-plugin-core"; import { getBundleName } from "./getBundleName"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const nuxtBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, vite: { generateBundle(this, options) { // TODO - remove this once we hard fail on not having a bundle name @@ -36,7 +33,7 @@ export const nuxtBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output.lockBundleName(); // manually set this to avoid resetting in the vite plugin - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, }, }); diff --git a/packages/remix-vite-plugin/src/index.ts b/packages/remix-vite-plugin/src/index.ts index 561c0ba9..bfece098 100644 --- a/packages/remix-vite-plugin/src/index.ts +++ b/packages/remix-vite-plugin/src/index.ts @@ -15,6 +15,11 @@ import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; import { remixBundleAnalysisPlugin } from "./remix-bundle-analysis/remixBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + const codecovRemixVitePluginFactory = createVitePlugin( (userOptions, unpluginMetaContext) => { if (checkNodeVersion(unpluginMetaContext)) { @@ -36,8 +41,16 @@ const codecovRemixVitePluginFactory = createVitePlugin( const options = normalizedOptions.options; if (options.enableBundleAnalysis) { plugins.push( - remixBundleAnalysisPlugin({ output }), - _internal_viteBundleAnalysisPlugin({ output }), + remixBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), + _internal_viteBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), ); } diff --git a/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts b/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts index e74d8b5d..de71cb3c 100644 --- a/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts +++ b/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { remixBundleAnalysisPlugin } from "../remixBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("remixBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -15,6 +20,8 @@ describe("remixBundleAnalysisPlugin", () => { retryCount: 1, uploadToken: "test-token", }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/remix-vite-plugin/src/remix-bundle-analysis/remixBundleAnalysisPlugin.ts b/packages/remix-vite-plugin/src/remix-bundle-analysis/remixBundleAnalysisPlugin.ts index 6e43c9d1..9d1c894b 100644 --- a/packages/remix-vite-plugin/src/remix-bundle-analysis/remixBundleAnalysisPlugin.ts +++ b/packages/remix-vite-plugin/src/remix-bundle-analysis/remixBundleAnalysisPlugin.ts @@ -4,17 +4,14 @@ import { } from "@codecov/bundler-plugin-core"; import { getBundleName } from "./getBundleName"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const remixBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, vite: { generateBundle(this, options) { // TODO - remove this once we hard fail on not having a bundle name @@ -36,7 +33,7 @@ export const remixBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output.lockBundleName(); // manually set this to avoid resetting in the vite plugin - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, }, }); diff --git a/packages/rollup-plugin/src/index.ts b/packages/rollup-plugin/src/index.ts index e7d82685..02dd3a6e 100644 --- a/packages/rollup-plugin/src/index.ts +++ b/packages/rollup-plugin/src/index.ts @@ -14,6 +14,11 @@ import { import { rollupBundleAnalysisPlugin } from "./rollup-bundle-analysis/rollupBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + const codecovRollupPluginFactory = createRollupPlugin( (userOptions, unpluginMetaContext) => { if (checkNodeVersion(unpluginMetaContext)) { @@ -37,6 +42,8 @@ const codecovRollupPluginFactory = createRollupPlugin( plugins.push( rollupBundleAnalysisPlugin({ output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }), ); } diff --git a/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts b/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts index d0f4592a..1005480f 100644 --- a/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts +++ b/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { rollupBundleAnalysisPlugin } from "../rollupBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("rollupBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -15,6 +20,8 @@ describe("rollupBundleAnalysisPlugin", () => { retryCount: 1, uploadToken: "test-token", }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/rollup-plugin/src/rollup-bundle-analysis/rollupBundleAnalysisPlugin.ts b/packages/rollup-plugin/src/rollup-bundle-analysis/rollupBundleAnalysisPlugin.ts index 31ffd7de..fcf4a199 100644 --- a/packages/rollup-plugin/src/rollup-bundle-analysis/rollupBundleAnalysisPlugin.ts +++ b/packages/rollup-plugin/src/rollup-bundle-analysis/rollupBundleAnalysisPlugin.ts @@ -8,20 +8,17 @@ import { createRollupAsset, } from "@codecov/bundler-plugin-core"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const rollupBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, buildStart: () => { output.start(); - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, buildEnd: () => { output.end(); diff --git a/packages/solidstart-plugin/src/index.ts b/packages/solidstart-plugin/src/index.ts index acaa3713..95031923 100644 --- a/packages/solidstart-plugin/src/index.ts +++ b/packages/solidstart-plugin/src/index.ts @@ -15,6 +15,11 @@ import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; import { solidstartBundleAnalysisPlugin } from "./solidstart-bundle-analysis/solidstartBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + const codecovSolidStartPluginFactory = createVitePlugin( (userOptions, unpluginMetaContext) => { if (checkNodeVersion(unpluginMetaContext)) { @@ -36,8 +41,16 @@ const codecovSolidStartPluginFactory = createVitePlugin( const options = normalizedOptions.options; if (options.enableBundleAnalysis) { plugins.push( - solidstartBundleAnalysisPlugin({ output }), - _internal_viteBundleAnalysisPlugin({ output }), + solidstartBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), + _internal_viteBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), ); } diff --git a/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts b/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts index 8e21392f..45fbd075 100644 --- a/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts +++ b/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { solidstartBundleAnalysisPlugin } from "../solidstartBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("solidstartBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -15,6 +20,8 @@ describe("solidstartBundleAnalysisPlugin", () => { retryCount: 1, uploadToken: "test-token", }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/solidstart-plugin/src/solidstart-bundle-analysis/solidstartBundleAnalysisPlugin.ts b/packages/solidstart-plugin/src/solidstart-bundle-analysis/solidstartBundleAnalysisPlugin.ts index a0d0d278..47d18793 100644 --- a/packages/solidstart-plugin/src/solidstart-bundle-analysis/solidstartBundleAnalysisPlugin.ts +++ b/packages/solidstart-plugin/src/solidstart-bundle-analysis/solidstartBundleAnalysisPlugin.ts @@ -4,17 +4,14 @@ import { } from "@codecov/bundler-plugin-core"; import { getBundleName } from "./getBundleName"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const solidstartBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, vite: { generateBundle(this, options) { // TODO - remove this once we hard fail on not having a bundle name @@ -36,7 +33,7 @@ export const solidstartBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output.lockBundleName(); // manually set this to avoid resetting in the vite plugin - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, }, }); diff --git a/packages/sveltekit-plugin/src/index.ts b/packages/sveltekit-plugin/src/index.ts index bae3d613..2d6f4800 100644 --- a/packages/sveltekit-plugin/src/index.ts +++ b/packages/sveltekit-plugin/src/index.ts @@ -15,6 +15,11 @@ import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; import { sveltekitBundleAnalysisPlugin } from "./sveltekit-bundle-analysis/sveltekitBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + const codecovSvelteKitPluginFactory = createVitePlugin( (userOptions, unpluginMetaContext) => { if (checkNodeVersion(unpluginMetaContext)) { @@ -36,8 +41,16 @@ const codecovSvelteKitPluginFactory = createVitePlugin( const options = normalizedOptions.options; if (options.enableBundleAnalysis) { plugins.push( - sveltekitBundleAnalysisPlugin({ output }), - _internal_viteBundleAnalysisPlugin({ output }), + sveltekitBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), + _internal_viteBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), ); } diff --git a/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/__tests__/sveltekitBundleAnalysisPlugin.test.ts b/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/__tests__/sveltekitBundleAnalysisPlugin.test.ts index f63fba01..ae1cf5a8 100644 --- a/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/__tests__/sveltekitBundleAnalysisPlugin.test.ts +++ b/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/__tests__/sveltekitBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { sveltekitBundleAnalysisPlugin } from "../sveltekitBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("sveltekitBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -14,7 +19,10 @@ describe("sveltekitBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/sveltekitBundleAnalysisPlugin.ts b/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/sveltekitBundleAnalysisPlugin.ts index 24ef67c2..2f6e11aa 100644 --- a/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/sveltekitBundleAnalysisPlugin.ts +++ b/packages/sveltekit-plugin/src/sveltekit-bundle-analysis/sveltekitBundleAnalysisPlugin.ts @@ -4,17 +4,14 @@ import { } from "@codecov/bundler-plugin-core"; import { getBundleName } from "./getBundleName"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const sveltekitBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, vite: { generateBundle(this, options) { // TODO - remove this once we hard fail on not having a bundle name @@ -36,7 +33,7 @@ export const sveltekitBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output.lockBundleName(); // manually set this to avoid resetting in the vite plugin - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, }, }); diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index 09bc83ad..fb403ac6 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -14,6 +14,11 @@ import { import { viteBundleAnalysisPlugin } from "./vite-bundle-analysis/viteBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + const codecovVitePluginFactory = createVitePlugin( (userOptions, unpluginMetaContext) => { if (checkNodeVersion(unpluginMetaContext)) { @@ -32,9 +37,17 @@ const codecovVitePluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; + if (options.enableBundleAnalysis) { const output = new Output(normalizedOptions.options); - plugins.push(viteBundleAnalysisPlugin({ output })); + + plugins.push( + viteBundleAnalysisPlugin({ + output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + }), + ); } return plugins; diff --git a/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts b/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts index 3c062107..2b79a265 100644 --- a/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts +++ b/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { viteBundleAnalysisPlugin } from "../viteBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("viteBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -15,6 +20,8 @@ describe("viteBundleAnalysisPlugin", () => { retryCount: 1, uploadToken: "test-token", }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/vite-plugin/src/vite-bundle-analysis/viteBundleAnalysisPlugin.ts b/packages/vite-plugin/src/vite-bundle-analysis/viteBundleAnalysisPlugin.ts index 5e3ee91b..8ae9677b 100644 --- a/packages/vite-plugin/src/vite-bundle-analysis/viteBundleAnalysisPlugin.ts +++ b/packages/vite-plugin/src/vite-bundle-analysis/viteBundleAnalysisPlugin.ts @@ -8,20 +8,17 @@ import { createRollupAsset, } from "@codecov/bundler-plugin-core"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const viteBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, buildStart: () => { output.start(); - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, buildEnd: () => { output.end(); diff --git a/packages/webpack-plugin/src/index.ts b/packages/webpack-plugin/src/index.ts index b18943b6..7d7f97ff 100644 --- a/packages/webpack-plugin/src/index.ts +++ b/packages/webpack-plugin/src/index.ts @@ -21,6 +21,11 @@ import { processModules, } from "./webpack-bundle-analysis/utils"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + const codecovWebpackPluginFactory = createWebpackPlugin( (userOptions, unpluginMetaContext) => { if (checkNodeVersion(unpluginMetaContext)) { @@ -44,6 +49,8 @@ const codecovWebpackPluginFactory = createWebpackPlugin( plugins.push( webpackBundleAnalysisPlugin({ output, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }), ); } diff --git a/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts b/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts index 1ef383be..4d4ffc91 100644 --- a/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts +++ b/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts @@ -2,6 +2,11 @@ import { Output } from "@codecov/bundler-plugin-core"; import { describe, it, expect } from "vitest"; import { webpackBundleAnalysisPlugin } from "../webpackBundleAnalysisPlugin"; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_NAME = __PACKAGE_NAME__ as string; +// @ts-expect-error this value is being replaced by rollup +const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; + describe("webpackBundleAnalysisPlugin", () => { describe("when called", () => { it("returns a plugin object", () => { @@ -15,6 +20,8 @@ describe("webpackBundleAnalysisPlugin", () => { retryCount: 1, uploadToken: "test-token", }), + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, }); expect(plugin).toMatchSnapshot(); diff --git a/packages/webpack-plugin/src/webpack-bundle-analysis/webpackBundleAnalysisPlugin.ts b/packages/webpack-plugin/src/webpack-bundle-analysis/webpackBundleAnalysisPlugin.ts index ab60fec0..23a837fe 100644 --- a/packages/webpack-plugin/src/webpack-bundle-analysis/webpackBundleAnalysisPlugin.ts +++ b/packages/webpack-plugin/src/webpack-bundle-analysis/webpackBundleAnalysisPlugin.ts @@ -4,20 +4,17 @@ import type * as TWebpack from "webpack"; import { processAssets, processChunks, processModules } from "./utils"; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_NAME = __PACKAGE_NAME__ as string; -// @ts-expect-error this value is being replaced by rollup -const PLUGIN_VERSION = __PACKAGE_VERSION__ as string; - export const webpackBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ output, + pluginName, + pluginVersion, }) => ({ version: output.version, - name: PLUGIN_NAME, - pluginVersion: PLUGIN_VERSION, + name: pluginName, + pluginVersion, buildStart: () => { output.start(); - output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION); + output.setPlugin(pluginName, pluginVersion); }, buildEnd: () => { output.end(); @@ -29,10 +26,10 @@ export const webpackBundleAnalysisPlugin: BundleAnalysisUploadPlugin = ({ const generatedRequire = createRequire(import.meta.url); const webpack = generatedRequire("webpack") as typeof TWebpack; - compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => { + compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { compilation.hooks.processAssets.tapPromise( { - name: PLUGIN_NAME, + name: pluginName, stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT, }, async () => { From d83cb03b2f4c32980b9c593789ebcfca2f61ae0b Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 10:30:11 -0400 Subject: [PATCH 02/23] setup Sentry in the bundler plugin core --- packages/bundler-plugin-core/package.json | 1 + packages/bundler-plugin-core/src/index.ts | 13 + .../src/sentry/__tests__/telemetry.test.ts | 188 +++++++++++++++ .../src/sentry/__tests__/transports.test.ts | 177 ++++++++++++++ .../src/sentry/telemetry.ts | 164 +++++++++++++ .../src/sentry/transports.ts | 126 ++++++++++ packages/bundler-plugin-core/src/types.ts | 9 + .../bundler-plugin-core/src/utils/Output.ts | 170 ++++++++++--- .../src/utils/__tests__/Output.test.ts | 224 +++++++++++++++++- .../utils/__tests__/normalizeOptions.test.ts | 6 + .../src/utils/normalizeOptions.ts | 5 + 11 files changed, 1047 insertions(+), 36 deletions(-) create mode 100644 packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts create mode 100644 packages/bundler-plugin-core/src/sentry/__tests__/transports.test.ts create mode 100644 packages/bundler-plugin-core/src/sentry/telemetry.ts create mode 100644 packages/bundler-plugin-core/src/sentry/transports.ts diff --git a/packages/bundler-plugin-core/package.json b/packages/bundler-plugin-core/package.json index 70be4395..98515461 100644 --- a/packages/bundler-plugin-core/package.json +++ b/packages/bundler-plugin-core/package.json @@ -41,6 +41,7 @@ "dependencies": { "@actions/core": "^1.10.1", "@actions/github": "^6.0.0", + "@sentry/core": "^8.42.0", "chalk": "4.1.2", "semver": "^7.5.4", "unplugin": "^1.10.1", diff --git a/packages/bundler-plugin-core/src/index.ts b/packages/bundler-plugin-core/src/index.ts index 5f1ec528..231bf2d3 100644 --- a/packages/bundler-plugin-core/src/index.ts +++ b/packages/bundler-plugin-core/src/index.ts @@ -1,3 +1,4 @@ +import { type Client, type Scope } from "@sentry/core"; import { type Asset, type BundleAnalysisUploadPlugin, @@ -22,6 +23,12 @@ import { Output, red, } from "./utils"; +import { + createSentryInstance, + telemetryPlugin, + safeFlushTelemetry, + setTelemetryDataOnScope, +} from "./sentry/telemetry.ts"; export type { Asset, @@ -36,6 +43,8 @@ export type { NormalizedOptions, ProviderUtilInputs, UploadOverrides, + Client as SentryClient, + Scope as SentryScope, }; export { @@ -47,4 +56,8 @@ export { normalizePath, Output, red, + createSentryInstance, + telemetryPlugin, + safeFlushTelemetry, + setTelemetryDataOnScope, }; diff --git a/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts new file mode 100644 index 00000000..50791595 --- /dev/null +++ b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts @@ -0,0 +1,188 @@ +import { describe, it, expect, vi, afterEach } from "vitest"; +import { + createSentryInstance, + setTelemetryDataOnScope, + safeFlushTelemetry, + telemetryPlugin, +} from "../telemetry"; +import { type Client, type Scope } from "@sentry/core"; +import { type NormalizedOptions } from "../../utils/normalizeOptions"; + +const mocks = vi.hoisted(() => ({ + cyan: vi.fn(), +})); + +vi.mock("../../utils/logging", () => ({ + cyan: mocks.cyan, +})); + +afterEach(() => { + vi.clearAllMocks(); +}); + +describe("telemetry", () => { + describe("createSentryInstance", () => { + it("creates instance with telemetry enabled", () => { + const options = { + telemetry: true, + dryRun: false, + } as NormalizedOptions; + const pluginInfo = { + name: "test-plugin", + version: "1.0.0", + }; + + const { sentryClient, sentryScope } = createSentryInstance( + true, + false, + pluginInfo, + options, + ); + + expect(sentryClient).toBeDefined(); + expect(sentryScope).toBeDefined(); + }); + + it("creates instance with telemetry disabled", () => { + const options = { + telemetry: false, + dryRun: false, + } as NormalizedOptions; + const pluginInfo = { + name: "test-plugin", + version: "1.0.0", + }; + + const { sentryClient, sentryScope } = createSentryInstance( + false, + false, + pluginInfo, + options, + ); + + expect(sentryClient).toBeDefined(); + expect(sentryScope).toBeDefined(); + }); + }); + + describe("setTelemetryDataOnScope", () => { + it("sets correct tags for token auth", () => { + const scope = { + setTag: vi.fn(), + } as unknown as Scope; + + const options = { + dryRun: false, + uploadToken: "some-token", + gitService: "github", + } as NormalizedOptions; + + const pluginInfo = { + name: "test-plugin", + version: "1.0.0", + }; + + setTelemetryDataOnScope(options, pluginInfo, scope); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(scope.setTag).toHaveBeenCalledWith("auth_mode", "token"); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(scope.setTag).toHaveBeenCalledWith("git_service", "github"); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(scope.setTag).toHaveBeenCalledWith("plugin.name", "test-plugin"); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(scope.setTag).toHaveBeenCalledWith("plugin.version", "1.0.0"); + }); + + it("sets correct tags for github OIDC auth", () => { + const scope = { + setTag: vi.fn(), + } as unknown as Scope; + + const options = { + dryRun: false, + oidc: { useGitHubOIDC: true }, + } as NormalizedOptions; + + const pluginInfo = { + name: "test-plugin", + version: "1.0.0", + }; + + setTelemetryDataOnScope(options, pluginInfo, scope); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(scope.setTag).toHaveBeenCalledWith("auth_mode", "github-oidc"); + }); + }); + + describe("safeFlushTelemetry", () => { + it("handles successful flush", async () => { + const client = { + flush: vi.fn().mockResolvedValue(undefined), + } as unknown as Client; + + await safeFlushTelemetry(client); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(client.flush).toHaveBeenCalledWith(2000); + }); + + it("handles failed flush without throwing", async () => { + const client = { + flush: vi.fn().mockRejectedValue(new Error("Flush failed")), + } as unknown as Client; + + await expect(safeFlushTelemetry(client)).resolves.not.toThrow(); + }); + }); + + describe("telemetryPlugin", () => { + it("logs message and starts span when telemetry enabled", async () => { + const client = { + flush: vi.fn().mockResolvedValue(undefined), + getOptions: vi.fn().mockReturnValue(undefined), + } as unknown as Client; + + const scope = { + getClient: vi.fn(() => client), + } as unknown as Scope; + + const plugin = telemetryPlugin({ + sentryClient: client, + sentryScope: scope, + shouldSendTelemetry: true, + }); + + // @ts-expect-error: buildStart is not defined in the type + await plugin.buildStart?.(); + + expect(mocks.cyan).toHaveBeenCalledWith( + "Sending telemetry data on issues and performance to Codecov. To disable telemetry, set `options.telemetry` to `false`.", + ); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(client.flush).toHaveBeenCalled(); + }); + + it("does not log message or start span when telemetry disabled", async () => { + const client = { + flush: vi.fn().mockResolvedValue(undefined), + } as unknown as Client; + + const scope = {} as Scope; + + const plugin = telemetryPlugin({ + sentryClient: client, + sentryScope: scope, + shouldSendTelemetry: false, + }); + + // @ts-expect-error: buildStart is not defined in the type + await plugin.buildStart?.(); + + expect(mocks.cyan).not.toHaveBeenCalled(); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(client.flush).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/packages/bundler-plugin-core/src/sentry/__tests__/transports.test.ts b/packages/bundler-plugin-core/src/sentry/__tests__/transports.test.ts new file mode 100644 index 00000000..12940f73 --- /dev/null +++ b/packages/bundler-plugin-core/src/sentry/__tests__/transports.test.ts @@ -0,0 +1,177 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { describe, it, expect, vi } from "vitest"; + +import { + createRequestExecutor, + makeNodeTransport, + makeOptionallyEnabledNodeTransport, + streamFromBody, +} from "../transports.ts"; +import { type Envelope } from "@sentry/core"; + +const mocks = vi.hoisted(() => ({ + statusCode: 200, + requestCalled: vi.fn(), +})); + +// Mock the node:https module +vi.mock("node:https", () => { + return { + request: vi.fn((options: any, callback: (arg?: any) => void) => { + const response = { + statusCode: mocks.statusCode, + setEncoding: vi.fn(), + headers: {}, + on: vi.fn((event: any, handler: (arg?: any) => void) => { + if (event === "data") { + handler("mocked data"); + } + if (event === "end") { + handler(); + } + }), + }; + callback(response); + mocks.requestCalled(options); + return { + end: vi.fn(), + write: vi.fn(), + }; + }), + }; +}); + +describe("transports", () => { + describe("streamFromBody", () => { + it("should return a readable stream from a Uint8Array", () => { + const body = new Uint8Array([1, 2, 3]); + const stream = streamFromBody(body); + + expect(stream.read()).toEqual(Buffer.from(body)); + }); + }); + + describe("createRequestExecutor", () => { + it("should create a request executor", () => { + const executor = createRequestExecutor({ + url: "https://localhost/upload", + recordDroppedEvent: () => { + /* */ + }, + }); + + expect(executor).toBeDefined(); + expect(typeof executor).toBe("function"); + }); + + describe("when the request is successful", () => { + it("should return a response", async () => { + const makeRequest = createRequestExecutor({ + url: "https://localhost/upload", + recordDroppedEvent: () => { + /* */ + }, + }); + + const response = await makeRequest({ + body: new Uint8Array([1, 2, 3]), + }); + + await vi.waitFor(() => expect(response.statusCode).toBe(200)); + }); + }); + + describe("when the request fails", () => { + it("should return a response", async () => { + mocks.statusCode = 500; + + const makeRequest = createRequestExecutor({ + url: "https://localhost/upload", + recordDroppedEvent: () => { + /* */ + }, + }); + + const response = await makeRequest({ + body: new Uint8Array([1, 2, 3]), + }); + + await vi.waitFor(() => expect(response.statusCode).toBe(500)); + }); + }); + }); + + describe("makeNodeTransport", () => { + it("should create a node transport object", () => { + const transport = makeNodeTransport({ + url: "https://localhost/upload", + recordDroppedEvent: () => { + /* */ + }, + }); + + expect(transport).toBeDefined(); + expect(typeof transport).toBe("object"); + }); + }); + + describe("makeOptionallyEnabledNodeTransport", () => { + it("should create an optionally enabled node transport", () => { + const transport = makeOptionallyEnabledNodeTransport(true); + + expect(transport).toBeDefined(); + expect(typeof transport).toBe("function"); + }); + + describe("when the transport is enabled", () => { + it("should send requests", async () => { + const transport = makeOptionallyEnabledNodeTransport(true); + + const transportObject = transport({ + url: "https://localhost/upload", + recordDroppedEvent: () => { + /* */ + }, + }); + + const mockEnvelope: Envelope = [ + { event_id: "test-event-id", sent_at: new Date().toISOString() }, + [], + ]; + + await transportObject.send(mockEnvelope); + + expect(mocks.requestCalled).toHaveBeenCalled(); + expect(mocks.requestCalled).toHaveBeenCalledWith({ + headers: {}, + hostname: "localhost", + method: "POST", + path: "/upload", + port: "", + protocol: "https:", + }); + }); + }); + + describe("when the transport is disabled", () => { + it("should not send requests", async () => { + const transport = makeOptionallyEnabledNodeTransport(false); + + const transportObject = transport({ + url: "https://localhost/upload", + recordDroppedEvent: () => { + /* */ + }, + }); + + const mockEnvelope: Envelope = [ + { event_id: "test-event-id", sent_at: new Date().toISOString() }, + [], + ]; + const response = await transportObject.send(mockEnvelope); + + await vi.waitFor(() => expect(response.statusCode).toBe(200)); + }); + }); + }); +}); diff --git a/packages/bundler-plugin-core/src/sentry/telemetry.ts b/packages/bundler-plugin-core/src/sentry/telemetry.ts new file mode 100644 index 00000000..c0915de5 --- /dev/null +++ b/packages/bundler-plugin-core/src/sentry/telemetry.ts @@ -0,0 +1,164 @@ +/** + * Copied and modified from: + * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/packages/bundler-plugin-core/src/sentry/telemetry.ts + */ +import { + Scope, + ServerRuntimeClient, + type ServerRuntimeClientOptions, + createStackParser, + nodeStackLineParser, + type Client, + startSpan, +} from "@sentry/core"; +import { type UnpluginOptions } from "unplugin"; +import { type NormalizedOptions } from "../utils/normalizeOptions"; +import { makeOptionallyEnabledNodeTransport } from "./transports"; +import { cyan } from "../utils/logging"; + +const stackParser = createStackParser(nodeStackLineParser()); + +interface CreateSentryInstanceOptions { + enableTelemetry: boolean; + isDryRun: boolean; + pluginName: string; + pluginVersion: string; + options?: NormalizedOptions; +} + +export function createSentryInstance({ + enableTelemetry, + isDryRun, + pluginName, + pluginVersion, + options, +}: CreateSentryInstanceOptions): { + sentryScope: Scope; + sentryClient: Client; +} { + let sampleRate = undefined; + let tracesSampleRate = undefined; + // just being really explicit here as to what we're checking for + if (enableTelemetry === true && isDryRun === false) { + sampleRate = 1; + tracesSampleRate = 1; + } + + const clientOptions: ServerRuntimeClientOptions = { + platform: "node", + runtime: { name: "node", version: global.process.version }, + + dsn: "https://942e283ea612c29cc3371c6d27f57e58@o26192.ingest.us.sentry.io/4506739665207296", + + tracesSampleRate, + sampleRate, + + release: pluginVersion, + integrations: [], + tracePropagationTargets: ["api.codecov.io"], + + stackParser, + + beforeSend: (event) => { + event.exception?.values?.forEach((exception) => { + delete exception.stacktrace; + }); + + delete event.server_name; // Server name might contain PII + return event; + }, + + beforeSendTransaction: (event) => { + delete event.server_name; // Server name might contain PII + return event; + }, + + // We create a transport that stalls sending events until we know that we're allowed to + transport: makeOptionallyEnabledNodeTransport(enableTelemetry), + }; + + const client = new ServerRuntimeClient(clientOptions); + const scope = new Scope(); + scope.setClient(client); + + if (options) { + setTelemetryDataOnScope( + options, + { name: pluginName, version: pluginVersion }, + scope, + ); + } + + return { sentryScope: scope, sentryClient: client }; +} + +interface PluginInfo { + name: string; + version: string; +} + +export function setTelemetryDataOnScope( + options: NormalizedOptions, + pluginInfo: PluginInfo, + scope: Scope, +) { + scope.setTag("node", process.version); + scope.setTag("platform", process.platform); + + scope.setTag("plugin.name", pluginInfo.name); + scope.setTag("plugin.version", pluginInfo.version); + + let authMode = options.dryRun ? "dry-run" : "tokenless"; + if (options.uploadToken && options.uploadToken !== "") { + authMode = "token"; + } else if (options.oidc?.useGitHubOIDC) { + authMode = "github-oidc"; + } + scope.setTag("auth_mode", authMode); + + if (options.gitService) { + scope.setTag("git_service", options.gitService); + } + + scope.setTag("ci", !!process.env.CI); +} + +/** Flushing the SDK client can fail. We never want to crash the plugin because of telemetry. */ +export async function safeFlushTelemetry(sentryClient: Client) { + try { + await sentryClient.flush(2000); + } catch { + // Noop when flushing fails. + // We don't even need to log anything because there's likely nothing the user can do and they likely will not care. + } +} + +interface TelemetryPluginOptions { + sentryClient: Client; + sentryScope: Scope; + shouldSendTelemetry: boolean; +} + +export function telemetryPlugin({ + sentryClient, + sentryScope, + shouldSendTelemetry, +}: TelemetryPluginOptions): UnpluginOptions { + return { + name: "codecov-telemetry-plugin", + async buildStart() { + if (shouldSendTelemetry) { + cyan( + "Sending telemetry data on issues and performance to Codecov. To disable telemetry, set `options.telemetry` to `false`.", + ); + startSpan( + { name: "Codecov Bundler Plugin execution", scope: sentryScope }, + () => { + // + }, + ); + await safeFlushTelemetry(sentryClient); + } + }, + }; +} diff --git a/packages/bundler-plugin-core/src/sentry/transports.ts b/packages/bundler-plugin-core/src/sentry/transports.ts new file mode 100644 index 00000000..4d588105 --- /dev/null +++ b/packages/bundler-plugin-core/src/sentry/transports.ts @@ -0,0 +1,126 @@ +/** + * Copied from: + * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/packages/bundler-plugin-core/src/sentry/transports.ts + */ +/** This is a simplified version of the Sentry Node SDK's HTTP transport. */ +import * as https from "node:https"; +import { Readable } from "node:stream"; +import { createGzip } from "node:zlib"; +import { + createTransport, + suppressTracing, + type BaseTransportOptions, + type Transport, + type TransportMakeRequestResponse, + type TransportRequest, + type TransportRequestExecutor, +} from "@sentry/core"; + +// Estimated maximum size for reasonable standalone event +const GZIP_THRESHOLD = 1024 * 32; + +/** + * Gets a stream from a Uint8Array or string Readable.from is ideal but was added in node.js v12.3.0 + * and v10.17.0. + */ +export function streamFromBody(body: Uint8Array | string): Readable { + return new Readable({ + read() { + this.push(body); + this.push(null); + }, + }); +} + +/** Creates a RequestExecutor to be used with `createTransport`. */ +export function createRequestExecutor( + options: BaseTransportOptions, +): TransportRequestExecutor { + const { hostname, pathname, port, protocol, search } = new URL(options.url); + + return function makeRequest( + request: TransportRequest, + ): Promise { + return new Promise((resolve, reject) => { + suppressTracing(() => { + let body = streamFromBody(request.body); + + const headers: Record = {}; + + if (request.body.length > GZIP_THRESHOLD) { + headers["content-encoding"] = "gzip"; + body = body.pipe(createGzip()); + } + + const req = https.request( + { + method: "POST", + headers, + hostname, + path: `${pathname}${search}`, + port, + protocol, + }, + (res) => { + res.on("data", () => { + // Drain socket + }); + + res.on("end", () => { + // Drain socket + }); + + res.setEncoding("utf8"); + + // "Key-value pairs of header names and values. Header names are lower-cased." + // https://nodejs.org/api/http.html#http_message_headers + const retryAfterHeader = res.headers["retry-after"] ?? null; + const rateLimitsHeader = + res.headers["x-sentry-rate-limits"] ?? null; + + resolve({ + statusCode: res.statusCode, + headers: { + "retry-after": retryAfterHeader, + "x-sentry-rate-limits": Array.isArray(rateLimitsHeader) + ? rateLimitsHeader[0] ?? null + : rateLimitsHeader, + }, + }); + }, + ); + + req.on("error", reject); + body.pipe(req); + }); + }); + }; +} + +/** + * Creates a Transport that uses native the native 'http' and 'https' modules to send events to + * Sentry. + */ +export function makeNodeTransport(options: BaseTransportOptions) { + const requestExecutor = createRequestExecutor(options); + return createTransport(options, requestExecutor); +} + +/** A transport that can be optionally enabled as a later time than it's creation. */ +export function makeOptionallyEnabledNodeTransport( + shouldSendTelemetry: boolean, +): (options: BaseTransportOptions) => Transport { + return (nodeTransportOptions) => { + const nodeTransport = makeNodeTransport(nodeTransportOptions); + return { + flush: (timeout) => nodeTransport.flush(timeout), + send: async (request) => { + if (shouldSendTelemetry) { + return nodeTransport.send(request); + } + + return { statusCode: 200 }; + }, + }; + }; +} diff --git a/packages/bundler-plugin-core/src/types.ts b/packages/bundler-plugin-core/src/types.ts index 58cf6cff..ea7860d1 100644 --- a/packages/bundler-plugin-core/src/types.ts +++ b/packages/bundler-plugin-core/src/types.ts @@ -146,6 +146,15 @@ export interface Options { */ dryRun?: boolean; + /** + * When enabled telemetry data will be sent to Codecov. + * + * Example: `telemetry: false` + * + * Defaults to `true` + */ + telemetry?: boolean; + /** Options for OIDC authentication. */ oidc?: { /** diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index 37a8e378..c56c18cd 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -1,3 +1,4 @@ +import { type Client, type Scope, startSpan } from "@sentry/core"; import { type Asset, type Chunk, @@ -12,6 +13,12 @@ import { detectProvider } from "./provider.ts"; import { uploadStats } from "./uploadStats.ts"; import { type ValidGitService } from "./normalizeOptions"; import { debug } from "./logging.ts"; +import { safeFlushTelemetry } from "../sentry/telemetry.ts"; + +interface SentryConfig { + sentryClient?: Client; + sentryScope?: Scope; +} class Output { // base user options @@ -27,6 +34,7 @@ class Output { debug: boolean; gitService?: ValidGitService; #internalOriginalBundleName: string; + telemetry: boolean; // uploader overrides branch?: string; build?: string; @@ -55,8 +63,10 @@ class Output { bundleName: false, pluginDetails: false, }; + sentryClient?: Client; + sentryScope?: Scope; - constructor(userOptions: NormalizedOptions) { + constructor(userOptions: NormalizedOptions, sentryConfig?: SentryConfig) { this.version = "3"; this.apiUrl = userOptions.apiUrl; this.dryRun = userOptions.dryRun; @@ -67,6 +77,9 @@ class Output { this.gitService = userOptions.gitService; this.#internalOriginalBundleName = userOptions.bundleName; this.oidc = userOptions.oidc; + this.telemetry = userOptions.telemetry; + this.sentryClient = sentryConfig?.sentryClient; + this.sentryScope = sentryConfig?.sentryScope; if (userOptions.uploadOverrides) { this.branch = userOptions.uploadOverrides.branch; @@ -148,42 +161,131 @@ class Output { }; const envs = process.env; const inputs: ProviderUtilInputs = { envs, args }; - const provider = await detectProvider(inputs, this); - let url = ""; - try { - url = await getPreSignedURL({ - apiUrl: this.apiUrl, - uploadToken: this.uploadToken, - gitService: this.gitService, - oidc: this.oidc, - retryCount: this.retryCount, - serviceParams: provider, - }); - } catch (error) { - if (emitError) { - throw error; - } - - debug(`Error getting pre-signed URL: "${error}"`, { - enabled: this.debug, - }); - return; + const provider = await startSpan( + { name: "detectProvider", scope: this.sentryScope }, + async () => { + let detectedProvider; + try { + detectedProvider = await detectProvider(inputs, this); + } catch (error) { + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.detectProvider", + level: "error", + data: { error }, + }); + // this is being set as info because this could be caused by user error + this.sentryClient.captureMessage( + "Error in detectProvider", + "info", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error getting provider: "${error}"`, { + enabled: this.debug, + }); + return; + } + + return detectedProvider; + }, + ); + + if (!provider) return; + + if (this.sentryScope) { + this.sentryScope.setTag("provider.service", provider.service); } - try { - await uploadStats({ - preSignedUrl: url, - bundleName: this.bundleName, - message: this.bundleStatsToJson(), - retryCount: this?.retryCount, - }); - } catch (error) { - if (emitError) { - throw error; - } - debug(`Error uploading stats: "${error}"`, { enabled: this.debug }); - return; + let url = ""; + await startSpan( + { name: "getPreSignedURL", scope: this.sentryScope }, + async () => { + try { + url = await getPreSignedURL({ + apiUrl: this.apiUrl, + uploadToken: this.uploadToken, + gitService: this.gitService, + oidc: this.oidc, + retryCount: this.retryCount, + serviceParams: provider, + }); + } catch (error) { + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.getPreSignedURL", + level: "error", + data: { error }, + }); + // only setting this as info because this could be caused by user error + this.sentryClient.captureMessage( + "Error in getPreSignedURL", + "info", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error getting pre-signed URL: "${error}"`, { + enabled: this.debug, + }); + return; + } + }, + ); + + await startSpan( + { name: "uploadStats", scope: this.sentryScope }, + async () => { + try { + await uploadStats({ + preSignedUrl: url, + bundleName: this.bundleName, + message: this.bundleStatsToJson(), + retryCount: this?.retryCount, + }); + } catch (error) { + // this is being set as an error because this could not be caused by a user error + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.uploadStats", + level: "error", + data: { error }, + }); + this.sentryClient.captureMessage( + "Error in uploadStats", + "error", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error uploading stats: "${error}"`, { enabled: this.debug }); + return; + } + }, + ); + + if (this.sentryClient) { + await safeFlushTelemetry(this.sentryClient); } return; diff --git a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts index 8150a245..0c67b9d1 100644 --- a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts +++ b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts @@ -8,18 +8,20 @@ import { afterAll, type MockInstance, type Mock, + beforeEach, } from "vitest"; +import { type Scope, type Client } from "@sentry/core"; +import chalk from "chalk"; import { detectProvider } from "../provider"; import { Output } from "../Output"; -import chalk from "chalk"; vi.mock("../provider"); const mockedDetectProvider = detectProvider as Mock; afterEach(() => { - vi.resetAllMocks(); + vi.clearAllMocks(); }); let consoleSpy: MockInstance; @@ -113,6 +115,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -140,6 +143,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -159,6 +163,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.end(); @@ -178,6 +183,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.setPlugin("test-plugin", "0.0.1"); @@ -199,6 +205,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.setPlugin("test-plugin", "0.0.1"); @@ -224,6 +231,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.setBundleName("new-bundle"); @@ -242,6 +250,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.setBundleName("new-bundle"); @@ -265,6 +274,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); output.end(); @@ -309,6 +319,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); output.end(); @@ -319,6 +330,107 @@ describe("Output", () => { }); }); + describe("fails to detect provider", () => { + beforeEach(() => { + mockedDetectProvider.mockRejectedValue( + new Error("Failed to detect provider"), + ); + }); + + it("throws an error", async () => { + const output = new Output({ + apiUrl: "http://localhost", + bundleName: "output-test", + debug: false, + dryRun: false, + enableBundleAnalysis: true, + retryCount: 1, + uploadToken: "token", + telemetry: false, + }); + + output.start(); + output.end(); + + try { + await output.write(); + } catch (error) { + expect(error).toBeInstanceOf(Error); + expect((error as Error).message).toBe("Failed to detect provider"); + } + }); + + it("logs error when debug is enabled", async () => { + const output = new Output({ + apiUrl: "http://localhost", + bundleName: "output-test", + debug: true, + dryRun: false, + enableBundleAnalysis: true, + retryCount: 1, + uploadToken: "token", + telemetry: false, + }); + + output.start(); + output.end(); + + await output.write(); + + expect(consoleSpy).toHaveBeenCalledWith( + `[codecov] ${chalk.italic.yellow( + 'Error getting provider: "Error: Failed to detect provider"', + )}`, + ); + }); + + it("captures a message to sentry", async () => { + const sentryClient = { + captureMessage: vi.fn(), + } as unknown as Client; + + const sentryScope = { + getClient: vi.fn(), + setTag: vi.fn(), + addBreadcrumb: vi.fn(), + } as unknown as Scope; + + const output = new Output( + { + apiUrl: "http://localhost", + bundleName: "output-test", + debug: true, + dryRun: false, + enableBundleAnalysis: true, + retryCount: 1, + uploadToken: "token", + telemetry: false, + }, + { sentryClient, sentryScope }, + ); + + output.start(); + output.end(); + + await output.write(); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryClient.captureMessage).toHaveBeenCalledWith( + "Error in detectProvider", + "info", + undefined, + sentryScope, + ); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryScope.addBreadcrumb).toHaveBeenCalledWith({ + category: "output.write.detectProvider", + level: "error", + data: { error: Error("Failed to detect provider") }, + }); + }); + }); + describe("fails to fetch pre-signed URL", () => { it("immediately returns", async () => { setup({ urlSendError: true }); @@ -331,6 +443,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -350,6 +463,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -375,6 +489,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -384,6 +499,54 @@ describe("Output", () => { "Failed to fetch pre-signed URL", ); }); + + it("captures message to sentry", async () => { + setup({ urlSendError: true }); + + const sentryClient = { + captureMessage: vi.fn(), + } as unknown as Client; + + const sentryScope = { + getClient: vi.fn(), + setTag: vi.fn(), + addBreadcrumb: vi.fn(), + } as unknown as Scope; + + const output = new Output( + { + apiUrl: "http://localhost", + bundleName: "output-test", + debug: false, + dryRun: false, + enableBundleAnalysis: true, + retryCount: 1, + uploadToken: "token", + telemetry: false, + }, + { sentryClient, sentryScope }, + ); + + output.start(); + output.end(); + + await output.write(); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryClient.captureMessage).toHaveBeenCalledWith( + "Error in getPreSignedURL", + "info", + undefined, + sentryScope, + ); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryScope.addBreadcrumb).toHaveBeenCalledWith({ + category: "output.write.getPreSignedURL", + level: "error", + data: { error: Error("Failed to fetch pre-signed URL") }, + }); + }); }); describe("successful fetch of pre-signed URL", () => { @@ -401,6 +564,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -448,6 +612,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -471,6 +636,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -500,6 +666,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); @@ -509,6 +676,58 @@ describe("Output", () => { "Failed to upload stats", ); }); + + it("captures message to sentry", async () => { + setup({ + urlData: { url: "http://localhost/upload/stats/" }, + urlStatus: 200, + statsSendError: true, + }); + + const sentryClient = { + captureMessage: vi.fn(), + } as unknown as Client; + + const sentryScope = { + getClient: vi.fn(), + setTag: vi.fn(), + addBreadcrumb: vi.fn(), + } as unknown as Scope; + + const output = new Output( + { + apiUrl: "http://localhost", + bundleName: "output-test", + debug: false, + dryRun: false, + enableBundleAnalysis: true, + retryCount: 1, + uploadToken: "token", + telemetry: false, + }, + { sentryClient, sentryScope }, + ); + + output.start(); + output.end(); + + await output.write(); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryClient.captureMessage).toHaveBeenCalledWith( + "Error in uploadStats", + "error", + undefined, + sentryScope, + ); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryScope.addBreadcrumb).toHaveBeenCalledWith({ + category: "output.write.uploadStats", + level: "error", + data: { error: Error("Failed to upload stats") }, + }); + }); }); describe("successful uploading of stats", () => { @@ -528,6 +747,7 @@ describe("Output", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "token", + telemetry: false, }); output.start(); diff --git a/packages/bundler-plugin-core/src/utils/__tests__/normalizeOptions.test.ts b/packages/bundler-plugin-core/src/utils/__tests__/normalizeOptions.test.ts index a5a02c40..1f003811 100644 --- a/packages/bundler-plugin-core/src/utils/__tests__/normalizeOptions.test.ts +++ b/packages/bundler-plugin-core/src/utils/__tests__/normalizeOptions.test.ts @@ -39,6 +39,7 @@ const tests: Test[] = [ retryCount: 3, enableBundleAnalysis: false, debug: false, + telemetry: true, }, }, }, @@ -62,6 +63,7 @@ const tests: Test[] = [ }, debug: true, gitService: "bitbucket", + telemetry: false, oidc: { useGitHubOIDC: true, gitHubOIDCTokenAudience: "https://codecov.io", @@ -87,6 +89,7 @@ const tests: Test[] = [ }, debug: true, gitService: "bitbucket", + telemetry: false, oidc: { useGitHubOIDC: true, gitHubOIDCTokenAudience: "https://codecov.io", @@ -128,6 +131,8 @@ const tests: Test[] = [ debug: "true", // @ts-expect-error - testing invalid input gitService: 123, + // @ts-expect-error - testing invalid input + telemetry: "true", oidc: { // @ts-expect-error - testing invalid input useGitHubOIDC: "true", @@ -155,6 +160,7 @@ const tests: Test[] = [ "`gitService` must be a valid git service.", "`useGitHubOIDC` must be a boolean.", "`gitHubOIDCTokenAudience` must be a string.", + "`telemetry` must be a boolean.", ], }, }, diff --git a/packages/bundler-plugin-core/src/utils/normalizeOptions.ts b/packages/bundler-plugin-core/src/utils/normalizeOptions.ts index 6dbedd88..6efff8b2 100644 --- a/packages/bundler-plugin-core/src/utils/normalizeOptions.ts +++ b/packages/bundler-plugin-core/src/utils/normalizeOptions.ts @@ -146,6 +146,11 @@ const optionsSchemaFactory = (options: Options) => ) .optional(), oidc: OIDCSchema.optional(), + telemetry: z + .boolean({ + invalid_type_error: "`telemetry` must be a boolean.", + }) + .default(true), }); interface NormalizedOptionsFailure { From 26b4a736d457355d5e3368e98be443c2a4eb7404 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 10:30:43 -0400 Subject: [PATCH 03/23] add to the plugins --- .../__tests__/astroBundleAnalysisPlugin.test.ts | 1 + packages/astro-plugin/src/index.ts | 17 ++++++++++++++++- packages/nextjs-webpack-plugin/src/index.ts | 17 ++++++++++++++++- .../nextJSWebpackBundleAnalysisPlugin.test.ts | 1 + packages/nuxt-plugin/src/index.ts | 17 ++++++++++++++++- .../__tests__/nuxtBundleAnalysisPlugin.test.ts | 1 + packages/remix-vite-plugin/src/index.ts | 17 ++++++++++++++++- .../__tests__/remixBundleAnalysisPlugin.test.ts | 1 + packages/rollup-plugin/src/index.ts | 17 ++++++++++++++++- .../rollupBundleAnalysisPlugin.test.ts | 1 + packages/solidstart-plugin/src/index.ts | 17 ++++++++++++++++- .../solidstartBundleAnalysisPlugin.test.ts | 1 + packages/sveltekit-plugin/src/index.ts | 17 ++++++++++++++++- packages/vite-plugin/src/index.ts | 17 +++++++++++++++-- .../__tests__/viteBundleAnalysisPlugin.test.ts | 1 + packages/webpack-plugin/src/index.ts | 17 ++++++++++++++++- .../webpackBundleAnalysisPlugin.test.ts | 1 + 17 files changed, 151 insertions(+), 10 deletions(-) diff --git a/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts b/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts index 1959ebe7..8f4b5440 100644 --- a/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts +++ b/packages/astro-plugin/src/astro-bundle-analysis/__tests__/astroBundleAnalysisPlugin.test.ts @@ -20,6 +20,7 @@ describe("astroBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, diff --git a/packages/astro-plugin/src/index.ts b/packages/astro-plugin/src/index.ts index 7aced8cd..fac9ae1a 100644 --- a/packages/astro-plugin/src/index.ts +++ b/packages/astro-plugin/src/index.ts @@ -5,6 +5,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; import { type AstroIntegration } from "astro"; @@ -39,10 +41,23 @@ const astroPluginFactory = createVitePlugin( } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), astroBundleAnalysisPlugin({ output, target, diff --git a/packages/nextjs-webpack-plugin/src/index.ts b/packages/nextjs-webpack-plugin/src/index.ts index 238e479c..a7c83f2d 100644 --- a/packages/nextjs-webpack-plugin/src/index.ts +++ b/packages/nextjs-webpack-plugin/src/index.ts @@ -11,6 +11,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { nextJSWebpackBundleAnalysisPlugin } from "./nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts"; @@ -43,10 +45,23 @@ const codecovNextJSWebpackPluginFactory = createWebpackPlugin< } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), nextJSWebpackBundleAnalysisPlugin({ output, options: { diff --git a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts index 031c758c..9b826a5b 100644 --- a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts +++ b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/__tests__/nextJSWebpackBundleAnalysisPlugin.test.ts @@ -20,6 +20,7 @@ describe("webpackBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), options: { webpack: webpack, diff --git a/packages/nuxt-plugin/src/index.ts b/packages/nuxt-plugin/src/index.ts index e2b8a223..69587dec 100644 --- a/packages/nuxt-plugin/src/index.ts +++ b/packages/nuxt-plugin/src/index.ts @@ -6,6 +6,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; import { addVitePlugin, defineNuxtModule } from "@nuxt/kit"; @@ -35,10 +37,23 @@ const codecovNuxtPluginFactory = createVitePlugin( } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), nuxtBundleAnalysisPlugin({ output, pluginName: PLUGIN_NAME, diff --git a/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts b/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts index ee04d0a7..84da0a9f 100644 --- a/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts +++ b/packages/nuxt-plugin/src/nuxt-bundle-analysis/__tests__/nuxtBundleAnalysisPlugin.test.ts @@ -19,6 +19,7 @@ describe("nuxtBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, diff --git a/packages/remix-vite-plugin/src/index.ts b/packages/remix-vite-plugin/src/index.ts index bfece098..e016559b 100644 --- a/packages/remix-vite-plugin/src/index.ts +++ b/packages/remix-vite-plugin/src/index.ts @@ -10,6 +10,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; @@ -37,10 +39,23 @@ const codecovRemixVitePluginFactory = createVitePlugin( } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), remixBundleAnalysisPlugin({ output, pluginName: PLUGIN_NAME, diff --git a/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts b/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts index de71cb3c..0383c1d2 100644 --- a/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts +++ b/packages/remix-vite-plugin/src/remix-bundle-analysis/__tests__/remixBundleAnalysisPlugin.test.ts @@ -19,6 +19,7 @@ describe("remixBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, diff --git a/packages/rollup-plugin/src/index.ts b/packages/rollup-plugin/src/index.ts index 02dd3a6e..04b4ac15 100644 --- a/packages/rollup-plugin/src/index.ts +++ b/packages/rollup-plugin/src/index.ts @@ -10,6 +10,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { rollupBundleAnalysisPlugin } from "./rollup-bundle-analysis/rollupBundleAnalysisPlugin"; @@ -36,10 +38,23 @@ const codecovRollupPluginFactory = createRollupPlugin( } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), rollupBundleAnalysisPlugin({ output, pluginName: PLUGIN_NAME, diff --git a/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts b/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts index 1005480f..a4e63639 100644 --- a/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts +++ b/packages/rollup-plugin/src/rollup-bundle-analysis/__tests__/rollupBundleAnalysisPlugin.test.ts @@ -19,6 +19,7 @@ describe("rollupBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, diff --git a/packages/solidstart-plugin/src/index.ts b/packages/solidstart-plugin/src/index.ts index 95031923..64fa90d8 100644 --- a/packages/solidstart-plugin/src/index.ts +++ b/packages/solidstart-plugin/src/index.ts @@ -10,6 +10,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; @@ -37,10 +39,23 @@ const codecovSolidStartPluginFactory = createVitePlugin( } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), solidstartBundleAnalysisPlugin({ output, pluginName: PLUGIN_NAME, diff --git a/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts b/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts index 45fbd075..5123109c 100644 --- a/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts +++ b/packages/solidstart-plugin/src/solidstart-bundle-analysis/__tests__/solidstartBundleAnalysisPlugin.test.ts @@ -19,6 +19,7 @@ describe("solidstartBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, diff --git a/packages/sveltekit-plugin/src/index.ts b/packages/sveltekit-plugin/src/index.ts index 2d6f4800..11b97dbe 100644 --- a/packages/sveltekit-plugin/src/index.ts +++ b/packages/sveltekit-plugin/src/index.ts @@ -10,6 +10,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { _internal_viteBundleAnalysisPlugin } from "@codecov/vite-plugin"; @@ -37,10 +39,23 @@ const codecovSvelteKitPluginFactory = createVitePlugin( } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), sveltekitBundleAnalysisPlugin({ output, pluginName: PLUGIN_NAME, diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index fb403ac6..619b01fd 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -10,6 +10,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { viteBundleAnalysisPlugin } from "./vite-bundle-analysis/viteBundleAnalysisPlugin"; @@ -37,11 +39,22 @@ const codecovVitePluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); if (options.enableBundleAnalysis) { - const output = new Output(normalizedOptions.options); - plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), viteBundleAnalysisPlugin({ output, pluginName: PLUGIN_NAME, diff --git a/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts b/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts index 2b79a265..2fd50f0c 100644 --- a/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts +++ b/packages/vite-plugin/src/vite-bundle-analysis/__tests__/viteBundleAnalysisPlugin.test.ts @@ -19,6 +19,7 @@ describe("viteBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, diff --git a/packages/webpack-plugin/src/index.ts b/packages/webpack-plugin/src/index.ts index 7d7f97ff..ce38c53f 100644 --- a/packages/webpack-plugin/src/index.ts +++ b/packages/webpack-plugin/src/index.ts @@ -10,6 +10,8 @@ import { checkNodeVersion, Output, handleErrors, + createSentryInstance, + telemetryPlugin, } from "@codecov/bundler-plugin-core"; import { webpackBundleAnalysisPlugin } from "./webpack-bundle-analysis/webpackBundleAnalysisPlugin"; @@ -43,10 +45,23 @@ const codecovWebpackPluginFactory = createWebpackPlugin( } const plugins: UnpluginOptions[] = []; - const output = new Output(normalizedOptions.options); const options = normalizedOptions.options; + const output = new Output(options); + const sentryConfig = createSentryInstance({ + enableTelemetry: options.telemetry, + isDryRun: options.dryRun, + pluginName: PLUGIN_NAME, + pluginVersion: PLUGIN_VERSION, + options, + }); + if (options.enableBundleAnalysis) { plugins.push( + telemetryPlugin({ + sentryClient: sentryConfig.sentryClient, + sentryScope: sentryConfig.sentryScope, + shouldSendTelemetry: options.telemetry, + }), webpackBundleAnalysisPlugin({ output, pluginName: PLUGIN_NAME, diff --git a/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts b/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts index 4d4ffc91..f4e31285 100644 --- a/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts +++ b/packages/webpack-plugin/src/webpack-bundle-analysis/__tests__/webpackBundleAnalysisPlugin.test.ts @@ -19,6 +19,7 @@ describe("webpackBundleAnalysisPlugin", () => { enableBundleAnalysis: true, retryCount: 1, uploadToken: "test-token", + telemetry: false, }), pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, From bd3493618bc8071cf8917b64d393c1eb12fb16b2 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 10:31:06 -0400 Subject: [PATCH 04/23] disable telemetry in the integration tests --- .../fixtures/generate-bundle-stats/astro/astro-base.config.mjs | 1 + .../fixtures/generate-bundle-stats/nextjs/next-base.config.mjs | 1 + .../fixtures/generate-bundle-stats/nuxt/nuxt-base.config.ts | 1 + .../fixtures/generate-bundle-stats/remix/vite-base.config.ts | 1 + .../fixtures/generate-bundle-stats/rollup/rollup-base.config.cjs | 1 + .../fixtures/generate-bundle-stats/solidstart/app-base.config.ts | 1 + .../fixtures/generate-bundle-stats/sveltekit/vite-base.config.ts | 1 + .../fixtures/generate-bundle-stats/vite/vite-base.config.ts | 1 + .../generate-bundle-stats/webpack/webpack-base.config.cjs | 1 + 9 files changed, 9 insertions(+) diff --git a/integration-tests/fixtures/generate-bundle-stats/astro/astro-base.config.mjs b/integration-tests/fixtures/generate-bundle-stats/astro/astro-base.config.mjs index e53a9549..d9e32b23 100644 --- a/integration-tests/fixtures/generate-bundle-stats/astro/astro-base.config.mjs +++ b/integration-tests/fixtures/generate-bundle-stats/astro/astro-base.config.mjs @@ -26,6 +26,7 @@ export default defineConfig({ bundleName: "test-astro-v4", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, }), ], }); diff --git a/integration-tests/fixtures/generate-bundle-stats/nextjs/next-base.config.mjs b/integration-tests/fixtures/generate-bundle-stats/nextjs/next-base.config.mjs index bf18c485..49104d33 100644 --- a/integration-tests/fixtures/generate-bundle-stats/nextjs/next-base.config.mjs +++ b/integration-tests/fixtures/generate-bundle-stats/nextjs/next-base.config.mjs @@ -10,6 +10,7 @@ export default { uploadToken: "test-token", apiUrl: process.env.API_URL, webpack: options.webpack, + telemetry: false, debug: true, }), ); diff --git a/integration-tests/fixtures/generate-bundle-stats/nuxt/nuxt-base.config.ts b/integration-tests/fixtures/generate-bundle-stats/nuxt/nuxt-base.config.ts index a306bde2..497e2d29 100644 --- a/integration-tests/fixtures/generate-bundle-stats/nuxt/nuxt-base.config.ts +++ b/integration-tests/fixtures/generate-bundle-stats/nuxt/nuxt-base.config.ts @@ -11,6 +11,7 @@ const config: ReturnType = defineNuxtConfig({ bundleName: "test-nuxt-v3", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, }, ], ], diff --git a/integration-tests/fixtures/generate-bundle-stats/remix/vite-base.config.ts b/integration-tests/fixtures/generate-bundle-stats/remix/vite-base.config.ts index fe5468a0..c56a8daa 100644 --- a/integration-tests/fixtures/generate-bundle-stats/remix/vite-base.config.ts +++ b/integration-tests/fixtures/generate-bundle-stats/remix/vite-base.config.ts @@ -26,6 +26,7 @@ export default defineConfig({ bundleName: "test-remix-v2", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, }), ], }); diff --git a/integration-tests/fixtures/generate-bundle-stats/rollup/rollup-base.config.cjs b/integration-tests/fixtures/generate-bundle-stats/rollup/rollup-base.config.cjs index 3a8c557c..02bf4d3b 100644 --- a/integration-tests/fixtures/generate-bundle-stats/rollup/rollup-base.config.cjs +++ b/integration-tests/fixtures/generate-bundle-stats/rollup/rollup-base.config.cjs @@ -22,6 +22,7 @@ module.exports = defineConfig({ bundleName: "test-rollup-v3", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, }), ], }); diff --git a/integration-tests/fixtures/generate-bundle-stats/solidstart/app-base.config.ts b/integration-tests/fixtures/generate-bundle-stats/solidstart/app-base.config.ts index c51751e7..5ca1ed79 100644 --- a/integration-tests/fixtures/generate-bundle-stats/solidstart/app-base.config.ts +++ b/integration-tests/fixtures/generate-bundle-stats/solidstart/app-base.config.ts @@ -22,6 +22,7 @@ export default defineConfig({ bundleName: "test-solidstart-v1", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, // eslint-disable-next-line @typescript-eslint/no-explicit-any }) as any, ], diff --git a/integration-tests/fixtures/generate-bundle-stats/sveltekit/vite-base.config.ts b/integration-tests/fixtures/generate-bundle-stats/sveltekit/vite-base.config.ts index 590a48a1..34525a26 100644 --- a/integration-tests/fixtures/generate-bundle-stats/sveltekit/vite-base.config.ts +++ b/integration-tests/fixtures/generate-bundle-stats/sveltekit/vite-base.config.ts @@ -22,6 +22,7 @@ export default defineConfig({ bundleName: "test-sveltekit-v2", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, }), ], }); diff --git a/integration-tests/fixtures/generate-bundle-stats/vite/vite-base.config.ts b/integration-tests/fixtures/generate-bundle-stats/vite/vite-base.config.ts index 9bcbd41a..d2c319ec 100644 --- a/integration-tests/fixtures/generate-bundle-stats/vite/vite-base.config.ts +++ b/integration-tests/fixtures/generate-bundle-stats/vite/vite-base.config.ts @@ -24,6 +24,7 @@ export default defineConfig({ bundleName: "test-vite-v5", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, }), ], }); diff --git a/integration-tests/fixtures/generate-bundle-stats/webpack/webpack-base.config.cjs b/integration-tests/fixtures/generate-bundle-stats/webpack/webpack-base.config.cjs index bcc60070..8a9e48aa 100644 --- a/integration-tests/fixtures/generate-bundle-stats/webpack/webpack-base.config.cjs +++ b/integration-tests/fixtures/generate-bundle-stats/webpack/webpack-base.config.cjs @@ -19,6 +19,7 @@ module.exports = { bundleName: "test-webpack-v5", uploadToken: "test-token", apiUrl: process.env.API_URL, + telemetry: false, }), ], }; From b9d057d212d94d7046d7c9af540b0d60e62d8372 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 10:31:25 -0400 Subject: [PATCH 05/23] update lock file --- pnpm-lock.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e17331f0..e09af1ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1017,6 +1017,9 @@ importers: '@actions/github': specifier: ^6.0.0 version: 6.0.0 + '@sentry/core': + specifier: ^8.42.0 + version: 8.42.0 chalk: specifier: 4.1.2 version: 4.1.2 @@ -4694,6 +4697,10 @@ packages: '@rushstack/eslint-patch@1.7.2': resolution: {integrity: sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==} + '@sentry/core@8.42.0': + resolution: {integrity: sha512-ac6O3pgoIbU6rpwz6LlwW0wp3/GAHuSI0C5IsTgIY6baN8rOBnlAtG6KrHDDkGmUQ2srxkDJu9n1O6Td3cBCqw==} + engines: {node: '>=14.18'} + '@shikijs/core@1.23.1': resolution: {integrity: sha512-NuOVgwcHgVC6jBVH5V7iblziw6iQbWWHrj5IlZI3Fqu2yx9awH7OIQkXIcsHsUmY19ckwSgUMgrqExEyP5A0TA==} @@ -16495,6 +16502,8 @@ snapshots: '@rushstack/eslint-patch@1.7.2': {} + '@sentry/core@8.42.0': {} + '@shikijs/core@1.23.1': dependencies: '@shikijs/engine-javascript': 1.23.1 From 56421c7f5fb40ed1b1ca37115c80a3efdc1f89e2 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 10:31:37 -0400 Subject: [PATCH 06/23] add in changeset --- .changeset/green-goats-thank.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .changeset/green-goats-thank.md diff --git a/.changeset/green-goats-thank.md b/.changeset/green-goats-thank.md new file mode 100644 index 00000000..fff3248a --- /dev/null +++ b/.changeset/green-goats-thank.md @@ -0,0 +1,15 @@ +--- +"@codecov/nextjs-webpack-plugin": minor +"@codecov/bundler-plugin-core": minor +"@codecov/remix-vite-plugin": minor +"@codecov/solidstart-plugin": minor +"@codecov/sveltekit-plugin": minor +"@codecov/webpack-plugin": minor +"@codecov/rollup-plugin": minor +"@codecov/astro-plugin": minor +"@codecov/nuxt-plugin": minor +"@codecov/vite-plugin": minor +"@codecov/bundle-analyzer": minor +--- + +Add Sentry to the bundler plugins to start collecting issues and telemerty From 5f6b20e03f6098101b9c6c55ef4b3518ac19e74e Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 10:49:07 -0400 Subject: [PATCH 07/23] fix type issues --- .../src/sentry/__tests__/telemetry.test.ts | 42 ++++++------------- .../src/utils/__tests__/provider.test.ts | 2 + .../providers/__tests__/AppVeyorCI.test.ts | 4 ++ .../__tests__/AzurePipelines.test.ts | 6 +++ .../providers/__tests__/Bitbucket.test.ts | 5 +++ .../utils/providers/__tests__/Bitrise.test.ts | 4 ++ .../providers/__tests__/Buildkite.test.ts | 2 + .../providers/__tests__/CircleCI.test.ts | 3 ++ .../utils/providers/__tests__/Cirrus.test.ts | 2 + .../__tests__/CloudflarePages.test.ts | 3 ++ .../providers/__tests__/CodeBuild.test.ts | 2 + .../utils/providers/__tests__/Drone.test.ts | 3 ++ .../providers/__tests__/GitHubActions.test.ts | 8 ++++ .../providers/__tests__/GitLabCI.test.ts | 5 +++ .../providers/__tests__/HerokuCI.test.ts | 3 ++ .../providers/__tests__/JenkinsCI.test.ts | 4 ++ .../utils/providers/__tests__/Local.test.ts | 6 +++ .../utils/providers/__tests__/Netlify.test.ts | 3 ++ .../utils/providers/__tests__/Render.test.ts | 3 ++ .../providers/__tests__/TeamCity.test.ts | 4 ++ .../providers/__tests__/TravisCI.test.ts | 5 +++ .../utils/providers/__tests__/Vercel.test.ts | 3 ++ .../utils/providers/__tests__/Werker.test.ts | 3 ++ .../providers/__tests__/Woodpecker.test.ts | 3 ++ .../utils/providers/__tests__/index.test.ts | 2 + 25 files changed, 100 insertions(+), 30 deletions(-) diff --git a/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts index 50791595..58e5f36a 100644 --- a/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts +++ b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts @@ -23,42 +23,24 @@ afterEach(() => { describe("telemetry", () => { describe("createSentryInstance", () => { it("creates instance with telemetry enabled", () => { - const options = { - telemetry: true, - dryRun: false, - } as NormalizedOptions; - const pluginInfo = { - name: "test-plugin", - version: "1.0.0", - }; - - const { sentryClient, sentryScope } = createSentryInstance( - true, - false, - pluginInfo, - options, - ); + const { sentryClient, sentryScope } = createSentryInstance({ + enableTelemetry: true, + isDryRun: false, + pluginName: "test-plugin", + pluginVersion: "1.0.0", + }); expect(sentryClient).toBeDefined(); expect(sentryScope).toBeDefined(); }); it("creates instance with telemetry disabled", () => { - const options = { - telemetry: false, - dryRun: false, - } as NormalizedOptions; - const pluginInfo = { - name: "test-plugin", - version: "1.0.0", - }; - - const { sentryClient, sentryScope } = createSentryInstance( - false, - false, - pluginInfo, - options, - ); + const { sentryClient, sentryScope } = createSentryInstance({ + enableTelemetry: false, + isDryRun: false, + pluginName: "test-plugin", + pluginVersion: "1.0.0", + }); expect(sentryClient).toBeDefined(); expect(sentryScope).toBeDefined(); diff --git a/packages/bundler-plugin-core/src/utils/__tests__/provider.test.ts b/packages/bundler-plugin-core/src/utils/__tests__/provider.test.ts index 4fdd8115..837fb013 100644 --- a/packages/bundler-plugin-core/src/utils/__tests__/provider.test.ts +++ b/packages/bundler-plugin-core/src/utils/__tests__/provider.test.ts @@ -47,6 +47,7 @@ describe("detectProvider", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const result = await detectProvider(inputs, output); @@ -65,6 +66,7 @@ describe("detectProvider", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); try { diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/AppVeyorCI.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/AppVeyorCI.test.ts index 624f5a70..41cf2940 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/AppVeyorCI.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/AppVeyorCI.test.ts @@ -88,6 +88,7 @@ describe("AppveyorCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AppVeyorCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -130,6 +131,7 @@ describe("AppveyorCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AppVeyorCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -171,6 +173,7 @@ describe("AppveyorCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AppVeyorCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -200,6 +203,7 @@ describe("AppveyorCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AppVeyorCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/AzurePipelines.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/AzurePipelines.test.ts index c3ebcd01..c371a453 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/AzurePipelines.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/AzurePipelines.test.ts @@ -65,6 +65,7 @@ describe("Azure Pipelines CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AzurePipelines.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -107,6 +108,7 @@ describe("Azure Pipelines CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AzurePipelines.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -149,6 +151,7 @@ describe("Azure Pipelines CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AzurePipelines.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -194,6 +197,7 @@ describe("Azure Pipelines CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AzurePipelines.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -240,6 +244,7 @@ describe("Azure Pipelines CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AzurePipelines.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -280,6 +285,7 @@ describe("Azure Pipelines CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await AzurePipelines.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitbucket.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitbucket.test.ts index 8d098c25..f8f62417 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitbucket.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitbucket.test.ts @@ -69,6 +69,7 @@ describe("Bitbucket Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitbucket.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -104,6 +105,7 @@ describe("Bitbucket Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitbucket.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -138,6 +140,7 @@ describe("Bitbucket Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitbucket.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -180,6 +183,7 @@ describe("Bitbucket Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitbucket.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -224,6 +228,7 @@ describe("Bitbucket Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitbucket.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitrise.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitrise.test.ts index 0cb91d3c..50ec3543 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitrise.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Bitrise.test.ts @@ -84,6 +84,7 @@ describe("Bitrise Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitrise.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -128,6 +129,7 @@ describe("Bitrise Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitrise.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -172,6 +174,7 @@ describe("Bitrise Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitrise.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -226,6 +229,7 @@ describe("Bitrise Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Bitrise.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Buildkite.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Buildkite.test.ts index 13a2191a..00e10f1d 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Buildkite.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Buildkite.test.ts @@ -68,6 +68,7 @@ describe("Buildkite Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Buildkite.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -108,6 +109,7 @@ describe("Buildkite Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Buildkite.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/CircleCI.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/CircleCI.test.ts index cda8b487..973d94e7 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/CircleCI.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/CircleCI.test.ts @@ -71,6 +71,7 @@ describe("CircleCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CircleCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -109,6 +110,7 @@ describe("CircleCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CircleCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -154,6 +156,7 @@ describe("CircleCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CircleCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Cirrus.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Cirrus.test.ts index 23761de8..84ba5d07 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Cirrus.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Cirrus.test.ts @@ -68,6 +68,7 @@ describe("Cirrus Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Cirrus.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -114,6 +115,7 @@ describe("Cirrus Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Cirrus.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/CloudflarePages.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/CloudflarePages.test.ts index c634732b..d1eca607 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/CloudflarePages.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/CloudflarePages.test.ts @@ -65,6 +65,7 @@ describe("CloudflarePages Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CloudflarePages.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -104,6 +105,7 @@ describe("CloudflarePages Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CloudflarePages.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -133,6 +135,7 @@ describe("CloudflarePages Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CloudflarePages.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/CodeBuild.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/CodeBuild.test.ts index 25ea6a35..e1b0d263 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/CodeBuild.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/CodeBuild.test.ts @@ -68,6 +68,7 @@ describe("CodeBuild Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CodeBuild.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -113,6 +114,7 @@ describe("CodeBuild Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await CodeBuild.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Drone.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Drone.test.ts index 4fecbe18..c3c72989 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Drone.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Drone.test.ts @@ -68,6 +68,7 @@ describe("Drone Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Drone.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -115,6 +116,7 @@ describe("Drone Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Drone.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -152,6 +154,7 @@ describe("Drone Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Drone.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/GitHubActions.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/GitHubActions.test.ts index 1d5525eb..cb2d06fa 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/GitHubActions.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/GitHubActions.test.ts @@ -153,6 +153,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -181,6 +182,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); @@ -244,6 +246,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); @@ -300,6 +303,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); @@ -355,6 +359,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); @@ -419,6 +424,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); @@ -459,6 +465,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); @@ -503,6 +510,7 @@ describe("GitHub Actions Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitHubActions.getServiceParams(inputs, output); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/GitLabCI.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/GitLabCI.test.ts index bdc3dd54..f7a0e41f 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/GitLabCI.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/GitLabCI.test.ts @@ -68,6 +68,7 @@ describe("GitLabCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitLabCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -105,6 +106,7 @@ describe("GitLabCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitLabCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -139,6 +141,7 @@ describe("GitLabCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitLabCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -159,6 +162,7 @@ describe("GitLabCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); it("can get the slug from http", async () => { @@ -250,6 +254,7 @@ describe("GitLabCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await GitLabCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/HerokuCI.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/HerokuCI.test.ts index 3f6c961c..183a04f9 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/HerokuCI.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/HerokuCI.test.ts @@ -67,6 +67,7 @@ describe("HerokuCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await HerokuCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -108,6 +109,7 @@ describe("HerokuCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await HerokuCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -145,6 +147,7 @@ describe("HerokuCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await HerokuCI.getServiceParams(inputs, output); expect(expected).toBeTruthy(); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/JenkinsCI.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/JenkinsCI.test.ts index eab10f89..b61f2d7f 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/JenkinsCI.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/JenkinsCI.test.ts @@ -77,6 +77,7 @@ describe("Jenkins CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await JenkinsCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -110,6 +111,7 @@ describe("Jenkins CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await JenkinsCI.getServiceParams(inputs, output); expect(params.slug).toBe("testOrg/testRepo"); @@ -149,6 +151,7 @@ describe("Jenkins CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await JenkinsCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -187,6 +190,7 @@ describe("Jenkins CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await JenkinsCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Local.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Local.test.ts index 96a08abd..62359082 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Local.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Local.test.ts @@ -69,6 +69,7 @@ describe("Local Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Local.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -107,6 +108,7 @@ describe("Local Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Local.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -125,6 +127,7 @@ describe("Local Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const spawnSync = td.replace(childProcess, "spawnSync"); await expect(Local.getServiceParams(inputs, output)).rejects.toThrow(); @@ -188,6 +191,7 @@ describe("Local Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Local.getServiceParams(inputs, output); expect(params.slug).toBe("testOrg/testRepo"); @@ -226,6 +230,7 @@ describe("Local Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); await expect(Local.getServiceParams(inputs, output)).rejects.toThrow(); }); @@ -264,6 +269,7 @@ describe("Local Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Local.getServiceParams(inputs, output); expect(params.slug).toBe("testOrg/testRepo"); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Netlify.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Netlify.test.ts index 2727ba11..db531efe 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Netlify.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Netlify.test.ts @@ -66,6 +66,7 @@ describe("Netlify Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Netlify.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -106,6 +107,7 @@ describe("Netlify Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Netlify.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -135,6 +137,7 @@ describe("Netlify Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Netlify.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Render.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Render.test.ts index 27515ddd..c1ab9e96 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Render.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Render.test.ts @@ -66,6 +66,7 @@ describe("Render Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Render.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -106,6 +107,7 @@ describe("Render Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Render.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -135,6 +137,7 @@ describe("Render Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Render.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/TeamCity.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/TeamCity.test.ts index 56728532..24621c77 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/TeamCity.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/TeamCity.test.ts @@ -73,6 +73,7 @@ describe("TeamCity Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TeamCity.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -115,6 +116,7 @@ describe("TeamCity Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TeamCity.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -164,6 +166,7 @@ describe("TeamCity Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TeamCity.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -200,6 +203,7 @@ describe("TeamCity Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TeamCity.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/TravisCI.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/TravisCI.test.ts index 54e612f2..b1bc9655 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/TravisCI.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/TravisCI.test.ts @@ -83,6 +83,7 @@ describe("TravisCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TravisCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -124,6 +125,7 @@ describe("TravisCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TravisCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -164,6 +166,7 @@ describe("TravisCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TravisCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -205,6 +208,7 @@ describe("TravisCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TravisCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -234,6 +238,7 @@ describe("TravisCI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await TravisCI.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Vercel.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Vercel.test.ts index 8caf0c53..4c92fe98 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Vercel.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Vercel.test.ts @@ -67,6 +67,7 @@ describe("Vercel Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Vercel.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -108,6 +109,7 @@ describe("Vercel Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Vercel.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -137,6 +139,7 @@ describe("Vercel Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Vercel.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Werker.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Werker.test.ts index f75f90b7..01c3a7a3 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Werker.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Werker.test.ts @@ -68,6 +68,7 @@ describe("Wercker CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Wercker.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -114,6 +115,7 @@ describe("Wercker CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Wercker.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -142,6 +144,7 @@ describe("Wercker CI Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await Wercker.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/Woodpecker.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/Woodpecker.test.ts index 97508e46..333ccb7c 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/Woodpecker.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/Woodpecker.test.ts @@ -69,6 +69,7 @@ describe("Woodpecker Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await providerWoodpecker.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -119,6 +120,7 @@ describe("Woodpecker Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await providerWoodpecker.getServiceParams(inputs, output); expect(params).toMatchObject(expected); @@ -147,6 +149,7 @@ describe("Woodpecker Params", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const params = await providerWoodpecker.getServiceParams(inputs, output); expect(params).toMatchObject(expected); diff --git a/packages/bundler-plugin-core/src/utils/providers/__tests__/index.test.ts b/packages/bundler-plugin-core/src/utils/providers/__tests__/index.test.ts index 33c34432..fa8dc384 100644 --- a/packages/bundler-plugin-core/src/utils/providers/__tests__/index.test.ts +++ b/packages/bundler-plugin-core/src/utils/providers/__tests__/index.test.ts @@ -72,6 +72,7 @@ describe("CI Providers", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const serviceParams = await provider.getServiceParams(inputs, output); @@ -100,6 +101,7 @@ describe("CI Providers", () => { dryRun: true, enableBundleAnalysis: true, retryCount: 0, + telemetry: false, }); const serviceParams = await provider.getServiceParams(inputs, output); From 4c6b2e79fb8b7485db3b45646ebece714d3a43e6 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 10:49:26 -0400 Subject: [PATCH 08/23] add in fix for next js webpack plugin not using the correct webpack --- .changeset/wise-toys-hug.md | 14 +++++++++++++ .../nextJSWebpackBundleAnalysisPlugin.ts | 21 ++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 .changeset/wise-toys-hug.md diff --git a/.changeset/wise-toys-hug.md b/.changeset/wise-toys-hug.md new file mode 100644 index 00000000..7902f1bf --- /dev/null +++ b/.changeset/wise-toys-hug.md @@ -0,0 +1,14 @@ +--- +"@codecov/nextjs-webpack-plugin": patch +"@codecov/bundler-plugin-core": patch +"@codecov/remix-vite-plugin": patch +"@codecov/solidstart-plugin": patch +"@codecov/sveltekit-plugin": patch +"@codecov/webpack-plugin": patch +"@codecov/rollup-plugin": patch +"@codecov/astro-plugin": patch +"@codecov/nuxt-plugin": patch +"@codecov/vite-plugin": patch +--- + +Fix issue not using the correct webpack in the nextjs plugin diff --git a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts index 1ccd91fc..1ee70da5 100644 --- a/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts +++ b/packages/nextjs-webpack-plugin/src/nextjs-webpack-bundle-analysis/nextJSWebpackBundleAnalysisPlugin.ts @@ -1,5 +1,5 @@ import { red, type ExtendedBAUploadPlugin } from "@codecov/bundler-plugin-core"; -import type * as webpack from "webpack"; +import type * as TWebpack from "webpack"; import { _internal_processAssets as processAssets, @@ -8,8 +8,8 @@ import { } from "@codecov/webpack-plugin"; export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ - webpack: typeof webpack | null; -}> = ({ output, pluginName, pluginVersion }) => ({ + webpack: typeof TWebpack | null; +}> = ({ output, pluginName, pluginVersion, options }) => ({ version: output.version, name: pluginName, pluginVersion, @@ -25,7 +25,7 @@ export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ }, webpack(compiler) { compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { - if (!webpack) { + if (!options.webpack) { red( "Unable to run bundle analysis, Webpack wasn't passed successfully.", ); @@ -35,9 +35,16 @@ export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ compilation.hooks.processAssets.tapPromise( { name: pluginName, - stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT, + stage: options.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT, }, async () => { + if (!options.webpack) { + red( + "Unable to run bundle analysis, Webpack wasn't passed successfully.", + ); + return; + } + output.setBundleName(output.originalBundleName); // Webpack base chunk format options: https://webpack.js.org/configuration/output/#outputchunkformat if (typeof compilation.outputOptions.chunkFormat === "string") { @@ -65,7 +72,7 @@ export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ output.bundler = { name: "webpack", - version: webpack.version, + version: options.webpack.version, }; const outputOptions = compilation.outputOptions; @@ -96,7 +103,7 @@ export const nextJSWebpackBundleAnalysisPlugin: ExtendedBAUploadPlugin<{ // only output file if running dry run if (output.dryRun) { - const { RawSource } = webpack.sources; + const { RawSource } = options.webpack.sources; compilation.emitAsset( `${output.bundleName}-stats.json`, new RawSource(output.bundleStatsToJson()), From 937c3cd10640fba619ae9b1a1dd3fcd578a9bac5 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 12:21:43 -0400 Subject: [PATCH 09/23] set owner and repo tags --- .../bundler-plugin-core/src/utils/Output.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index c56c18cd..1f26e399 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -163,7 +163,7 @@ class Output { const inputs: ProviderUtilInputs = { envs, args }; const provider = await startSpan( - { name: "detectProvider", scope: this.sentryScope }, + { name: "output.write.detectProvider", scope: this.sentryScope }, async () => { let detectedProvider; try { @@ -202,12 +202,24 @@ class Output { if (!provider) return; if (this.sentryScope) { - this.sentryScope.setTag("provider.service", provider.service); + this.sentryScope.setTag("service", provider.service); + + const slug = provider.slug ?? ""; + const repoIndex = slug.lastIndexOf("/") + 1; + const owner = slug.substring(0, repoIndex).trimEnd(); + if (owner.length > 0) { + this.sentryScope.setTag("owner", owner); + } + + const repo = slug.substring(repoIndex, slug.length); + if (repo.length > 0) { + this.sentryScope.setTag("repo", repo); + } } let url = ""; await startSpan( - { name: "getPreSignedURL", scope: this.sentryScope }, + { name: "output.write.getPreSignedURL", scope: this.sentryScope }, async () => { try { url = await getPreSignedURL({ @@ -248,7 +260,7 @@ class Output { ); await startSpan( - { name: "uploadStats", scope: this.sentryScope }, + { name: "output.write.uploadStats", scope: this.sentryScope }, async () => { try { await uploadStats({ From 8e60f723cc1dea132b9895aa6c1fc2f1ddfa1238 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 12:52:22 -0400 Subject: [PATCH 10/23] add op's to the spans --- .../src/sentry/telemetry.ts | 6 ++- .../bundler-plugin-core/src/utils/Output.ts | 21 ++++++-- .../src/utils/__tests__/Output.test.ts | 53 +++++++++++++++++++ 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/packages/bundler-plugin-core/src/sentry/telemetry.ts b/packages/bundler-plugin-core/src/sentry/telemetry.ts index c0915de5..3fca2492 100644 --- a/packages/bundler-plugin-core/src/sentry/telemetry.ts +++ b/packages/bundler-plugin-core/src/sentry/telemetry.ts @@ -152,7 +152,11 @@ export function telemetryPlugin({ "Sending telemetry data on issues and performance to Codecov. To disable telemetry, set `options.telemetry` to `false`.", ); startSpan( - { name: "Codecov Bundler Plugin execution", scope: sentryScope }, + { + name: "Codecov Bundler Plugin execution", + op: "bundler-plugin-startup", + scope: sentryScope, + }, () => { // }, diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index 1f26e399..14924273 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -163,7 +163,11 @@ class Output { const inputs: ProviderUtilInputs = { envs, args }; const provider = await startSpan( - { name: "output.write.detectProvider", scope: this.sentryScope }, + { + name: "Detect Provider", + op: "output.write.detectProvider", + scope: this.sentryScope, + }, async () => { let detectedProvider; try { @@ -206,7 +210,8 @@ class Output { const slug = provider.slug ?? ""; const repoIndex = slug.lastIndexOf("/") + 1; - const owner = slug.substring(0, repoIndex).trimEnd(); + // -1 to trim the trailing slash + const owner = slug.substring(0, repoIndex - 1).trimEnd(); if (owner.length > 0) { this.sentryScope.setTag("owner", owner); } @@ -219,7 +224,11 @@ class Output { let url = ""; await startSpan( - { name: "output.write.getPreSignedURL", scope: this.sentryScope }, + { + name: "Get Pre-Signed URL", + op: "output.write.getPreSignedURL", + scope: this.sentryScope, + }, async () => { try { url = await getPreSignedURL({ @@ -260,7 +269,11 @@ class Output { ); await startSpan( - { name: "output.write.uploadStats", scope: this.sentryScope }, + { + name: "Upload Stats", + op: "output.write.uploadStats", + scope: this.sentryScope, + }, async () => { try { await uploadStats({ diff --git a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts index 0c67b9d1..e31ea901 100644 --- a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts +++ b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts @@ -431,6 +431,59 @@ describe("Output", () => { }); }); + describe("successful detection of provider", () => { + it("sets the owner and repo tags", async () => { + setup({}); + const sentryClient = { + captureMessage: vi.fn(), + } as unknown as Client; + + const sentryScope = { + getClient: vi.fn(), + setTag: vi.fn(), + addBreadcrumb: vi.fn(), + } as unknown as Scope; + + const output = new Output( + { + apiUrl: "http://localhost", + bundleName: "output-test", + debug: false, + dryRun: false, + enableBundleAnalysis: true, + retryCount: 1, + uploadToken: "token", + telemetry: false, + }, + { sentryClient, sentryScope }, + ); + + output.start(); + output.end(); + + await output.write(); + + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryScope.setTag).toHaveBeenNthCalledWith( + 1, + "service", + "github", + ); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryScope.setTag).toHaveBeenNthCalledWith( + 2, + "owner", + "codecov", + ); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(sentryScope.setTag).toHaveBeenNthCalledWith( + 3, + "repo", + "codecov-javascript-bundler-plugins", + ); + }); + }); + describe("fails to fetch pre-signed URL", () => { it("immediately returns", async () => { setup({ urlSendError: true }); From 92352c3c2e8c6c924f3719ce8a3f0950ef892501 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 6 Dec 2024 13:05:25 -0400 Subject: [PATCH 11/23] collect some more info about meta frameworks and bundlers --- packages/astro-plugin/src/index.ts | 2 ++ .../src/sentry/__tests__/telemetry.test.ts | 22 +++++++++++++++++-- .../src/sentry/telemetry.ts | 11 ++++++++++ packages/nextjs-webpack-plugin/src/index.ts | 2 ++ packages/nuxt-plugin/src/index.ts | 2 ++ packages/remix-vite-plugin/src/index.ts | 2 ++ packages/rollup-plugin/src/index.ts | 1 + packages/solidstart-plugin/src/index.ts | 2 ++ packages/sveltekit-plugin/src/index.ts | 2 ++ packages/vite-plugin/src/index.ts | 1 + packages/webpack-plugin/src/index.ts | 1 + 11 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/astro-plugin/src/index.ts b/packages/astro-plugin/src/index.ts index fac9ae1a..d3864904 100644 --- a/packages/astro-plugin/src/index.ts +++ b/packages/astro-plugin/src/index.ts @@ -49,6 +49,8 @@ const astroPluginFactory = createVitePlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, + metaFramework: "astro", }); if (options.enableBundleAnalysis) { diff --git a/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts index 58e5f36a..3850a1c1 100644 --- a/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts +++ b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts @@ -28,6 +28,7 @@ describe("telemetry", () => { isDryRun: false, pluginName: "test-plugin", pluginVersion: "1.0.0", + bundler: "test-bundler", }); expect(sentryClient).toBeDefined(); @@ -40,6 +41,7 @@ describe("telemetry", () => { isDryRun: false, pluginName: "test-plugin", pluginVersion: "1.0.0", + bundler: "test-bundler", }); expect(sentryClient).toBeDefined(); @@ -64,7 +66,13 @@ describe("telemetry", () => { version: "1.0.0", }; - setTelemetryDataOnScope(options, pluginInfo, scope); + setTelemetryDataOnScope( + options, + pluginInfo, + scope, + "test-bundler", + "none", + ); // eslint-disable-next-line @typescript-eslint/unbound-method expect(scope.setTag).toHaveBeenCalledWith("auth_mode", "token"); @@ -74,6 +82,10 @@ describe("telemetry", () => { expect(scope.setTag).toHaveBeenCalledWith("plugin.name", "test-plugin"); // eslint-disable-next-line @typescript-eslint/unbound-method expect(scope.setTag).toHaveBeenCalledWith("plugin.version", "1.0.0"); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(scope.setTag).toHaveBeenCalledWith("bundler", "test-bundler"); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(scope.setTag).toHaveBeenCalledWith("meta_framework", "none"); }); it("sets correct tags for github OIDC auth", () => { @@ -91,7 +103,13 @@ describe("telemetry", () => { version: "1.0.0", }; - setTelemetryDataOnScope(options, pluginInfo, scope); + setTelemetryDataOnScope( + options, + pluginInfo, + scope, + "test-bundler", + "none", + ); // eslint-disable-next-line @typescript-eslint/unbound-method expect(scope.setTag).toHaveBeenCalledWith("auth_mode", "github-oidc"); diff --git a/packages/bundler-plugin-core/src/sentry/telemetry.ts b/packages/bundler-plugin-core/src/sentry/telemetry.ts index 3fca2492..25ee0869 100644 --- a/packages/bundler-plugin-core/src/sentry/telemetry.ts +++ b/packages/bundler-plugin-core/src/sentry/telemetry.ts @@ -24,6 +24,8 @@ interface CreateSentryInstanceOptions { pluginName: string; pluginVersion: string; options?: NormalizedOptions; + bundler: string; + metaFramework?: string; } export function createSentryInstance({ @@ -32,6 +34,8 @@ export function createSentryInstance({ pluginName, pluginVersion, options, + bundler, + metaFramework, }: CreateSentryInstanceOptions): { sentryScope: Scope; sentryClient: Client; @@ -86,6 +90,8 @@ export function createSentryInstance({ options, { name: pluginName, version: pluginVersion }, scope, + bundler, + metaFramework, ); } @@ -101,6 +107,8 @@ export function setTelemetryDataOnScope( options: NormalizedOptions, pluginInfo: PluginInfo, scope: Scope, + bundler: string, + metaFramework?: string, ) { scope.setTag("node", process.version); scope.setTag("platform", process.platform); @@ -121,6 +129,9 @@ export function setTelemetryDataOnScope( } scope.setTag("ci", !!process.env.CI); + + scope.setTag("meta_framework", metaFramework ?? "none"); + scope.setTag("bundler", bundler); } /** Flushing the SDK client can fail. We never want to crash the plugin because of telemetry. */ diff --git a/packages/nextjs-webpack-plugin/src/index.ts b/packages/nextjs-webpack-plugin/src/index.ts index a7c83f2d..e9da8b4e 100644 --- a/packages/nextjs-webpack-plugin/src/index.ts +++ b/packages/nextjs-webpack-plugin/src/index.ts @@ -53,6 +53,8 @@ const codecovNextJSWebpackPluginFactory = createWebpackPlugin< pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, + metaFramework: "nextjs", }); if (options.enableBundleAnalysis) { diff --git a/packages/nuxt-plugin/src/index.ts b/packages/nuxt-plugin/src/index.ts index 69587dec..8cbce097 100644 --- a/packages/nuxt-plugin/src/index.ts +++ b/packages/nuxt-plugin/src/index.ts @@ -45,6 +45,8 @@ const codecovNuxtPluginFactory = createVitePlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, + metaFramework: "nuxt", }); if (options.enableBundleAnalysis) { diff --git a/packages/remix-vite-plugin/src/index.ts b/packages/remix-vite-plugin/src/index.ts index e016559b..86b76873 100644 --- a/packages/remix-vite-plugin/src/index.ts +++ b/packages/remix-vite-plugin/src/index.ts @@ -47,6 +47,8 @@ const codecovRemixVitePluginFactory = createVitePlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, + metaFramework: "remix", }); if (options.enableBundleAnalysis) { diff --git a/packages/rollup-plugin/src/index.ts b/packages/rollup-plugin/src/index.ts index 04b4ac15..a7c8dc93 100644 --- a/packages/rollup-plugin/src/index.ts +++ b/packages/rollup-plugin/src/index.ts @@ -46,6 +46,7 @@ const codecovRollupPluginFactory = createRollupPlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, }); if (options.enableBundleAnalysis) { diff --git a/packages/solidstart-plugin/src/index.ts b/packages/solidstart-plugin/src/index.ts index 64fa90d8..36d72df4 100644 --- a/packages/solidstart-plugin/src/index.ts +++ b/packages/solidstart-plugin/src/index.ts @@ -47,6 +47,8 @@ const codecovSolidStartPluginFactory = createVitePlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, + metaFramework: "solidstart", }); if (options.enableBundleAnalysis) { diff --git a/packages/sveltekit-plugin/src/index.ts b/packages/sveltekit-plugin/src/index.ts index 11b97dbe..3a18c3d8 100644 --- a/packages/sveltekit-plugin/src/index.ts +++ b/packages/sveltekit-plugin/src/index.ts @@ -47,6 +47,8 @@ const codecovSvelteKitPluginFactory = createVitePlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, + metaFramework: "sveltekit", }); if (options.enableBundleAnalysis) { diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index 619b01fd..dec9eb07 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -46,6 +46,7 @@ const codecovVitePluginFactory = createVitePlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, }); if (options.enableBundleAnalysis) { diff --git a/packages/webpack-plugin/src/index.ts b/packages/webpack-plugin/src/index.ts index ce38c53f..dde71aef 100644 --- a/packages/webpack-plugin/src/index.ts +++ b/packages/webpack-plugin/src/index.ts @@ -53,6 +53,7 @@ const codecovWebpackPluginFactory = createWebpackPlugin( pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, options, + bundler: unpluginMetaContext.framework, }); if (options.enableBundleAnalysis) { From 83c8e0ccbb3c98e2a1045976a57d58b63f8375b4 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Mon, 9 Dec 2024 10:18:56 -0500 Subject: [PATCH 12/23] add in some more comments --- .../bundler-plugin-core/src/sentry/telemetry.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/bundler-plugin-core/src/sentry/telemetry.ts b/packages/bundler-plugin-core/src/sentry/telemetry.ts index 25ee0869..2d62c07b 100644 --- a/packages/bundler-plugin-core/src/sentry/telemetry.ts +++ b/packages/bundler-plugin-core/src/sentry/telemetry.ts @@ -40,9 +40,13 @@ export function createSentryInstance({ sentryScope: Scope; sentryClient: Client; } { + // setting to undefined will ensure that no data is sent let sampleRate = undefined; let tracesSampleRate = undefined; // just being really explicit here as to what we're checking for + // currently we're not tracking dry runs as they're more for debugging, and + // are not interacting with our systems - up for debate whether we want to + // keep this if (enableTelemetry === true && isDryRun === false) { sampleRate = 1; tracesSampleRate = 1; @@ -65,6 +69,7 @@ export function createSentryInstance({ beforeSend: (event) => { event.exception?.values?.forEach((exception) => { + // Stack track may have some PII delete exception.stacktrace; }); @@ -110,12 +115,15 @@ export function setTelemetryDataOnScope( bundler: string, metaFramework?: string, ) { + // some general information about where the plugins are being ram scope.setTag("node", process.version); scope.setTag("platform", process.platform); + // determine which plugin and it's version that's being used scope.setTag("plugin.name", pluginInfo.name); scope.setTag("plugin.version", pluginInfo.version); + // determine the method of authorization let authMode = options.dryRun ? "dry-run" : "tokenless"; if (options.uploadToken && options.uploadToken !== "") { authMode = "token"; @@ -124,12 +132,15 @@ export function setTelemetryDataOnScope( } scope.setTag("auth_mode", authMode); + // determine what git services are being used to auth with tokenless if (options.gitService) { scope.setTag("git_service", options.gitService); } + // want to see if we're mainly running in ci envs compared to local builds scope.setTag("ci", !!process.env.CI); + // track which bundlers and meta-frameworks are being used scope.setTag("meta_framework", metaFramework ?? "none"); scope.setTag("bundler", bundler); } @@ -164,8 +175,8 @@ export function telemetryPlugin({ ); startSpan( { - name: "Codecov Bundler Plugin execution", - op: "bundler-plugin-startup", + name: "Codecov Bundler Plugin Execution", + op: "bundler-plugin-execution", scope: sentryScope, }, () => { From d04efd9ac6def2882f327c6636d3ac10a5572745 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Thu, 2 Jan 2025 08:38:57 -0500 Subject: [PATCH 13/23] Update .changeset/green-goats-thank.md Co-authored-by: Lukas Stracke --- .changeset/green-goats-thank.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/green-goats-thank.md b/.changeset/green-goats-thank.md index fff3248a..f9d422f7 100644 --- a/.changeset/green-goats-thank.md +++ b/.changeset/green-goats-thank.md @@ -12,4 +12,4 @@ "@codecov/bundle-analyzer": minor --- -Add Sentry to the bundler plugins to start collecting issues and telemerty +Add Sentry to the bundler plugins to start collecting issues and telemetry From a8bfd1186b4370ab578266b2337353a7638d1e3f Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Thu, 2 Jan 2025 10:45:32 -0500 Subject: [PATCH 14/23] actually send the sentry config to the Output constructor --- packages/astro-plugin/src/index.ts | 3 +-- packages/nextjs-webpack-plugin/src/index.ts | 3 +-- packages/nuxt-plugin/src/index.ts | 2 +- packages/remix-vite-plugin/src/index.ts | 2 +- packages/rollup-plugin/src/index.ts | 2 +- packages/solidstart-plugin/src/index.ts | 2 +- packages/sveltekit-plugin/src/index.ts | 3 ++- packages/vite-plugin/src/index.ts | 2 +- packages/webpack-plugin/src/index.ts | 2 +- 9 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/astro-plugin/src/index.ts b/packages/astro-plugin/src/index.ts index d3864904..fe5a835b 100644 --- a/packages/astro-plugin/src/index.ts +++ b/packages/astro-plugin/src/index.ts @@ -42,7 +42,6 @@ const astroPluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -52,7 +51,7 @@ const astroPluginFactory = createVitePlugin( bundler: unpluginMetaContext.framework, metaFramework: "astro", }); - + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( telemetryPlugin({ diff --git a/packages/nextjs-webpack-plugin/src/index.ts b/packages/nextjs-webpack-plugin/src/index.ts index e9da8b4e..89f6fe7e 100644 --- a/packages/nextjs-webpack-plugin/src/index.ts +++ b/packages/nextjs-webpack-plugin/src/index.ts @@ -46,7 +46,6 @@ const codecovNextJSWebpackPluginFactory = createWebpackPlugin< const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -56,7 +55,7 @@ const codecovNextJSWebpackPluginFactory = createWebpackPlugin< bundler: unpluginMetaContext.framework, metaFramework: "nextjs", }); - + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( telemetryPlugin({ diff --git a/packages/nuxt-plugin/src/index.ts b/packages/nuxt-plugin/src/index.ts index 8cbce097..3fb475fb 100644 --- a/packages/nuxt-plugin/src/index.ts +++ b/packages/nuxt-plugin/src/index.ts @@ -38,7 +38,6 @@ const codecovNuxtPluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -48,6 +47,7 @@ const codecovNuxtPluginFactory = createVitePlugin( bundler: unpluginMetaContext.framework, metaFramework: "nuxt", }); + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( diff --git a/packages/remix-vite-plugin/src/index.ts b/packages/remix-vite-plugin/src/index.ts index 86b76873..de706fe6 100644 --- a/packages/remix-vite-plugin/src/index.ts +++ b/packages/remix-vite-plugin/src/index.ts @@ -40,7 +40,6 @@ const codecovRemixVitePluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -50,6 +49,7 @@ const codecovRemixVitePluginFactory = createVitePlugin( bundler: unpluginMetaContext.framework, metaFramework: "remix", }); + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( diff --git a/packages/rollup-plugin/src/index.ts b/packages/rollup-plugin/src/index.ts index a7c8dc93..707bdae2 100644 --- a/packages/rollup-plugin/src/index.ts +++ b/packages/rollup-plugin/src/index.ts @@ -39,7 +39,6 @@ const codecovRollupPluginFactory = createRollupPlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -48,6 +47,7 @@ const codecovRollupPluginFactory = createRollupPlugin( options, bundler: unpluginMetaContext.framework, }); + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( diff --git a/packages/solidstart-plugin/src/index.ts b/packages/solidstart-plugin/src/index.ts index 36d72df4..9c2b74bb 100644 --- a/packages/solidstart-plugin/src/index.ts +++ b/packages/solidstart-plugin/src/index.ts @@ -40,7 +40,6 @@ const codecovSolidStartPluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -50,6 +49,7 @@ const codecovSolidStartPluginFactory = createVitePlugin( bundler: unpluginMetaContext.framework, metaFramework: "solidstart", }); + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( diff --git a/packages/sveltekit-plugin/src/index.ts b/packages/sveltekit-plugin/src/index.ts index 3a18c3d8..f6059ae6 100644 --- a/packages/sveltekit-plugin/src/index.ts +++ b/packages/sveltekit-plugin/src/index.ts @@ -40,7 +40,7 @@ const codecovSvelteKitPluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); + const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -50,6 +50,7 @@ const codecovSvelteKitPluginFactory = createVitePlugin( bundler: unpluginMetaContext.framework, metaFramework: "sveltekit", }); + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index dec9eb07..1bb43ad4 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -39,7 +39,6 @@ const codecovVitePluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -48,6 +47,7 @@ const codecovVitePluginFactory = createVitePlugin( options, bundler: unpluginMetaContext.framework, }); + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( diff --git a/packages/webpack-plugin/src/index.ts b/packages/webpack-plugin/src/index.ts index dde71aef..1f25b937 100644 --- a/packages/webpack-plugin/src/index.ts +++ b/packages/webpack-plugin/src/index.ts @@ -46,7 +46,6 @@ const codecovWebpackPluginFactory = createWebpackPlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; - const output = new Output(options); const sentryConfig = createSentryInstance({ enableTelemetry: options.telemetry, isDryRun: options.dryRun, @@ -55,6 +54,7 @@ const codecovWebpackPluginFactory = createWebpackPlugin( options, bundler: unpluginMetaContext.framework, }); + const output = new Output(options, sentryConfig); if (options.enableBundleAnalysis) { plugins.push( From e23ed03a34406bf49d7d954382c9188d66e49986 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Mon, 6 Jan 2025 07:15:20 -0400 Subject: [PATCH 15/23] force transaction span wrapping all of output.write method --- .../bundler-plugin-core/src/utils/Output.ts | 318 +++++++++--------- 1 file changed, 165 insertions(+), 153 deletions(-) diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index 14924273..a9ca41f5 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -148,172 +148,184 @@ class Output { } async write(emitError?: boolean) { - if (this.dryRun) return; - - if (!this.bundleName || this.bundleName === "") return; - - const args: UploadOverrides = { - branch: this.branch, - build: this.build, - pr: this.pr, - sha: this.sha, - slug: this.slug, - }; - const envs = process.env; - const inputs: ProviderUtilInputs = { envs, args }; - - const provider = await startSpan( - { - name: "Detect Provider", - op: "output.write.detectProvider", - scope: this.sentryScope, - }, - async () => { - let detectedProvider; - try { - detectedProvider = await detectProvider(inputs, this); - } catch (error) { - if (this.sentryClient && this.sentryScope) { - this.sentryScope.addBreadcrumb({ - category: "output.write.detectProvider", - level: "error", - data: { error }, - }); - // this is being set as info because this could be caused by user error - this.sentryClient.captureMessage( - "Error in detectProvider", - "info", - undefined, - this.sentryScope, - ); - await safeFlushTelemetry(this.sentryClient); - } - - if (emitError) { - throw error; - } - - debug(`Error getting provider: "${error}"`, { - enabled: this.debug, - }); - return; - } - - return detectedProvider; - }, - ); - - if (!provider) return; - - if (this.sentryScope) { - this.sentryScope.setTag("service", provider.service); - - const slug = provider.slug ?? ""; - const repoIndex = slug.lastIndexOf("/") + 1; - // -1 to trim the trailing slash - const owner = slug.substring(0, repoIndex - 1).trimEnd(); - if (owner.length > 0) { - this.sentryScope.setTag("owner", owner); - } - - const repo = slug.substring(repoIndex, slug.length); - if (repo.length > 0) { - this.sentryScope.setTag("repo", repo); - } - } - - let url = ""; await startSpan( { - name: "Get Pre-Signed URL", - op: "output.write.getPreSignedURL", + name: "Output Write", + op: "output.write", scope: this.sentryScope, + forceTransaction: true, }, async () => { - try { - url = await getPreSignedURL({ - apiUrl: this.apiUrl, - uploadToken: this.uploadToken, - gitService: this.gitService, - oidc: this.oidc, - retryCount: this.retryCount, - serviceParams: provider, - }); - } catch (error) { - if (this.sentryClient && this.sentryScope) { - this.sentryScope.addBreadcrumb({ - category: "output.write.getPreSignedURL", - level: "error", - data: { error }, - }); - // only setting this as info because this could be caused by user error - this.sentryClient.captureMessage( - "Error in getPreSignedURL", - "info", - undefined, - this.sentryScope, - ); - await safeFlushTelemetry(this.sentryClient); + if (this.dryRun) return; + + if (!this.bundleName || this.bundleName === "") return; + + const args: UploadOverrides = { + branch: this.branch, + build: this.build, + pr: this.pr, + sha: this.sha, + slug: this.slug, + }; + const envs = process.env; + const inputs: ProviderUtilInputs = { envs, args }; + + const provider = await startSpan( + { + name: "Detect Provider", + op: "output.write.detectProvider", + scope: this.sentryScope, + }, + async () => { + let detectedProvider; + try { + detectedProvider = await detectProvider(inputs, this); + } catch (error) { + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.detectProvider", + level: "error", + data: { error }, + }); + // this is being set as info because this could be caused by user error + this.sentryClient.captureMessage( + "Error in detectProvider", + "info", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error getting provider: "${error}"`, { + enabled: this.debug, + }); + return; + } + + return detectedProvider; + }, + ); + + if (!provider) return; + + if (this.sentryScope) { + this.sentryScope.setTag("service", provider.service); + + const slug = provider.slug ?? ""; + const repoIndex = slug.lastIndexOf("/") + 1; + // -1 to trim the trailing slash + const owner = slug.substring(0, repoIndex - 1).trimEnd(); + if (owner.length > 0) { + this.sentryScope.setTag("owner", owner); } - if (emitError) { - throw error; + const repo = slug.substring(repoIndex, slug.length); + if (repo.length > 0) { + this.sentryScope.setTag("repo", repo); } - - debug(`Error getting pre-signed URL: "${error}"`, { - enabled: this.debug, - }); - return; } - }, - ); - await startSpan( - { - name: "Upload Stats", - op: "output.write.uploadStats", - scope: this.sentryScope, - }, - async () => { - try { - await uploadStats({ - preSignedUrl: url, - bundleName: this.bundleName, - message: this.bundleStatsToJson(), - retryCount: this?.retryCount, - }); - } catch (error) { - // this is being set as an error because this could not be caused by a user error - if (this.sentryClient && this.sentryScope) { - this.sentryScope.addBreadcrumb({ - category: "output.write.uploadStats", - level: "error", - data: { error }, - }); - this.sentryClient.captureMessage( - "Error in uploadStats", - "error", - undefined, - this.sentryScope, - ); - await safeFlushTelemetry(this.sentryClient); - } - - if (emitError) { - throw error; - } - - debug(`Error uploading stats: "${error}"`, { enabled: this.debug }); - return; + let url = ""; + await startSpan( + { + name: "Get Pre-Signed URL", + op: "output.write.getPreSignedURL", + scope: this.sentryScope, + }, + async () => { + try { + url = await getPreSignedURL({ + apiUrl: this.apiUrl, + uploadToken: this.uploadToken, + gitService: this.gitService, + oidc: this.oidc, + retryCount: this.retryCount, + serviceParams: provider, + }); + } catch (error) { + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.getPreSignedURL", + level: "error", + data: { error }, + }); + // only setting this as info because this could be caused by user error + this.sentryClient.captureMessage( + "Error in getPreSignedURL", + "info", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error getting pre-signed URL: "${error}"`, { + enabled: this.debug, + }); + return; + } + }, + ); + + await startSpan( + { + name: "Upload Stats", + op: "output.write.uploadStats", + scope: this.sentryScope, + }, + async () => { + try { + await uploadStats({ + preSignedUrl: url, + bundleName: this.bundleName, + message: this.bundleStatsToJson(), + retryCount: this?.retryCount, + }); + } catch (error) { + // this is being set as an error because this could not be caused by a user error + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.uploadStats", + level: "error", + data: { error }, + }); + this.sentryClient.captureMessage( + "Error in uploadStats", + "error", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error uploading stats: "${error}"`, { + enabled: this.debug, + }); + return; + } + }, + ); + + if (this.sentryClient) { + await safeFlushTelemetry(this.sentryClient); } + + return; }, ); - - if (this.sentryClient) { - await safeFlushTelemetry(this.sentryClient); - } - - return; } bundleStatsToJson() { From 04dcead57b7e478404334f0570671208869cd8a0 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Mon, 6 Jan 2025 10:12:23 -0400 Subject: [PATCH 16/23] default values to 0 not undefined --- packages/bundler-plugin-core/src/sentry/telemetry.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bundler-plugin-core/src/sentry/telemetry.ts b/packages/bundler-plugin-core/src/sentry/telemetry.ts index 2d62c07b..cfd73780 100644 --- a/packages/bundler-plugin-core/src/sentry/telemetry.ts +++ b/packages/bundler-plugin-core/src/sentry/telemetry.ts @@ -40,9 +40,9 @@ export function createSentryInstance({ sentryScope: Scope; sentryClient: Client; } { - // setting to undefined will ensure that no data is sent - let sampleRate = undefined; - let tracesSampleRate = undefined; + // setting to 0 will ensure that no data is sent + let sampleRate = 0; + let tracesSampleRate = 0; // just being really explicit here as to what we're checking for // currently we're not tracking dry runs as they're more for debugging, and // are not interacting with our systems - up for debate whether we want to From 63438347a937d2be5bb456d2050463a6cfc89e4f Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Mon, 6 Jan 2025 10:14:46 -0400 Subject: [PATCH 17/23] manually set the parent span --- .../bundler-plugin-core/src/utils/Output.ts | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index a9ca41f5..c9b063fd 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -148,33 +148,34 @@ class Output { } async write(emitError?: boolean) { - await startSpan( + if (this.dryRun) return; + + if (!this.bundleName || this.bundleName === "") return; + + const args: UploadOverrides = { + branch: this.branch, + build: this.build, + pr: this.pr, + sha: this.sha, + slug: this.slug, + }; + const envs = process.env; + const inputs: ProviderUtilInputs = { envs, args }; + + return await startSpan( { name: "Output Write", op: "output.write", scope: this.sentryScope, forceTransaction: true, }, - async () => { - if (this.dryRun) return; - - if (!this.bundleName || this.bundleName === "") return; - - const args: UploadOverrides = { - branch: this.branch, - build: this.build, - pr: this.pr, - sha: this.sha, - slug: this.slug, - }; - const envs = process.env; - const inputs: ProviderUtilInputs = { envs, args }; - + async (outputWriteSpan) => { const provider = await startSpan( { name: "Detect Provider", op: "output.write.detectProvider", scope: this.sentryScope, + parentSpan: outputWriteSpan, }, async () => { let detectedProvider; @@ -236,6 +237,7 @@ class Output { name: "Get Pre-Signed URL", op: "output.write.getPreSignedURL", scope: this.sentryScope, + parentSpan: outputWriteSpan, }, async () => { try { @@ -281,6 +283,7 @@ class Output { name: "Upload Stats", op: "output.write.uploadStats", scope: this.sentryScope, + parentSpan: outputWriteSpan, }, async () => { try { From 5b16c223a5642dc1e0a7897b831874c3c8151198 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Tue, 7 Jan 2025 07:31:41 -0400 Subject: [PATCH 18/23] mock out startSpan from Sentry --- .../src/utils/__tests__/Output.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts index e31ea901..ac302fd4 100644 --- a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts +++ b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts @@ -18,6 +18,15 @@ import { Output } from "../Output"; vi.mock("../provider"); +vi.mock("@sentry/core", async () => { + const original = await vi.importActual("@sentry/core"); + return { + ...original, + startSpan: (_data: unknown, callback: (...args: unknown[]) => unknown) => + callback(), + }; +}); + const mockedDetectProvider = detectProvider as Mock; afterEach(() => { @@ -436,11 +445,17 @@ describe("Output", () => { setup({}); const sentryClient = { captureMessage: vi.fn(), + getScope: vi.fn().mockReturnValue({ + clone: vi.fn(), + }), } as unknown as Client; const sentryScope = { getClient: vi.fn(), setTag: vi.fn(), + getScope: vi.fn().mockReturnValue({ + clone: vi.fn(), + }), addBreadcrumb: vi.fn(), } as unknown as Scope; From c26a9e1db5c908ec51c22cc012b3cbf2611682d7 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Tue, 7 Jan 2025 07:34:17 -0400 Subject: [PATCH 19/23] remove mocks for getScope and clone --- .../bundler-plugin-core/src/utils/__tests__/Output.test.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts index ac302fd4..666b5dd3 100644 --- a/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts +++ b/packages/bundler-plugin-core/src/utils/__tests__/Output.test.ts @@ -445,17 +445,11 @@ describe("Output", () => { setup({}); const sentryClient = { captureMessage: vi.fn(), - getScope: vi.fn().mockReturnValue({ - clone: vi.fn(), - }), } as unknown as Client; const sentryScope = { getClient: vi.fn(), setTag: vi.fn(), - getScope: vi.fn().mockReturnValue({ - clone: vi.fn(), - }), addBreadcrumb: vi.fn(), } as unknown as Scope; From 11ac6b936e8d2c58bcfc01eae94ea42593e16c5d Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Tue, 7 Jan 2025 08:03:34 -0400 Subject: [PATCH 20/23] wrap outer span in a try catch to actually throw any errors if they're thrown --- .../bundler-plugin-core/src/utils/Output.ts | 309 +++++++++--------- 1 file changed, 156 insertions(+), 153 deletions(-) diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index c9b063fd..866ee236 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -161,174 +161,177 @@ class Output { }; const envs = process.env; const inputs: ProviderUtilInputs = { envs, args }; - - return await startSpan( - { - name: "Output Write", - op: "output.write", - scope: this.sentryScope, - forceTransaction: true, - }, - async (outputWriteSpan) => { - const provider = await startSpan( - { - name: "Detect Provider", - op: "output.write.detectProvider", - scope: this.sentryScope, - parentSpan: outputWriteSpan, - }, - async () => { - let detectedProvider; - try { - detectedProvider = await detectProvider(inputs, this); - } catch (error) { - if (this.sentryClient && this.sentryScope) { - this.sentryScope.addBreadcrumb({ - category: "output.write.detectProvider", - level: "error", - data: { error }, + try { + return await startSpan( + { + name: "Output Write", + op: "output.write", + scope: this.sentryScope, + forceTransaction: true, + }, + async (outputWriteSpan) => { + const provider = await startSpan( + { + name: "Detect Provider", + op: "output.write.detectProvider", + scope: this.sentryScope, + parentSpan: outputWriteSpan, + }, + async () => { + let detectedProvider; + try { + detectedProvider = await detectProvider(inputs, this); + } catch (error) { + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.detectProvider", + level: "error", + data: { error }, + }); + // this is being set as info because this could be caused by user error + this.sentryClient.captureMessage( + "Error in detectProvider", + "info", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error getting provider: "${error}"`, { + enabled: this.debug, }); - // this is being set as info because this could be caused by user error - this.sentryClient.captureMessage( - "Error in detectProvider", - "info", - undefined, - this.sentryScope, - ); - await safeFlushTelemetry(this.sentryClient); + return; } - if (emitError) { - throw error; - } + return detectedProvider; + }, + ); - debug(`Error getting provider: "${error}"`, { - enabled: this.debug, - }); - return; - } + if (!provider) return; - return detectedProvider; - }, - ); + if (this.sentryScope) { + this.sentryScope.setTag("service", provider.service); - if (!provider) return; - - if (this.sentryScope) { - this.sentryScope.setTag("service", provider.service); + const slug = provider.slug ?? ""; + const repoIndex = slug.lastIndexOf("/") + 1; + // -1 to trim the trailing slash + const owner = slug.substring(0, repoIndex - 1).trimEnd(); + if (owner.length > 0) { + this.sentryScope.setTag("owner", owner); + } - const slug = provider.slug ?? ""; - const repoIndex = slug.lastIndexOf("/") + 1; - // -1 to trim the trailing slash - const owner = slug.substring(0, repoIndex - 1).trimEnd(); - if (owner.length > 0) { - this.sentryScope.setTag("owner", owner); + const repo = slug.substring(repoIndex, slug.length); + if (repo.length > 0) { + this.sentryScope.setTag("repo", repo); + } } - const repo = slug.substring(repoIndex, slug.length); - if (repo.length > 0) { - this.sentryScope.setTag("repo", repo); - } - } - - let url = ""; - await startSpan( - { - name: "Get Pre-Signed URL", - op: "output.write.getPreSignedURL", - scope: this.sentryScope, - parentSpan: outputWriteSpan, - }, - async () => { - try { - url = await getPreSignedURL({ - apiUrl: this.apiUrl, - uploadToken: this.uploadToken, - gitService: this.gitService, - oidc: this.oidc, - retryCount: this.retryCount, - serviceParams: provider, - }); - } catch (error) { - if (this.sentryClient && this.sentryScope) { - this.sentryScope.addBreadcrumb({ - category: "output.write.getPreSignedURL", - level: "error", - data: { error }, + let url = ""; + await startSpan( + { + name: "Get Pre-Signed URL", + op: "output.write.getPreSignedURL", + scope: this.sentryScope, + parentSpan: outputWriteSpan, + }, + async () => { + try { + url = await getPreSignedURL({ + apiUrl: this.apiUrl, + uploadToken: this.uploadToken, + gitService: this.gitService, + oidc: this.oidc, + retryCount: this.retryCount, + serviceParams: provider, }); - // only setting this as info because this could be caused by user error - this.sentryClient.captureMessage( - "Error in getPreSignedURL", - "info", - undefined, - this.sentryScope, - ); - await safeFlushTelemetry(this.sentryClient); - } - - if (emitError) { - throw error; - } - - debug(`Error getting pre-signed URL: "${error}"`, { - enabled: this.debug, - }); - return; - } - }, - ); - - await startSpan( - { - name: "Upload Stats", - op: "output.write.uploadStats", - scope: this.sentryScope, - parentSpan: outputWriteSpan, - }, - async () => { - try { - await uploadStats({ - preSignedUrl: url, - bundleName: this.bundleName, - message: this.bundleStatsToJson(), - retryCount: this?.retryCount, - }); - } catch (error) { - // this is being set as an error because this could not be caused by a user error - if (this.sentryClient && this.sentryScope) { - this.sentryScope.addBreadcrumb({ - category: "output.write.uploadStats", - level: "error", - data: { error }, + } catch (error) { + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.getPreSignedURL", + level: "error", + data: { error }, + }); + // only setting this as info because this could be caused by user error + this.sentryClient.captureMessage( + "Error in getPreSignedURL", + "info", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error getting pre-signed URL: "${error}"`, { + enabled: this.debug, }); - this.sentryClient.captureMessage( - "Error in uploadStats", - "error", - undefined, - this.sentryScope, - ); - await safeFlushTelemetry(this.sentryClient); + return; } - - if (emitError) { - throw error; + }, + ); + + await startSpan( + { + name: "Upload Stats", + op: "output.write.uploadStats", + scope: this.sentryScope, + parentSpan: outputWriteSpan, + }, + async () => { + try { + await uploadStats({ + preSignedUrl: url, + bundleName: this.bundleName, + message: this.bundleStatsToJson(), + retryCount: this?.retryCount, + }); + } catch (error) { + // this is being set as an error because this could not be caused by a user error + if (this.sentryClient && this.sentryScope) { + this.sentryScope.addBreadcrumb({ + category: "output.write.uploadStats", + level: "error", + data: { error }, + }); + this.sentryClient.captureMessage( + "Error in uploadStats", + "error", + undefined, + this.sentryScope, + ); + await safeFlushTelemetry(this.sentryClient); + } + + if (emitError) { + throw error; + } + + debug(`Error uploading stats: "${error}"`, { + enabled: this.debug, + }); + return; } + }, + ); - debug(`Error uploading stats: "${error}"`, { - enabled: this.debug, - }); - return; - } - }, - ); - - if (this.sentryClient) { - await safeFlushTelemetry(this.sentryClient); - } + if (this.sentryClient) { + await safeFlushTelemetry(this.sentryClient); + } - return; - }, - ); + return; + }, + ); + } catch (error) { + throw error; + } } bundleStatsToJson() { From e5ba3ccc38d6aa61335feb04f395d4032c706cf0 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Tue, 7 Jan 2025 08:25:32 -0400 Subject: [PATCH 21/23] bring back early returns if no provider or upload url --- packages/bundler-plugin-core/src/utils/Output.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index 866ee236..28247967 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -212,6 +212,7 @@ class Output { }, ); + // early return if no provider if (!provider) return; if (this.sentryScope) { @@ -231,8 +232,7 @@ class Output { } } - let url = ""; - await startSpan( + const presignedURL = await startSpan( { name: "Get Pre-Signed URL", op: "output.write.getPreSignedURL", @@ -240,6 +240,7 @@ class Output { parentSpan: outputWriteSpan, }, async () => { + let url = ""; try { url = await getPreSignedURL({ apiUrl: this.apiUrl, @@ -275,9 +276,14 @@ class Output { }); return; } + + return url; }, ); + // early return if no url + if (!presignedURL || presignedURL === "") return; + await startSpan( { name: "Upload Stats", @@ -288,7 +294,7 @@ class Output { async () => { try { await uploadStats({ - preSignedUrl: url, + preSignedUrl: presignedURL, bundleName: this.bundleName, message: this.bundleStatsToJson(), retryCount: this?.retryCount, From e31749adb9c0ae9182b1061ec3401fee5b436c91 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Wed, 8 Jan 2025 08:09:01 -0400 Subject: [PATCH 22/23] add in emitError wrapper --- packages/bundler-plugin-core/src/utils/Output.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/bundler-plugin-core/src/utils/Output.ts b/packages/bundler-plugin-core/src/utils/Output.ts index 28247967..033bbaa0 100644 --- a/packages/bundler-plugin-core/src/utils/Output.ts +++ b/packages/bundler-plugin-core/src/utils/Output.ts @@ -336,7 +336,9 @@ class Output { }, ); } catch (error) { - throw error; + if (emitError) { + throw error; + } } } From e167fcb7bb6e45e1cf51a8bca64b2bdb671d9058 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Wed, 8 Jan 2025 08:16:01 -0400 Subject: [PATCH 23/23] use common naming for telemetry --- packages/astro-plugin/src/index.ts | 4 ++-- .../src/sentry/__tests__/telemetry.test.ts | 8 ++++---- .../bundler-plugin-core/src/sentry/telemetry.ts | 14 +++++++------- packages/nextjs-webpack-plugin/src/index.ts | 8 +++----- packages/nuxt-plugin/src/index.ts | 4 ++-- packages/remix-vite-plugin/src/index.ts | 4 ++-- packages/rollup-plugin/src/index.ts | 4 ++-- packages/solidstart-plugin/src/index.ts | 4 ++-- packages/sveltekit-plugin/src/index.ts | 4 ++-- packages/vite-plugin/src/index.ts | 4 ++-- packages/webpack-plugin/src/index.ts | 4 ++-- 11 files changed, 30 insertions(+), 32 deletions(-) diff --git a/packages/astro-plugin/src/index.ts b/packages/astro-plugin/src/index.ts index fe5a835b..eb51dce4 100644 --- a/packages/astro-plugin/src/index.ts +++ b/packages/astro-plugin/src/index.ts @@ -43,7 +43,7 @@ const astroPluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -57,7 +57,7 @@ const astroPluginFactory = createVitePlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), astroBundleAnalysisPlugin({ output, diff --git a/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts index 3850a1c1..5e386d47 100644 --- a/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts +++ b/packages/bundler-plugin-core/src/sentry/__tests__/telemetry.test.ts @@ -24,7 +24,7 @@ describe("telemetry", () => { describe("createSentryInstance", () => { it("creates instance with telemetry enabled", () => { const { sentryClient, sentryScope } = createSentryInstance({ - enableTelemetry: true, + telemetry: true, isDryRun: false, pluginName: "test-plugin", pluginVersion: "1.0.0", @@ -37,7 +37,7 @@ describe("telemetry", () => { it("creates instance with telemetry disabled", () => { const { sentryClient, sentryScope } = createSentryInstance({ - enableTelemetry: false, + telemetry: false, isDryRun: false, pluginName: "test-plugin", pluginVersion: "1.0.0", @@ -151,7 +151,7 @@ describe("telemetry", () => { const plugin = telemetryPlugin({ sentryClient: client, sentryScope: scope, - shouldSendTelemetry: true, + telemetry: true, }); // @ts-expect-error: buildStart is not defined in the type @@ -174,7 +174,7 @@ describe("telemetry", () => { const plugin = telemetryPlugin({ sentryClient: client, sentryScope: scope, - shouldSendTelemetry: false, + telemetry: false, }); // @ts-expect-error: buildStart is not defined in the type diff --git a/packages/bundler-plugin-core/src/sentry/telemetry.ts b/packages/bundler-plugin-core/src/sentry/telemetry.ts index cfd73780..610dcd6a 100644 --- a/packages/bundler-plugin-core/src/sentry/telemetry.ts +++ b/packages/bundler-plugin-core/src/sentry/telemetry.ts @@ -19,7 +19,7 @@ import { cyan } from "../utils/logging"; const stackParser = createStackParser(nodeStackLineParser()); interface CreateSentryInstanceOptions { - enableTelemetry: boolean; + telemetry: boolean; isDryRun: boolean; pluginName: string; pluginVersion: string; @@ -29,7 +29,7 @@ interface CreateSentryInstanceOptions { } export function createSentryInstance({ - enableTelemetry, + telemetry, isDryRun, pluginName, pluginVersion, @@ -47,7 +47,7 @@ export function createSentryInstance({ // currently we're not tracking dry runs as they're more for debugging, and // are not interacting with our systems - up for debate whether we want to // keep this - if (enableTelemetry === true && isDryRun === false) { + if (telemetry === true && isDryRun === false) { sampleRate = 1; tracesSampleRate = 1; } @@ -83,7 +83,7 @@ export function createSentryInstance({ }, // We create a transport that stalls sending events until we know that we're allowed to - transport: makeOptionallyEnabledNodeTransport(enableTelemetry), + transport: makeOptionallyEnabledNodeTransport(telemetry), }; const client = new ServerRuntimeClient(clientOptions); @@ -158,18 +158,18 @@ export async function safeFlushTelemetry(sentryClient: Client) { interface TelemetryPluginOptions { sentryClient: Client; sentryScope: Scope; - shouldSendTelemetry: boolean; + telemetry: boolean; } export function telemetryPlugin({ sentryClient, sentryScope, - shouldSendTelemetry, + telemetry, }: TelemetryPluginOptions): UnpluginOptions { return { name: "codecov-telemetry-plugin", async buildStart() { - if (shouldSendTelemetry) { + if (telemetry) { cyan( "Sending telemetry data on issues and performance to Codecov. To disable telemetry, set `options.telemetry` to `false`.", ); diff --git a/packages/nextjs-webpack-plugin/src/index.ts b/packages/nextjs-webpack-plugin/src/index.ts index 89f6fe7e..5405283c 100644 --- a/packages/nextjs-webpack-plugin/src/index.ts +++ b/packages/nextjs-webpack-plugin/src/index.ts @@ -47,7 +47,7 @@ const codecovNextJSWebpackPluginFactory = createWebpackPlugin< const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -61,13 +61,11 @@ const codecovNextJSWebpackPluginFactory = createWebpackPlugin< telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), nextJSWebpackBundleAnalysisPlugin({ output, - options: { - webpack: userOptions.webpack, - }, + options: { webpack: userOptions.webpack }, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, }), diff --git a/packages/nuxt-plugin/src/index.ts b/packages/nuxt-plugin/src/index.ts index 3fb475fb..d1130262 100644 --- a/packages/nuxt-plugin/src/index.ts +++ b/packages/nuxt-plugin/src/index.ts @@ -39,7 +39,7 @@ const codecovNuxtPluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -54,7 +54,7 @@ const codecovNuxtPluginFactory = createVitePlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), nuxtBundleAnalysisPlugin({ output, diff --git a/packages/remix-vite-plugin/src/index.ts b/packages/remix-vite-plugin/src/index.ts index de706fe6..1f43145c 100644 --- a/packages/remix-vite-plugin/src/index.ts +++ b/packages/remix-vite-plugin/src/index.ts @@ -41,7 +41,7 @@ const codecovRemixVitePluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -56,7 +56,7 @@ const codecovRemixVitePluginFactory = createVitePlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), remixBundleAnalysisPlugin({ output, diff --git a/packages/rollup-plugin/src/index.ts b/packages/rollup-plugin/src/index.ts index 707bdae2..c11aae0d 100644 --- a/packages/rollup-plugin/src/index.ts +++ b/packages/rollup-plugin/src/index.ts @@ -40,7 +40,7 @@ const codecovRollupPluginFactory = createRollupPlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -54,7 +54,7 @@ const codecovRollupPluginFactory = createRollupPlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), rollupBundleAnalysisPlugin({ output, diff --git a/packages/solidstart-plugin/src/index.ts b/packages/solidstart-plugin/src/index.ts index 9c2b74bb..06b5e299 100644 --- a/packages/solidstart-plugin/src/index.ts +++ b/packages/solidstart-plugin/src/index.ts @@ -41,7 +41,7 @@ const codecovSolidStartPluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -56,7 +56,7 @@ const codecovSolidStartPluginFactory = createVitePlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), solidstartBundleAnalysisPlugin({ output, diff --git a/packages/sveltekit-plugin/src/index.ts b/packages/sveltekit-plugin/src/index.ts index f6059ae6..d34bb76a 100644 --- a/packages/sveltekit-plugin/src/index.ts +++ b/packages/sveltekit-plugin/src/index.ts @@ -42,7 +42,7 @@ const codecovSvelteKitPluginFactory = createVitePlugin( const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -57,7 +57,7 @@ const codecovSvelteKitPluginFactory = createVitePlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), sveltekitBundleAnalysisPlugin({ output, diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index 1bb43ad4..63d4cbd4 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -40,7 +40,7 @@ const codecovVitePluginFactory = createVitePlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -54,7 +54,7 @@ const codecovVitePluginFactory = createVitePlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), viteBundleAnalysisPlugin({ output, diff --git a/packages/webpack-plugin/src/index.ts b/packages/webpack-plugin/src/index.ts index 1f25b937..36bdc0e5 100644 --- a/packages/webpack-plugin/src/index.ts +++ b/packages/webpack-plugin/src/index.ts @@ -47,7 +47,7 @@ const codecovWebpackPluginFactory = createWebpackPlugin( const plugins: UnpluginOptions[] = []; const options = normalizedOptions.options; const sentryConfig = createSentryInstance({ - enableTelemetry: options.telemetry, + telemetry: options.telemetry, isDryRun: options.dryRun, pluginName: PLUGIN_NAME, pluginVersion: PLUGIN_VERSION, @@ -61,7 +61,7 @@ const codecovWebpackPluginFactory = createWebpackPlugin( telemetryPlugin({ sentryClient: sentryConfig.sentryClient, sentryScope: sentryConfig.sentryScope, - shouldSendTelemetry: options.telemetry, + telemetry: options.telemetry, }), webpackBundleAnalysisPlugin({ output,