Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/cli/lib/src/codegen/api/dockerfile_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:mustache_template/mustache_template.dart';
final class DockerfileGenerator {
DockerfileGenerator({required this.project});

final ast.Project project;
final ast.ResolvedProject project;

static final Template _dartTemplate = Template(r'''
# syntax=docker/dockerfile:1
Expand Down
29 changes: 6 additions & 23 deletions apps/cli/lib/src/frontend/celest_frontend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import 'package:celest_cli/src/repositories/project_repository.dart';
import 'package:celest_cli/src/utils/json.dart';
import 'package:celest_cli/src/utils/recase.dart';
import 'package:celest_cloud/src/proto.dart' as pb;
import 'package:celest_core/_internal.dart';
import 'package:dcli/dcli.dart' as dcli;
import 'package:logging/logging.dart';
import 'package:mason_logger/mason_logger.dart' show Progress;
Expand Down Expand Up @@ -555,7 +554,6 @@ final class CelestFrontend {
);
try {
await _writeProjectOutputs(
project: project,
resolvedProject: resolvedProject,
environmentId: environmentId,
);
Expand Down Expand Up @@ -653,8 +651,7 @@ final class CelestFrontend {
iteration++;
});
final (deployedProject, baseUri) = await _deployProject(
projectId: projectId,
environmentId: environment.projectEnvironmentId,
environmentName: environment.name,
resolvedProject: resolvedProject,
);
await _generateClientCode(
Expand Down Expand Up @@ -745,7 +742,6 @@ final class CelestFrontend {
});

Future<void> _writeProjectOutputs({
required Project project,
required ResolvedProject resolvedProject,
required String environmentId,
}) async {
Expand Down Expand Up @@ -788,7 +784,7 @@ final class CelestFrontend {
}
}

final dockerfile = DockerfileGenerator(project: project);
final dockerfile = DockerfileGenerator(project: resolvedProject);
await buildOutputs
.childFile('Dockerfile')
.writeAsString(dockerfile.generate());
Expand Down Expand Up @@ -887,12 +883,10 @@ final class CelestFrontend {
}

Future<(ast.ResolvedProject, Uri)> _deployProject({
required String projectId,
required String environmentId,
required String environmentName,
required ast.ResolvedProject resolvedProject,
}) =>
performance.trace('CelestFrontend', 'deployProject', () async {
final deploymentId = Uuid.v7().hexValue;
try {
final entrypointCompiler = EntrypointCompiler(
logger: logger,
Expand All @@ -905,7 +899,7 @@ final class CelestFrontend {
entrypointPath: projectPaths.localApiEntrypoint,
);
final operation = cloud.projects.environments.deploy(
'projects/$projectId/environments/$environmentId',
environmentName,
// HACK(dnys1): celest_ast and celest_cloud don't share types.
resolvedProject: pb.ResolvedProject.fromBuffer(
resolvedProject.toProto().writeToBuffer(),
Expand All @@ -918,7 +912,6 @@ final class CelestFrontend {
inline: kernel.outputDill,
),
],
requestId: deploymentId,
);
final waiter = CloudCliOperation(
operation,
Expand All @@ -945,24 +938,14 @@ final class CelestFrontend {
);
} on Exception catch (e, st) {
if (e case CancellationException() || CliException()) {
analytics.capture(
'cancel_deployment',
properties: {
'deployment_id': deploymentId,
'project_id': projectId,
'environment_id': environmentId,
},
);
rethrow;
}
Error.throwWithStackTrace(
CliException(
'Failed to deploy project. Please contact the Celest team and '
'reference deployment ID: $deploymentId',
'reference environment: $environmentName',
additionalContext: {
'deploymentId': deploymentId,
'project_id': projectId,
'environment_id': environmentId,
'environment_name': environmentName,
'error': '$e',
},
),
Expand Down
6 changes: 4 additions & 2 deletions apps/cli/lib/src/project/project_linker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ final class ProjectLinker extends AstVisitorWithArg<Node?, AstNode> {
required Map<String, String> configValues,
required String environmentId,
this.driftSchemas = const {},
}) : configValues = {...configValues, 'CELEST_ENVIRONMENT': environmentId};
}) : configValues = {...configValues, 'CELEST_ENVIRONMENT': environmentId},
_resolvedProject = ResolvedProjectBuilder()
..environmentId = environmentId;

final _resolvedProject = ResolvedProjectBuilder();
final ResolvedProjectBuilder _resolvedProject;
late final ResolvedProject resolvedProject = run(() {
final celestConfigValues = configValues.keys.toSet().difference(
_seenConfigValues,
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/lib/src/repositories/project_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final class ProjectRepository {
return null;
}
final cloudPrj = await _cloud.projects.get(
'${organization.name}projects/$projectIdOrAlias',
'${organization.name}/projects/$projectIdOrAlias',
);
return cloudPrj;
} on Object catch (e, st) {
Expand Down
1 change: 1 addition & 0 deletions packages/celest/example/celest/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

# Celest
**/.env
build/
31 changes: 30 additions & 1 deletion packages/celest_cloud/lib/src/cloud/cloud.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ import 'package:celest_cloud/src/cloud/projects/projects.dart';
import 'package:celest_cloud/src/cloud/subscriptions/subscriptions.dart';
import 'package:celest_cloud/src/cloud/users/users.dart';
import 'package:celest_cloud/src/proto.dart';
import 'package:celest_cloud/src/proto/google/protobuf/duration.pb.dart' as pb;
import 'package:celest_cloud/src/proto/google/protobuf/empty.pb.dart' as pb;
import 'package:celest_cloud/src/proto/google/protobuf/field_mask.pb.dart'
as pb;
import 'package:celest_cloud/src/proto/google/protobuf/struct.pb.dart' as pb;
import 'package:celest_cloud/src/proto/google/protobuf/timestamp.pb.dart' as pb;
import 'package:celest_cloud/src/proto/google/protobuf/wrappers.pb.dart' as pb;
import 'package:celest_cloud/src/proto/google/rpc/status.pb.dart' as pb;
import 'package:celest_core/_internal.dart';
import 'package:http/http.dart' as http;
import 'package:logging/logging.dart';
Expand Down Expand Up @@ -117,11 +125,32 @@ class CelestCloud {
: ClientType.CLIENT_TYPE_UNSPECIFIED;

static final typeRegistry = TypeRegistry([
Empty(),
// Cloud
OperationMetadata(),
Operation(),
Organization(),
Project(),
ProjectEnvironment(),
DeployProjectEnvironmentResponse(),

// RPC
pb.Status(),

// Well-known types
pb.BoolValue(),
pb.StringValue(),
pb.Int32Value(),
pb.Int64Value(),
pb.FloatValue(),
pb.DoubleValue(),
pb.Timestamp(),
pb.BytesValue(),
pb.Duration(),
pb.FieldMask(),
pb.Empty(),
pb.Struct(),
pb.ListValue(),
pb.Value(),
]);

final Uri? _baseUri;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ final class ProjectEnvironmentsProtocolHttp
queryParameters: {
if (request.hasParent()) 'parent': request.parent,
if (request.hasProjectEnvironmentId())
'project_environment_id': request.projectEnvironmentId,
'projectEnvironmentId': request.projectEnvironmentId,
if (request.hasValidateOnly())
'validateOnly': request.validateOnly.toString(),
},
Expand Down
1 change: 1 addition & 0 deletions services/celest_cloud_hub/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ analyzer:
implementation_imports: ignore
exclude:
- lib/src/proto/**
- lib/src/**/*.g.dart
2 changes: 1 addition & 1 deletion services/celest_cloud_hub/bin/cloud_hub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import 'package:logging/logging.dart';
import 'package:stack_trace/stack_trace.dart';

Future<void> main() async {
context.logger.level = Level.ALL;
context.logger.level = Level.INFO;
context.logger.onRecord.listen((record) {
print('${record.level.name}: ${record.time}: ${record.message}');
if (record.error != null) {
Expand Down
130 changes: 130 additions & 0 deletions services/celest_cloud_hub/bin/deploy_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import 'dart:io';

import 'package:celest_ast/celest_ast.dart' as ast;
import 'package:celest_cli/src/sdk/sdk_finder.dart';
import 'package:celest_cloud_hub/src/database/cloud_hub_database.dart';
import 'package:celest_cloud_hub/src/deploy/fly/fly_deployment_engine.dart';
import 'package:celest_cloud_hub/src/services/service_mixin.dart';
import 'package:file/local.dart';
import 'package:http/http.dart' as http;
import 'package:logging/logging.dart';
import 'package:process/process.dart';
import 'package:pub_semver/pub_semver.dart';

const fileSystem = LocalFileSystem();
const processManager = LocalProcessManager();

Future<void> main() async {
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((record) {
print(
'[${record.loggerName.split('.').last}] ${record.level}: ${record.message}',
);
});

const sdkFinder = DartSdkFinder();
final sdk = (await sdkFinder.findSdk()).sdk;

const helloWorld = r'''
import 'dart:io';

Future<void> main() async {
final port = int.parse(Platform.environment['PORT'] ?? '8080');
final server = await HttpServer.bind(InternetAddress.anyIPv4, port);
print('Listening on http://localhost:$port');
await for (final request in server) {
request.response.write('Hello, world!');
await request.response.close();
}
}
''';
final tmpDir = fileSystem.systemTempDirectory.createTempSync('celest_').path;
await fileSystem
.directory(tmpDir)
.childFile('hello_world.dart')
.writeAsString(helloWorld);

print('Compiling server');
final res = await processManager.run([
sdk.dartAotRuntime,
sdk.frontendServerAotSnapshot,
'--sdk-root',
sdk.sdkPath,
'--platform',
sdk.vmPlatformProductDill,
'--aot',
'--tfa',
'--no-support-mirrors',
'--link-platform',
'--target=vm',
'-Ddart.vm.product=true',
'--output-dill=$tmpDir/celest.aot.dill',
'$tmpDir/hello_world.dart',
]);
if (res.exitCode != 0) {
throw Exception('Failed to compile hello_world.dart:\n${res.stderr}');
}
final bytes = await fileSystem.file('$tmpDir/celest.aot.dill').readAsBytes();

final db = CloudHubDatabase.memory();

print('Creating organization');
final orgId = typeId('org');
await db.organizationsDrift.createOrganization(
id: orgId,
organizationId: 'my-org',
state: 'ACTIVE',
displayName: 'My Organization',
);

print('Creating project');
final projectId = typeId('prj');
await db.projectsDrift.createProject(
id: projectId,
parentType: 'Celest::Organization',
parentId: orgId,
projectId: 'my-project',
state: 'ACTIVE',
regions: '',
);

print('Creating environment');
final environmentId = typeId('env');
final environment =
(await db.projectEnvironmentsDrift.createProjectEnvironment(
id: environmentId,
parentType: 'Celest::Project',
parentId: projectId,
projectEnvironmentId: 'production',
state: 'CREATING',
)).first;
final flyApiToken = Platform.environment['FLY_API_TOKEN']!;
final deploymentEngine = FlyDeploymentEngine(
db: db,
flyApiToken: flyApiToken,
projectAst: ast.ResolvedProject(
projectId: 'my-project',
environmentId: 'production',
sdkConfig: ast.SdkConfiguration(
celest: Version(1, 0, 9),
dart: ast.Sdk(type: ast.SdkType.dart, version: sdk.version),
),
),
kernelAsset: bytes,
environment: environment,
);

print('Deploying');
final state = await deploymentEngine.deploy();
deploymentEngine.close();

final uri = Uri.parse('https://${state.domainName}');
final response = await http.get(uri);
if (response.statusCode != 200) {
throw http.ClientException(
'Bad response: ${response.statusCode} ${response.body}',
uri,
);
}
print(response.body);
}
2 changes: 1 addition & 1 deletion services/celest_cloud_hub/fly.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# fly.yaml app configuration file generated for cloud-hub on 2025-04-07T11:42:36-07:00
# fly.yaml app configuration file generated for cloud-hub on 2025-04-10T10:46:14-07:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#
Expand Down
Loading
Loading