Skip to content

Commit

Permalink
Improved datadog-ci command safety
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-saia-datadog committed Jun 12, 2024
1 parent effe4c2 commit b162e20
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 61 deletions.
48 changes: 4 additions & 44 deletions src/plugin/__tests__/__snapshots__/withIosSourcemaps.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,49 +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
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""`;

if [[ -z "$DATADOG_CI_EXEC" ]]; then
export DATADOG_CI_EXEC="$("$NODE_BINARY" --print "require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')")"
fi
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""`;

$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""
`;

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
if [[ -z "$DATADOG_CI_EXEC" ]]; then
export DATADOG_CI_EXEC="$("$NODE_BINARY" --print "require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')")"
fi
$DATADOG_CI_EXEC 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""
`;

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
if [[ -z "$DATADOG_CI_EXEC" ]]; then
export DATADOG_CI_EXEC="$("$NODE_BINARY" --print "require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')")"
fi
$DATADOG_CI_EXEC react-native xcode \`"$NODE_BINARY" --print "require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'"\`
""
`;

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
if [[ -z "$DATADOG_CI_EXEC" ]]; then
export DATADOG_CI_EXEC="$("$NODE_BINARY" --print "require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')")"
fi
$DATADOG_CI_EXEC react-native xcode \`"$NODE_BINARY" --print "require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'"\`
--service com.company.app""
`;
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""`;
11 changes: 10 additions & 1 deletion src/plugin/common/exports.ts
Original file line number Diff line number Diff line change
@@ -1,7 +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
export DATADOG_CI_EXEC="$("$NODE_BINARY" --print "require('path').resolve(require('path').dirname(require.resolve('@datadog/datadog-ci/package.json')), '../../.bin/datadog-ci')")"
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
`;
10 changes: 10 additions & 0 deletions src/plugin/common/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const escapeStringForIOSBuildPhase = (str: string) => {
return (
str
.replace(/\\/g, "\\\\") // Escape backslashes
.replace(/"/g, '\\"') // Escape double quotes
// .replace(/\$/g, '\\$') // Escape dollar signs
.replace(/\n/g, "\\n")
); // Replace newlines with \n
// .replace(/`/g, '\\`'); // Escape backticks
};
27 changes: 13 additions & 14 deletions src/plugin/withIosDsyms/withIosDsyms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,19 @@ const withIosDsyms: ConfigPlugin<void> = (config) => {
{
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
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",
}
Expand Down
5 changes: 3 additions & 2 deletions src/plugin/withIosSourcemaps/withIosSourcemaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import {
IOS_DATADOG_CI_EXPORT,
IOS_SOURCEMAP_FILE_EXPORT,
} from "../common/exports";
import { escapeStringForIOSBuildPhase } from "../common/utils";
import { SourceMapUploadOptions } from "../getErrorTrackingPluginsFromOptions";

const DATADOG_XCODE_COMMAND = `
const DATADOG_XCODE_COMMAND = escapeStringForIOSBuildPhase(`
${IOS_DATADOG_CI_EXPORT}
$DATADOG_CI_EXEC react-native xcode \`"$NODE_BINARY" --print "require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'"\`
`;
`);
const getDatadogXCodeCommand = (
serviceName: SourceMapUploadOptions["serviceName"]
) =>
Expand Down

0 comments on commit b162e20

Please sign in to comment.