Skip to content

Commit 6c078ce

Browse files
Merge branch 'master' into cursor/update-mobile-app-command-for-ipa-uploads-e699
2 parents 9586ada + 88882b4 commit 6c078ce

File tree

10 files changed

+145
-42
lines changed

10 files changed

+145
-42
lines changed

.github/workflows/test_node.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ jobs:
2020
node-version-file: package.json
2121

2222
# We need to skip the fallback download because downloading will fail on release branches because the new version isn't available yet.
23-
- run: SENTRYCLI_SKIP_DOWNLOAD=1 yarn install --frozen-lockfile
23+
# We have to use npm here because yarn fails on the non-existing existing optionalDependency version:
24+
# https://github.com/yarnpkg/berry/issues/2425#issuecomment-1627807326
25+
- run: SENTRYCLI_SKIP_DOWNLOAD=1 npm install
2426

25-
- run: yarn check:types
27+
- run: npm run check:types
2628

2729
test_node:
2830
strategy:
@@ -42,13 +44,12 @@ jobs:
4244
node-version: ${{ matrix.node-version }}
4345

4446
# We need to skip the fallback download because downloading will fail on release branches because the new version isn't available yet.
45-
- run: SENTRYCLI_SKIP_DOWNLOAD=1 yarn install --frozen-lockfile
46-
if: matrix.node-version != '10.x' && matrix.node-version != '12.x'
47+
# We have to use npm here because yarn fails on the non-existing existing optionalDependency version:
48+
# https://github.com/yarnpkg/berry/issues/2425#issuecomment-1627807326
49+
- run: SENTRYCLI_SKIP_DOWNLOAD=1 npm install
4750

4851
# older node versions need an older nft
49-
- run: |
50-
SENTRYCLI_SKIP_DOWNLOAD=1 yarn install --ignore-engines --frozen-lockfile
51-
SENTRYCLI_SKIP_DOWNLOAD=1 yarn add @vercel/nft@0.22.1 --ignore-engines
52+
- run: SENTRYCLI_SKIP_DOWNLOAD=1 npm install @vercel/nft@0.22.1
5253
if: matrix.node-version == '10.x' || matrix.node-version == '12.x'
5354

54-
- run: yarn test
55+
- run: npm test

apple-catalog-parsing/build.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ use std::env;
22
use std::process::Command;
33

44
fn main() {
5+
/// Environment variable to disable Swift sandboxing.
6+
const SWIFT_DISABLE_SANDBOX: &str = "SWIFT_DISABLE_SANDBOX";
7+
58
let target = env::var("TARGET").expect("TARGET is set for build scripts");
69
let mut target_bits = target.split('-');
710

@@ -20,21 +23,34 @@ fn main() {
2023

2124
println!("cargo:rerun-if-changed=native/swift/AssetCatalogParser");
2225

26+
// Allow swift to be run with `--disable-sandbox` in case cargo has been invoked inside a
27+
// sandbox already. Nested sandboxes are not allowed on Darwin.
28+
println!("cargo:rerun-if-env-changed={SWIFT_DISABLE_SANDBOX}");
29+
2330
let out_dir = env::var("OUT_DIR").expect("OUT_DIR is set for build scripts");
2431

2532
// Compile Swift code
2633
let status = Command::new("swift")
27-
.args([
28-
"build",
29-
"-c",
30-
"release",
31-
"--package-path",
32-
"native/swift/AssetCatalogParser",
33-
"--scratch-path",
34-
&format!("{out_dir}/swift-scratch"),
35-
"--triple",
36-
&format!("{arch}-apple-macosx10.12"),
37-
])
34+
.args(
35+
[
36+
"build",
37+
"-c",
38+
"release",
39+
"--package-path",
40+
"native/swift/AssetCatalogParser",
41+
"--scratch-path",
42+
&format!("{out_dir}/swift-scratch"),
43+
"--triple",
44+
&format!("{arch}-apple-macosx10.12"),
45+
]
46+
.into_iter()
47+
.chain(
48+
env::var(SWIFT_DISABLE_SANDBOX)
49+
.ok()
50+
.filter(|s| s == "1")
51+
.map(|_| "--disable-sandbox"),
52+
),
53+
)
3854
.status()
3955
.expect("Failed to compile SPM");
4056

js/__tests__/helper.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,30 @@ describe('SentryCli helper', () => {
2222
expect(helper.getPath()).toMatch(pattern);
2323
});
2424

25+
describe('execute', () => {
26+
test('execute with live=false returns stdout', async () => {
27+
const output = await helper.execute(['--version'], false);
28+
expect(output.trim()).toBe('sentry-cli DEV');
29+
});
30+
31+
test('execute with live=true resolves without output', async () => {
32+
// TODO (v3): This should resolve with a string, not undefined/void
33+
const result = await helper.execute(['--version'], true);
34+
expect(result).toBeUndefined();
35+
});
36+
37+
test('execute with live=rejectOnError resolves on success', async () => {
38+
const result = await helper.execute(['--version'], 'rejectOnError');
39+
expect(result).toBe('success (live mode)');
40+
});
41+
42+
test('execute with live=rejectOnError rejects on failure', async () => {
43+
await expect(helper.execute(['fail'], 'rejectOnError')).rejects.toThrow(
44+
'Command fail failed with exit code 1'
45+
);
46+
});
47+
});
48+
2549
describe('`prepare` command', () => {
2650
test('call prepare command add default ignore', () => {
2751
const command = ['releases', 'files', 'release', 'upload-sourcemaps', '/dev/null'];

js/helper.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,11 @@ function getPath() {
281281
* expect(output.trim()).toBe('sentry-cli x.y.z');
282282
*
283283
* @param {string[]} args Command line arguments passed to `sentry-cli`.
284-
* @param {boolean} live We inherit stdio to display `sentry-cli` output directly.
284+
* @param {boolean | 'rejectOnError'} live can be set to:
285+
* - `true` to inherit stdio to display `sentry-cli` output directly.
286+
* - `false` to not inherit stdio and return the output as a string.
287+
* - `'rejectOnError'` to inherit stdio and reject the promise if the command
288+
* exits with a non-zero exit code.
285289
* @param {boolean} silent Disable stdout for silents build (CI/Webpack Stats, ...)
286290
* @param {string} [configFile] Relative or absolute path to the configuration file.
287291
* @param {Object} [config] More configuration to pass to the CLI
@@ -322,16 +326,27 @@ async function execute(args, live, silent, configFile, config = {}) {
322326
]);
323327
args = [...headers, ...args];
324328
}
329+
325330
return new Promise((resolve, reject) => {
326-
if (live === true) {
331+
if (live === true || live === 'rejectOnError') {
327332
const output = silent ? 'ignore' : 'inherit';
328333
const pid = childProcess.spawn(getPath(), args, {
329334
env,
330335
// stdin, stdout, stderr
331336
stdio: ['ignore', output, output],
332337
});
333-
pid.on('exit', () => {
334-
// @ts-expect-error - this is a TODO (v3) to fix and resolve a string here
338+
pid.on('exit', (exitCode) => {
339+
if (live === 'rejectOnError') {
340+
if (exitCode === 0) {
341+
resolve('success (live mode)');
342+
}
343+
reject(new Error(`Command ${args.join(' ')} failed with exit code ${exitCode}`));
344+
}
345+
// According to the type definition, resolving with void is not allowed.
346+
// However, for backwards compatibility, we resolve void here to
347+
// avoid a behaviour-breaking change.
348+
// TODO (v3): Clean this up and always resolve a string (or change the type definition)
349+
// @ts-expect-error - see comment above
335350
resolve();
336351
});
337352
} else {

js/releases/__tests__/index.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,25 @@ describe('SentryCli releases', () => {
159159
{ silent: false }
160160
);
161161
});
162+
163+
test.each([true, false, 'rejectOnError'])('handles live mode %s', async (live) => {
164+
await cli.releases.uploadSourceMaps('my-version', { include: ['path'], live });
165+
expect(mockExecute).toHaveBeenCalledWith(
166+
[
167+
'releases',
168+
'files',
169+
'my-version',
170+
'upload-sourcemaps',
171+
'path',
172+
'--ignore',
173+
'node_modules',
174+
],
175+
live,
176+
false,
177+
undefined,
178+
{ silent: false }
179+
);
180+
});
162181
});
163182
});
164183
});

js/releases/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,10 @@ class Releases {
199199

200200
return uploadPaths.map((path) =>
201201
// `execute()` is async and thus we're returning a promise here
202-
this.execute(helper.prepareCommand([...args, path], SOURCEMAPS_SCHEMA, newOptions), true)
202+
this.execute(
203+
helper.prepareCommand([...args, path], SOURCEMAPS_SCHEMA, newOptions),
204+
options.live != null ? options.live : true
205+
)
203206
);
204207
});
205208

@@ -255,7 +258,11 @@ class Releases {
255258
/**
256259
* See {helper.execute} docs.
257260
* @param {string[]} args Command line arguments passed to `sentry-cli`.
258-
* @param {boolean} live We inherit stdio to display `sentry-cli` output directly.
261+
* @param {boolean | 'rejectOnError'} live can be set to:
262+
* - `true` to inherit stdio to display `sentry-cli` output directly.
263+
* - `false` to not inherit stdio and return the output as a string.
264+
* - `'rejectOnError'` to inherit stdio and reject the promise if the command
265+
* exits with a non-zero exit code.
259266
* @returns {Promise.<string>} A promise that resolves to the standard output.
260267
*/
261268
async execute(args, live) {

src/commands/mobile_app/upload.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::borrow::Cow;
2-
use std::io::Write;
3-
use std::path::Path;
42
#[cfg(not(windows))]
53
use std::fs;
4+
use std::io::Write;
65
#[cfg(not(windows))]
76
use std::os::unix::fs::PermissionsExt;
7+
use std::path::Path;
88

99
use anyhow::{anyhow, bail, Context as _, Result};
1010
use clap::{Arg, ArgAction, ArgMatches, Command};
@@ -343,9 +343,14 @@ fn normalize_directory(path: &Path) -> Result<TempFile> {
343343
.filter(|entry| entry.path().is_file())
344344
.map(|entry| {
345345
let entry_path = entry.into_path();
346-
let relative_path = entry_path.strip_prefix(
347-
path.parent().ok_or_else(|| anyhow!("Cannot determine parent directory for path: {}", path.display()))?
348-
)?.to_owned();
346+
let relative_path = entry_path
347+
.strip_prefix(path.parent().ok_or_else(|| {
348+
anyhow!(
349+
"Cannot determine parent directory for path: {}",
350+
path.display()
351+
)
352+
})?)?
353+
.to_owned();
349354
Ok((entry_path, relative_path))
350355
})
351356
.collect::<Result<Vec<_>>>()?

src/commands/mod.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,33 @@ use crate::utils::system::{load_dotenv, print_error, set_panic_hook, QuietExit};
1919
use crate::utils::update::run_sentrycli_update_nagger;
2020
use crate::utils::value_parsers::auth_token_parser;
2121

22+
mod bash_hook;
23+
mod debug_files;
24+
mod deploys;
2225
mod derive_parser;
26+
mod events;
27+
mod files;
28+
mod info;
29+
mod issues;
30+
mod login;
31+
mod mobile_app;
32+
mod monitors;
33+
mod organizations;
34+
mod projects;
35+
mod react_native;
36+
mod releases;
37+
mod repos;
38+
mod send_envelope;
39+
mod send_event;
40+
mod send_metric;
41+
mod sourcemaps;
42+
#[cfg(not(feature = "managed"))]
43+
mod uninstall;
44+
#[cfg(not(feature = "managed"))]
45+
mod update;
46+
mod upload_dif;
47+
mod upload_dsym;
48+
mod upload_proguard;
2349

2450
macro_rules! each_subcommand {
2551
($mac:ident) => {
@@ -53,14 +79,6 @@ macro_rules! each_subcommand {
5379
};
5480
}
5581

56-
macro_rules! import_subcommand {
57-
($name:ident) => {
58-
pub mod $name;
59-
};
60-
}
61-
62-
each_subcommand!(import_subcommand);
63-
6482
const ABOUT: &str = "
6583
Command line utility for Sentry.
6684

src/commands/react_native/gradle.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
119119

120120
if let Some(version) = version {
121121
for dist in matches.get_many::<String>("dist").unwrap() {
122-
println!(
123-
"Uploading sourcemaps for release {version} distribution {dist}"
124-
);
122+
println!("Uploading sourcemaps for release {version} distribution {dist}");
125123

126124
processor.upload(&UploadContext {
127125
org: &org,

src/commands/send_metric/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ This command will validate input parameters and attempt to send a metric to \
3838
Sentry. Due to network errors and rate limits, the metric is not guaranteed to \
3939
arrive. Check the debug output for transmission errors by passing --log-level=\
4040
debug or setting `SENTRY_LOG_LEVEL=debug`."))]
41-
#[command(hide=true)]
41+
#[command(hide = true)]
4242
enum SendMetricSubcommand {
4343
#[command(about = format!("[DEPRECATED] {INCREMENT_ABOUT}"))]
4444
#[command(long_about = format!("{DEPRECATION_MESSAGE}{{n}}{{n}}{INCREMENT_ABOUT}"))]

0 commit comments

Comments
 (0)