Skip to content

Commit 4748aa4

Browse files
committed
chore(cloud_hub): Add Fly volume ID
And create a test for deploying to Fly.io which can run in CI.
1 parent 9b6f638 commit 4748aa4

31 files changed

+24476
-351
lines changed

.github/workflows/celest_cloud_hub.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ jobs:
4141
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # 2.19.0
4242
with:
4343
cache: true
44+
- name: Setup Fly
45+
uses: superfly/flyctl-actions/setup-flyctl@63da3ecc5e2793b98a3f2519b3d75d4f4c11cec2 # master
4446
- name: Get Packages
4547
working-directory: services/celest_cloud_hub
4648
run: dart pub upgrade
4749
- name: Test
4850
working-directory: services/celest_cloud_hub
4951
run: dart test --fail-fast -j1
52+
env:
53+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

services/celest_cloud_core/lib/src/model/resource_name.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ extension type ResourceName(_ResourceNameInfo _info) {
4242
));
4343
}
4444

45+
/// Tries to parse a resource name string into a [ResourceName] object.
46+
///
47+
/// Returns `null` if the parsing fails for any reason.
48+
static ResourceName? tryParse(String name) {
49+
try {
50+
return ResourceName.parse(name);
51+
} on Object {
52+
return null;
53+
}
54+
}
55+
4556
/// A map of resource pattern types to their Cedar entity types.
4657
static const Map<String, EntityTypeName> entityTypes = {
4758
'operations': EntityTypeName('Celest::Operation'),
@@ -55,6 +66,9 @@ extension type ResourceName(_ResourceNameInfo _info) {
5566
/// The resource type for this resource.
5667
ResourceType get type => _info.type;
5768

69+
/// The identifier of this resource.
70+
String get id => uid.id;
71+
5872
/// The unique identifier for this resource.
5973
EntityUid get uid => _info.uid;
6074

services/celest_cloud_hub/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
lib/src/database/schema/*.drift.dart: lib/src/database/schema/*.drift
2+
@echo "Generating Drift code..."
3+
@dart run build_runner build --delete-conflicting-outputs
4+
5+
lib/src/database/cloud_hub_database.steps.dart: lib/src/database/cloud_hub_database.dart lib/src/database/schema/*.drift.dart
6+
@echo "Generating migration steps..."
7+
@dart run drift_dev make-migrations
8+
9+
drift: lib/src/database/cloud_hub_database.steps.dart
10+
11+
cedar: lib/src/auth/*.cedar
12+
@echo "Generating Cedar code..."
13+
@dart run tool/generate_policy_set.dart
14+
15+
.PHONY: drift cedar
16+
all: drift cedar

services/celest_cloud_hub/bin/deploy_test.dart

Lines changed: 0 additions & 138 deletions
This file was deleted.

services/celest_cloud_hub/build.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ targets:
1313
- lib/src/database/**
1414
- lib/src/model/**
1515
options: &options
16+
databases:
17+
cloud_hub_database: lib/src/database/cloud_hub_database.dart
18+
schema_dir: drift_schema/
19+
test_dir: test/database/
20+
1621
sql:
1722
dialect: sqlite
1823
options:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
tags:
2+
e2e:
3+
timeout: 5m

services/celest_cloud_hub/drift_schema/cloud_hub_database/drift_schema_v1.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

services/celest_cloud_hub/drift_schema/cloud_hub_database/drift_schema_v2.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'package:celest/src/config/config_values.dart';
2+
import 'package:celest/src/core/context.dart' as core;
3+
import 'package:celest_cloud_hub/src/deploy/fly/fly_api.dart';
4+
5+
export 'package:celest/src/core/context.dart' show ContextKey;
6+
7+
Context get context => Context._(core.Context.current);
8+
9+
extension type Context._(core.Context _ctx) implements core.Context {
10+
static const core.ContextKey<FlyMachinesApiClient> _flyContextKey =
11+
core.ContextKey<FlyMachinesApiClient>('FlyMachinesApiClient');
12+
13+
String get flyAuthToken => _ctx.expect(const env('FLY_API_TOKEN'));
14+
String get flyOrgSlug => 'celest-809';
15+
16+
FlyMachinesApiClient get fly {
17+
if (_ctx.get(_flyContextKey) case final flyApi?) {
18+
return flyApi;
19+
}
20+
final flyApi = FlyMachinesApiClient(
21+
authToken: flyAuthToken,
22+
client: _ctx.httpClient,
23+
);
24+
return _ctx.put(_flyContextKey, flyApi);
25+
}
26+
}

services/celest_cloud_hub/lib/src/database/cloud_hub_database.dart

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:io';
22

33
import 'package:celest_cloud_auth/celest_cloud_auth.dart';
44
import 'package:celest_cloud_hub/src/auth/policy_set.g.dart';
5+
import 'package:celest_cloud_hub/src/database/cloud_hub_database.steps.dart';
56
import 'package:celest_cloud_hub/src/database/db_functions.dart';
67
import 'package:celest_cloud_hub/src/project.dart';
78
import 'package:celest_cloud_hub/src/services/service_mixin.dart';
@@ -44,7 +45,7 @@ final class CloudHubDatabase extends $CloudHubDatabase
4445
}
4546

4647
@override
47-
int get schemaVersion => 1;
48+
int get schemaVersion => 2;
4849

4950
static final Entity rootOrg = Entity(
5051
uid: const EntityUid.of('Celest::Organization', 'celest-dev'),
@@ -53,44 +54,39 @@ final class CloudHubDatabase extends $CloudHubDatabase
5354
static final Logger _logger = Logger('CloudHubDatabase');
5455

5556
@override
56-
MigrationStrategy get migration => MigrationStrategy(
57-
onCreate: (m) async {
58-
await m.createAll();
59-
},
60-
onUpgrade: (m, from, to) async {
61-
await cloudAuth.onUpgrade(m);
62-
},
57+
MigrationStrategy get migration => createMigration(
58+
onUpgrade: stepByStep(
59+
from1To2: (m, schema) async {
60+
await m.addColumn(
61+
schema.projectEnvironmentStates,
62+
schema.projectEnvironmentStates.flyVolumeId,
63+
);
64+
},
65+
),
6366
beforeOpen: (details) async {
6467
final versionRow =
6568
await customSelect('SELECT sqlite_version() as version;').getSingle();
6669
final version = versionRow.read<String>('version');
6770
_logger.config('Using SQLite v$version');
68-
69-
await withoutForeignKeys(() async {
70-
if (details.wasCreated) {
71-
await cloudAuth.seed(
72-
additionalCedarTypes: {
73-
'Celest::Operation',
74-
'Celest::Organization',
75-
'Celest::Organization::Member',
76-
'Celest::Project',
77-
'Celest::Project::Member',
78-
'Celest::Project::Environment',
79-
'Celest::Project::Environment::Member',
80-
},
81-
additionalCedarEntities: {
82-
rootOrg.uid: rootOrg,
83-
ProjectEnvironmentAction.deploy: Entity(
84-
uid: ProjectEnvironmentAction.deploy,
85-
parents: [CelestAction.owner],
86-
),
87-
},
88-
additionalCedarPolicies: corePolicySet,
89-
);
90-
}
91-
await cloudAuth.upsertProject(project: project);
92-
});
9371
},
72+
project: project,
73+
additionalCedarTypes: {
74+
'Celest::Operation',
75+
'Celest::Organization',
76+
'Celest::Organization::Member',
77+
'Celest::Project',
78+
'Celest::Project::Member',
79+
'Celest::Project::Environment',
80+
'Celest::Project::Environment::Member',
81+
},
82+
additionalCedarEntities: {
83+
rootOrg.uid: rootOrg,
84+
ProjectEnvironmentAction.deploy: Entity(
85+
uid: ProjectEnvironmentAction.deploy,
86+
parents: [CelestAction.owner],
87+
),
88+
},
89+
additionalCedarPolicies: corePolicySet,
9490
);
9591

9692
/// Runs [action] in a context without foreign keys enabled.

0 commit comments

Comments
 (0)