Skip to content

Commit

Permalink
Merge pull request #38 from DataDog/marcosaia/RUM-4060/fix-datadog-ci…
Browse files Browse the repository at this point in the history
…-path

[RUM-4060] Fix datadog-ci path resolving on iOS scripts
  • Loading branch information
marco-saia-datadog authored Jun 12, 2024
2 parents 8b901b1 + f19acf0 commit dc2ea2e
Show file tree
Hide file tree
Showing 14 changed files with 91 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`withIosSourcemaps on pristine project adds script to upload sourcemaps to Datadog 1`] = `""if [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\nexport SOURCEMAP_FILE=$DERIVED_FILE_DIR/main.jsbundle.map\\n \\n\\nif [[ -z \\"$DATADOG_CI_EXEC\\" ]]; then\\n DATADOG_CI_EXEC=\\"$(\\"$NODE_BINARY\\" --print \\"require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')\\")\\";\\n \\n # Check if the file exists and is executable\\n if [[ -x \\"$DATADOG_CI_EXEC\\" ]]; then\\n export DATADOG_CI_EXEC;\\n else\\n echo \\"Error: DATADOG_CI_EXEC does not exist or is not executable\\";\\n exit 1;\\n fi\\nfi\\n\\n\\n$DATADOG_CI_EXEC react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n\\n\\n""`;

exports[`withIosSourcemaps on pristine project adds script to upload sourcemaps to Datadog with custom service name 1`] = `""if [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\nexport SOURCEMAP_FILE=$DERIVED_FILE_DIR/main.jsbundle.map\\n \\n\\nif [[ -z \\"$DATADOG_CI_EXEC\\" ]]; then\\n DATADOG_CI_EXEC=\\"$(\\"$NODE_BINARY\\" --print \\"require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')\\")\\";\\n \\n # Check if the file exists and is executable\\n if [[ -x \\"$DATADOG_CI_EXEC\\" ]]; then\\n export DATADOG_CI_EXEC;\\n else\\n echo \\"Error: DATADOG_CI_EXEC does not exist or is not executable\\";\\n exit 1;\\n fi\\nfi\\n\\n\\n$DATADOG_CI_EXEC react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n --service com.company.app\\n\\n""`;

exports[`withIosSourcemaps on projects implementing Sentry adds script to upload sourcemaps to Datadog 1`] = `""export SENTRY_PROPERTIES=sentry.properties\\nexport EXTRA_PACKAGER_ARGS=\\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\\"\\nif [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\n\`node --print \\"require.resolve('@sentry/cli/package.json').slice(0, -13) + '/bin/sentry-cli'\\"\` react-native xcode --force-foreground \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n\\n\\n \\n\\nif [[ -z \\"$DATADOG_CI_EXEC\\" ]]; then\\n DATADOG_CI_EXEC=\\"$(\\"$NODE_BINARY\\" --print \\"require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')\\")\\";\\n \\n # Check if the file exists and is executable\\n if [[ -x \\"$DATADOG_CI_EXEC\\" ]]; then\\n export DATADOG_CI_EXEC;\\n else\\n echo \\"Error: DATADOG_CI_EXEC does not exist or is not executable\\";\\n exit 1;\\n fi\\nfi\\n\\n\\n$DATADOG_CI_EXEC react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n""`;

exports[`withIosSourcemaps on projects implementing Sentry adds script to upload sourcemaps to Datadog with custom service name 1`] = `""export SENTRY_PROPERTIES=sentry.properties\\nexport EXTRA_PACKAGER_ARGS=\\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\\"\\nif [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\n\`node --print \\"require.resolve('@sentry/cli/package.json').slice(0, -13) + '/bin/sentry-cli'\\"\` react-native xcode --force-foreground \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n\\n\\n \\n\\nif [[ -z \\"$DATADOG_CI_EXEC\\" ]]; then\\n DATADOG_CI_EXEC=\\"$(\\"$NODE_BINARY\\" --print \\"require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')\\")\\";\\n \\n # Check if the file exists and is executable\\n if [[ -x \\"$DATADOG_CI_EXEC\\" ]]; then\\n export DATADOG_CI_EXEC;\\n else\\n echo \\"Error: DATADOG_CI_EXEC does not exist or is not executable\\";\\n exit 1;\\n fi\\nfi\\n\\n\\n$DATADOG_CI_EXEC react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n --service com.company.app""`;
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const ALL_PLUGINS = [
describe("getErrorTrackingPluginsFromOptions", () => {
it("returns all plugins if no option is provided", () => {
expect(getErrorTrackingPluginsFromOptions()).toHaveLength(
ALL_PLUGINS.length,
ALL_PLUGINS.length
);
});

Expand All @@ -31,7 +31,7 @@ describe("getErrorTrackingPluginsFromOptions", () => {
getErrorTrackingPluginsFromOptions({
iosDsyms: true,
androidProguardMappingFiles: false,
}).length,
}).length
).toEqual(ALL_PLUGINS.filter((_, index) => index !== 3).length);
});
});
8 changes: 4 additions & 4 deletions src/plugin/__tests__/withAndroidConfiguration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

import { withAppBuildGradle } from "@expo/config-plugins";

import buildGradle from "./__fixtures__/build.gradle";
import withAndroidConfiguration from "../withAndroidConfiguration/withAndroidConfiguration";
import buildGradle from "./__fixtures__/build.gradle";

jest.mock("@expo/config-plugins", () => {
return {
Expand Down Expand Up @@ -46,10 +46,10 @@ describe("withAndroidConfiguration", () => {
it("adds a datadog config block", async () => {
mockAppBuildGradle(buildGradle);
const result = (await withAndroidConfiguration({})(
createFakeConfig(),
createFakeConfig()
)) as any;
expect(result.modResults.contents).toMatch(
'id("com.datadoghq.dd-sdk-android-gradle-plugin") version "1.14.0"',
'id("com.datadoghq.dd-sdk-android-gradle-plugin") version "1.14.0"'
);
expect(result.modResults.contents).toMatchSnapshot();
});
Expand All @@ -70,7 +70,7 @@ describe("withAndroidConfiguration", () => {
datadogGradlePluginVersion: "1.9.0",
})(createFakeConfig())) as any;
expect(result.modResults.contents).toMatch(
'id("com.datadoghq.dd-sdk-android-gradle-plugin") version "1.9.0"',
'id("com.datadoghq.dd-sdk-android-gradle-plugin") version "1.9.0"'
);
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/plugin/__tests__/withAndroidSourcemaps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

import { withAppBuildGradle } from "@expo/config-plugins";

import buildGradle from "./__fixtures__/build.gradle";
import withAndroidSourcemaps from "../withAndroidSourcemaps/withAndroidSourcemaps";
import buildGradle from "./__fixtures__/build.gradle";

jest.mock("@expo/config-plugins", () => {
return {
Expand Down
18 changes: 5 additions & 13 deletions src/plugin/__tests__/withIosSourcemaps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

import { withXcodeProject } from "@expo/config-plugins";

import withIosSourcemaps from "../withIosSourcemaps/withIosSourcemaps";
import pristineProject from "./__fixtures__/pristineProjectPbxproj.json";
import sentryProject from "./__fixtures__/sentryProjectPbxproj.json";
import withIosSourcemaps from "../withIosSourcemaps/withIosSourcemaps";

jest.mock("@expo/config-plugins", () => {
return {
Expand Down Expand Up @@ -49,36 +49,28 @@ describe("withIosSourcemaps", () => {
it("adds script to upload sourcemaps to Datadog", async () => {
mockXcodeProject(pristineProject);
const result = (await withIosSourcemaps({})(createFakeConfig())) as any;
expect(result.xcodeProject.shellScript).toMatchInlineSnapshot(
`""if [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\nexport SOURCEMAP_FILE=$DERIVED_FILE_DIR/main.jsbundle.map\\n ../node_modules/.bin/datadog-ci react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n\\n""`,
);
expect(result.xcodeProject.shellScript).toMatchSnapshot();
});
it("adds script to upload sourcemaps to Datadog with custom service name", async () => {
mockXcodeProject(pristineProject);
const result = (await withIosSourcemaps({
serviceName: "com.company.app",
})(createFakeConfig())) as any;
expect(result.xcodeProject.shellScript).toMatchInlineSnapshot(
`""if [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\nexport SOURCEMAP_FILE=$DERIVED_FILE_DIR/main.jsbundle.map\\n ../node_modules/.bin/datadog-ci react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\` --service com.company.app\\n\\n""`,
);
expect(result.xcodeProject.shellScript).toMatchSnapshot();
});
});
describe("on projects implementing Sentry", () => {
it("adds script to upload sourcemaps to Datadog", async () => {
mockXcodeProject(sentryProject);
const result = (await withIosSourcemaps({})(createFakeConfig())) as any;
expect(result.xcodeProject.shellScript).toMatchInlineSnapshot(
`""export SENTRY_PROPERTIES=sentry.properties\\nexport EXTRA_PACKAGER_ARGS=\\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\\"\\nif [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\n\`node --print \\"require.resolve('@sentry/cli/package.json').slice(0, -13) + '/bin/sentry-cli'\\"\` react-native xcode --force-foreground \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n\\n\\n ../node_modules/.bin/datadog-ci react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`""`,
);
expect(result.xcodeProject.shellScript).toMatchSnapshot();
});
it("adds script to upload sourcemaps to Datadog with custom service name", async () => {
mockXcodeProject(sentryProject);
const result = (await withIosSourcemaps({
serviceName: "com.company.app",
})(createFakeConfig())) as any;
expect(result.xcodeProject.shellScript).toMatchInlineSnapshot(
`""export SENTRY_PROPERTIES=sentry.properties\\nexport EXTRA_PACKAGER_ARGS=\\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\\"\\nif [[ -f \\"$PODS_ROOT/../.xcode.env\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env\\"\\nfi\\nif [[ -f \\"$PODS_ROOT/../.xcode.env.local\\" ]]; then\\n source \\"$PODS_ROOT/../.xcode.env.local\\"\\nfi\\n\\n# The project root by default is one level up from the ios directory\\nexport PROJECT_ROOT=\\"$PROJECT_DIR\\"/..\\n\\nif [[ \\"$CONFIGURATION\\" = *Debug* ]]; then\\n export SKIP_BUNDLING=1\\nfi\\n\`node --print \\"require.resolve('@sentry/cli/package.json').slice(0, -13) + '/bin/sentry-cli'\\"\` react-native xcode --force-foreground \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\`\\n\\n\\n ../node_modules/.bin/datadog-ci react-native xcode \`\\"$NODE_BINARY\\" --print \\"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\\"\` --service com.company.app""`,
);
expect(result.xcodeProject.shellScript).toMatchSnapshot();
});
});
});
2 changes: 2 additions & 0 deletions src/plugin/common/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const DEFAULT_DATADOG_GRADLE_PLUGIN_VERSION = "1.14.0";
export const IOS_DSYMS_BUILD_PHASE_NAME = "Upload dSYMs to Datadog";
16 changes: 16 additions & 0 deletions src/plugin/common/exports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const IOS_SOURCEMAP_FILE_EXPORT =
"export SOURCEMAP_FILE=$DERIVED_FILE_DIR/main.jsbundle.map";

export const IOS_DATADOG_CI_EXPORT = `
if [[ -z "$DATADOG_CI_EXEC" ]]; then
DATADOG_CI_EXEC="$("$NODE_BINARY" --print "require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')")";
# Check if the file exists and is executable
if [[ -x "$DATADOG_CI_EXEC" ]]; then
export DATADOG_CI_EXEC;
else
echo "Error: DATADOG_CI_EXEC does not exist or is not executable";
exit 1;
fi
fi
`;
6 changes: 6 additions & 0 deletions src/plugin/common/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const escapeStringForIOSBuildPhase = (str: string) => {
return str
.replace(/\\/g, "\\\\") // Escape backslashes
.replace(/"/g, '\\"') // Escape double quotes
.replace(/\n/g, "\\n"); // Replace newlines with \n
};
4 changes: 2 additions & 2 deletions src/plugin/getErrorTrackingPluginsFromOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export type ErrorTrackingOptions = FileUploadOptions &
* to `false`.
*/
export const getErrorTrackingPluginsFromOptions = (
options?: ErrorTrackingOptions,
options?: ErrorTrackingOptions
): (ConfigPlugin<any> | StaticPlugin<any>)[] => {
const ERROR_TRACKING_CONFIG_PLUGINS_MAP: Record<
keyof FileUploadOptions,
Expand All @@ -73,7 +73,7 @@ export const getErrorTrackingPluginsFromOptions = (

const configPluginsKeys = (
Object.keys(
ERROR_TRACKING_CONFIG_PLUGINS_MAP,
ERROR_TRACKING_CONFIG_PLUGINS_MAP
) as (keyof FileUploadOptions)[]
).filter((option) => !options || options[option] !== false);

Expand Down
2 changes: 1 addition & 1 deletion src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type PluginConfiguration =
const withDatadog: ConfigPlugin<PluginConfiguration> = (config, options) => {
return withPlugins(
config,
getErrorTrackingPluginsFromOptions(options && options.errorTracking),
getErrorTrackingPluginsFromOptions(options && options.errorTracking)
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@
import type { ConfigPlugin } from "@expo/config-plugins";
import { withAppBuildGradle } from "@expo/config-plugins";

import { DEFAULT_DATADOG_GRADLE_PLUGIN_VERSION } from "../common/config";
import {
AndroidProguardMappingFilesOptions,
SourceMapUploadOptions,
} from "../getErrorTrackingPluginsFromOptions";

const DEFAULT_DATADOG_GRADLE_PLUGIN_VERSION = "1.14.0";

const withAndroidConfiguration =
(
options: SourceMapUploadOptions & AndroidProguardMappingFilesOptions,
options: SourceMapUploadOptions & AndroidProguardMappingFilesOptions
): ConfigPlugin<void> =>
(config) => {
return withAppBuildGradle(config, async (config) => {
Expand Down
4 changes: 2 additions & 2 deletions src/plugin/withAndroidSourcemaps/withAndroidSourcemaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const withAndroidSourcemaps: ConfigPlugin<void> = (config) => {
appBuildGradle.contents = appBuildGradle.contents.replace(
/apply plugin: "com\.facebook\.react"/,
`apply plugin: "com.facebook.react"\napply from: "${require("path").dirname(
require.resolve("@datadog/mobile-react-native/package.json"),
)}/datadog-sourcemaps.gradle"`,
require.resolve("@datadog/mobile-react-native/package.json")
)}/datadog-sourcemaps.gradle"`
);

return config;
Expand Down
28 changes: 22 additions & 6 deletions src/plugin/withIosDsyms/withIosDsyms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
import type { ConfigPlugin } from "@expo/config-plugins";
import { withXcodeProject } from "@expo/config-plugins";

const BUILD_PHASE_NAME = "Upload dSYMs to Datadog";
import { IOS_DSYMS_BUILD_PHASE_NAME } from "../common/config";
import { IOS_DATADOG_CI_EXPORT } from "../common/exports";

const withIosDsyms: ConfigPlugin<void> = (config) => {
return withXcodeProject(config, async (config) => {
const xcodeProject = config.modResults;
const buildPhase = xcodeProject.pbxItemByComment(
BUILD_PHASE_NAME,
"PBXShellScriptBuildPhase",
IOS_DSYMS_BUILD_PHASE_NAME,
"PBXShellScriptBuildPhase"
);
if (buildPhase) {
return config;
Expand All @@ -23,12 +24,27 @@ const withIosDsyms: ConfigPlugin<void> = (config) => {
xcodeProject.addBuildPhase(
[],
"PBXShellScriptBuildPhase",
BUILD_PHASE_NAME,
IOS_DSYMS_BUILD_PHASE_NAME,
null /* target */,
{
shellScript: `set -e\\n ../node_modules/.bin/datadog-ci dsyms upload $DWARF_DSYM_FOLDER_PATH`,
shellScript: `set -e
if [[ -f "$PODS_ROOT/../.xcode.env" ]]; then
source "$PODS_ROOT/../.xcode.env"
fi
if [[ -f "$PODS_ROOT/../.xcode.env.local" ]]; then
source "$PODS_ROOT/../.xcode.env.local"
fi
if [[ -z "$NODE_BINARY" ]]; then
echo "ERROR: NODE_BINARY env variable is not set"
fi
${IOS_DATADOG_CI_EXPORT}
$DATADOG_CI_EXEC dsyms upload $DWARF_DSYM_FOLDER_PATH
`,
shellPath: "/bin/sh",
},
}
);

return config;
Expand Down
Loading

0 comments on commit dc2ea2e

Please sign in to comment.