From 09bee6215ae054a3ec56851333dd4a2d9a7ebe75 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Thu, 21 Dec 2023 17:09:57 +0100 Subject: [PATCH 1/4] feat(globe_cli): Add --logs for globe deploy --- docs/cli/commands/deploy.mdx | 9 + .../lib/src/commands/deploy_command.dart | 181 +++++++++--------- 2 files changed, 104 insertions(+), 86 deletions(-) diff --git a/docs/cli/commands/deploy.mdx b/docs/cli/commands/deploy.mdx index 36c3e73e..55c7bcd3 100644 --- a/docs/cli/commands/deploy.mdx +++ b/docs/cli/commands/deploy.mdx @@ -30,8 +30,17 @@ When successfully built, the deployment will be promoted to production and will You can learn more about [preview and production deployments](/deployments) in the deployments documentation. +## Build logs + +If you want to see realtime build logs for your deployment on CLI, use `--logs` flag: + +```bash +globe deploy --logs +``` + ### Flags The command has flags (in addition to [global flags](/cli#global-flags)) that can be used to modify the behavior of the command, which can be accessed by running `globe deploy --`: - `--prod` - Creates a deployment that will be promoted to production once built. +- `--logs` - Streams build logs diff --git a/packages/globe_cli/lib/src/commands/deploy_command.dart b/packages/globe_cli/lib/src/commands/deploy_command.dart index a699bdb8..b0b82ea7 100644 --- a/packages/globe_cli/lib/src/commands/deploy_command.dart +++ b/packages/globe_cli/lib/src/commands/deploy_command.dart @@ -6,6 +6,7 @@ import 'package:mason_logger/mason_logger.dart'; import '../command.dart'; import '../utils/api.dart'; import '../utils/archiver.dart'; +import '../utils/logs.dart'; import '../utils/prompts.dart'; /// `globe deploy` @@ -16,11 +17,16 @@ import '../utils/prompts.dart'; class DeployCommand extends BaseGlobeCommand { /// {@macro deploy_command} DeployCommand() { - argParser.addFlag( - 'prod', - help: 'Creates a new deployment, ' - 'and if successful promotes it to the latest production deployment.', - ); + argParser + ..addFlag( + 'prod', + help: 'Creates a new deployment, ' + 'and if successful promotes it to the latest production deployment.', + ) + ..addFlag( + 'logs', + help: 'Shows build logs for the deployment.', + ); } @override @@ -72,87 +78,90 @@ class DeployCommand extends BaseGlobeCommand { '🔍 View deployment: ${metadata.endpoint}/${validated.organization.slug}/${validated.project.slug}/deployments/${deployment.id}', ); - // TODO: handle deployment logs - they currently disconnect immediately - // var status = logger.progress(deployment.state.message); - // final completer = Completer(); - // Stream? logs; - - // // Check the deployment status every x seconds. - // Timer.periodic(const Duration(milliseconds: 2000), (timer) async { - // final update = await api.getDeployment( - // orgId: validated.organization.id, - // projectId: validated.project.id, - // deploymentId: deployment.id, - // ); - - // if (update.state == DeploymentState.working || - // update.state == DeploymentState.deploying) { - // if (logs != null) return; - - // status.complete(); - // status = logger.progress('Preparing build environment'); - - // logs = await streamBuildLogs( - // api: api, - // orgId: validated.organization.id, - // projectId: validated.project.id, - // deploymentId: deployment.id, - // ); - - // unawaited( - // logs! - // .firstWhere((element) => element is! UnknownBuildLogEvent) - // .then((_) => status.complete()), - // ); - - // unawaited( - // logs!.firstWhere((element) { - // if (element case LogsBuildLogEvent(done: final done)) return done; - // return false; - // }).then((_) { - // status = logger.progress('Deploying...'); - // }), - // ); - - // unawaited(printLogs(logger, logs!)); - // } - - // if (update.state == DeploymentState.success) { - // status.complete(); - // logger.info( - // '${lightGreen.wrap('✓')} Preview: https://${update.url}', - // ); - // } - - // if (update.state == DeploymentState.error) { - // var message = 'Deployment failed'; - // if (update.message.isNotEmpty) { - // message = '$message: ${update.message}'; - // } - // status.fail(message); - // } - - // if (update.state == DeploymentState.cancelled) { - // status.complete(); - // logger.info('Deployment cancelled'); - // } - - // if (update.state == DeploymentState.invalid) { - // status.complete(); - // status = logger.progress( - // 'Invalid Deployment State Received. Waiting for valid state', - // ); - // } - - // if (update.state == DeploymentState.success || - // update.state == DeploymentState.cancelled || - // update.state == DeploymentState.error) { - // timer.cancel(); - // completer.complete(); - // } - // }); - - // await completer.future; + if (!(argResults!['logs'] as bool)) { + return ExitCode.success.code; + } + + var status = logger.progress(deployment.state.message); + final completer = Completer(); + Stream? logs; + + // Check the deployment status every x seconds. + Timer.periodic(const Duration(milliseconds: 2000), (timer) async { + final update = await api.getDeployment( + orgId: validated.organization.id, + projectId: validated.project.id, + deploymentId: deployment.id, + ); + + if (update.state == DeploymentState.working || + update.state == DeploymentState.deploying) { + if (logs != null) return; + + status.complete(); + status = logger.progress('Preparing build environment'); + + logs = await streamBuildLogs( + api: api, + orgId: validated.organization.id, + projectId: validated.project.id, + deploymentId: deployment.id, + ); + + unawaited( + logs! + .firstWhere((element) => element is! UnknownBuildLogEvent) + .then((_) => status.complete()), + ); + + unawaited( + logs!.firstWhere((element) { + if (element case LogsBuildLogEvent(done: final done)) return done; + return false; + }).then((_) { + status = logger.progress('Deploying...'); + }), + ); + + unawaited(printLogs(logger, logs!)); + } + + if (update.state == DeploymentState.success) { + status.complete(); + logger.info( + '${lightGreen.wrap('✓')} Preview: https://${update.url}', + ); + } + + if (update.state == DeploymentState.error) { + var message = 'Deployment failed'; + if (update.message.isNotEmpty) { + message = '$message: ${update.message}'; + } + status.fail(message); + } + + if (update.state == DeploymentState.cancelled) { + status.complete(); + logger.info('Deployment cancelled'); + } + + if (update.state == DeploymentState.invalid) { + status.complete(); + status = logger.progress( + 'Invalid Deployment State Received. Waiting for valid state', + ); + } + + if (update.state == DeploymentState.success || + update.state == DeploymentState.cancelled || + update.state == DeploymentState.error) { + timer.cancel(); + completer.complete(); + } + }); + + await completer.future; return ExitCode.success.code; } on ApiException catch (e) { From 3fccdec917abe608a02142bdb706efcf529f9016 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Thu, 21 Dec 2023 17:17:21 +0100 Subject: [PATCH 2/4] Update docs/cli/commands/deploy.mdx Co-authored-by: Mike Diarmid --- docs/cli/commands/deploy.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli/commands/deploy.mdx b/docs/cli/commands/deploy.mdx index 55c7bcd3..8b501f0b 100644 --- a/docs/cli/commands/deploy.mdx +++ b/docs/cli/commands/deploy.mdx @@ -30,7 +30,7 @@ When successfully built, the deployment will be promoted to production and will You can learn more about [preview and production deployments](/deployments) in the deployments documentation. -## Build logs +### Build logs If you want to see realtime build logs for your deployment on CLI, use `--logs` flag: From c0ef99cbb2309ef6134d41879d4efde1d5e69f25 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Thu, 21 Dec 2023 17:17:35 +0100 Subject: [PATCH 3/4] Update docs/cli/commands/deploy.mdx Co-authored-by: Mike Diarmid --- docs/cli/commands/deploy.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli/commands/deploy.mdx b/docs/cli/commands/deploy.mdx index 8b501f0b..d60aa60b 100644 --- a/docs/cli/commands/deploy.mdx +++ b/docs/cli/commands/deploy.mdx @@ -32,7 +32,7 @@ You can learn more about [preview and production deployments](/deployments) in t ### Build logs -If you want to see realtime build logs for your deployment on CLI, use `--logs` flag: +If you want to see realtime build logs for your deployment on the CLI, use the `--logs` flag: ```bash globe deploy --logs From 98b1edbc23cee91d5343e3f58a1e2e62a8e74b5e Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Thu, 21 Dec 2023 17:17:45 +0100 Subject: [PATCH 4/4] Update docs/cli/commands/deploy.mdx Co-authored-by: Mike Diarmid --- docs/cli/commands/deploy.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli/commands/deploy.mdx b/docs/cli/commands/deploy.mdx index d60aa60b..601e6fbd 100644 --- a/docs/cli/commands/deploy.mdx +++ b/docs/cli/commands/deploy.mdx @@ -43,4 +43,4 @@ globe deploy --logs The command has flags (in addition to [global flags](/cli#global-flags)) that can be used to modify the behavior of the command, which can be accessed by running `globe deploy --`: - `--prod` - Creates a deployment that will be promoted to production once built. -- `--logs` - Streams build logs +- `--logs` - Streams build logs.