From 95b1e69da83298fa98eda7ef998ae602130677f3 Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Thu, 9 Mar 2023 14:50:31 -0600 Subject: [PATCH] chore: remove shorebird_code_push_api (#51) --- .../deploy_shorebird_code_push_api.yaml | 61 ------------ .github/workflows/main.yaml | 5 +- README.md | 1 - .../shorebird_code_push_api/.dockerignore | 9 -- packages/shorebird_code_push_api/.gitignore | 9 -- packages/shorebird_code_push_api/Dockerfile | 27 ------ packages/shorebird_code_push_api/README.md | 47 --------- .../analysis_options.yaml | 4 - .../shorebird_code_push_api/bin/server.dart | 41 -------- .../lib/src/config.dart | 1 - .../lib/src/middleware/api_key_verifier.dart | 13 --- .../src/middleware/http_client_provider.dart | 9 -- .../lib/src/middleware/middleware.dart | 3 - .../middleware/version_store_provider.dart | 7 -- .../lib/src/provider.dart | 25 ----- .../check_for_updates/check_for_updates.dart | 2 - .../check_for_updates_handler.dart | 39 -------- .../models/check_for_updates_request.dart | 31 ------ .../models/check_for_updates_response.dart | 35 ------- .../check_for_updates/models/models.dart | 2 - .../download_engine/download_engine.dart | 1 - .../download_engine_handler.dart | 27 ------ .../download_release/download_release.dart | 1 - .../download_release_handler.dart | 19 ---- .../lib/src/routes/routes.dart | 4 - .../routes/upload_release/upload_release.dart | 1 - .../upload_release_handler.dart | 45 --------- .../lib/src/version_store.dart | 56 ----------- packages/shorebird_code_push_api/pubspec.yaml | 22 ----- .../test/fixtures/release.txt | 0 .../src/middleware/api_key_verifier_test.dart | 49 ---------- .../middleware/http_client_provider_test.dart | 24 ----- .../version_store_provider_test.dart | 24 ----- .../test/src/provider_test.dart | 45 --------- .../check_for_updates_handler_test.dart | 95 ------------------- .../download_engine_handler_test.dart | 57 ----------- .../download_release_handler_test.dart | 42 -------- .../test/src/version_store_test.dart | 61 ------------ 38 files changed, 1 insertion(+), 943 deletions(-) delete mode 100644 .github/workflows/deploy_shorebird_code_push_api.yaml delete mode 100644 packages/shorebird_code_push_api/.dockerignore delete mode 100644 packages/shorebird_code_push_api/.gitignore delete mode 100644 packages/shorebird_code_push_api/Dockerfile delete mode 100644 packages/shorebird_code_push_api/README.md delete mode 100644 packages/shorebird_code_push_api/analysis_options.yaml delete mode 100644 packages/shorebird_code_push_api/bin/server.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/config.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/middleware/api_key_verifier.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/middleware/http_client_provider.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/middleware/middleware.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/middleware/version_store_provider.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/provider.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates_handler.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_request.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_response.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/models.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine_handler.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/download_release/download_release.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/download_release/download_release_handler.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/routes.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release_handler.dart delete mode 100644 packages/shorebird_code_push_api/lib/src/version_store.dart delete mode 100644 packages/shorebird_code_push_api/pubspec.yaml delete mode 100644 packages/shorebird_code_push_api/test/fixtures/release.txt delete mode 100644 packages/shorebird_code_push_api/test/src/middleware/api_key_verifier_test.dart delete mode 100644 packages/shorebird_code_push_api/test/src/middleware/http_client_provider_test.dart delete mode 100644 packages/shorebird_code_push_api/test/src/middleware/version_store_provider_test.dart delete mode 100644 packages/shorebird_code_push_api/test/src/provider_test.dart delete mode 100644 packages/shorebird_code_push_api/test/src/routes/check_for_updates/check_for_updates_handler_test.dart delete mode 100644 packages/shorebird_code_push_api/test/src/routes/download_engine/download_engine_handler_test.dart delete mode 100644 packages/shorebird_code_push_api/test/src/routes/download_release/download_release_handler_test.dart delete mode 100644 packages/shorebird_code_push_api/test/src/version_store_test.dart diff --git a/.github/workflows/deploy_shorebird_code_push_api.yaml b/.github/workflows/deploy_shorebird_code_push_api.yaml deleted file mode 100644 index 87ce0a56..00000000 --- a/.github/workflows/deploy_shorebird_code_push_api.yaml +++ /dev/null @@ -1,61 +0,0 @@ -name: deploy_shorebird_code_push_api - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - push: - branches: - - main - paths: - - ".github/workflows/deploy_shorebird_code_push_api.yaml" - - "packages/shorebird_code_push_api/bin/**" - - "packages/shorebird_code_push_api/lib/**" - - "packages/shorebird_code_push_api/test/**" - - "packages/shorebird_code_push_api/pubspec.yaml" - -env: - PROJECT_ID: shorebird-code-push-api - SERVICE: shorebird-code-push-api - REGION: us-central1 - -jobs: - deploy: - defaults: - run: - working-directory: packages/shorebird_code_push_api - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Setup Cloud SDK - uses: google-github-actions/setup-gcloud@v0.2.0 - with: - project_id: ${{ env.PROJECT_ID }} - service_account_key: ${{ secrets.CLOUD_RUN_SA }} - export_default_credentials: true - - - name: Authorize Docker Push - run: gcloud auth configure-docker - - - name: Build and Push Container - run: |- - docker build -t gcr.io/${{ env.PROJECT_ID }}/${{ env.SERVICE }}:${{ github.sha }} . - docker push gcr.io/${{ env.PROJECT_ID }}/${{ env.SERVICE }}:${{ github.sha }} - - - name: Deploy to Cloud Run - id: deploy - uses: google-github-actions/deploy-cloudrun@v0.4.0 - with: - service: ${{ env.SERVICE }} - image: gcr.io/${{ env.PROJECT_ID }}/${{ env.SERVICE }}:${{ github.sha }} - region: ${{ env.REGION }} - - - name: Show Output - run: echo ${{ steps.deploy.outputs.url }} - - - name: Ping - run: curl "${{ steps.deploy.outputs.url }}" diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 10ab4fbd..be80c503 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -31,10 +31,7 @@ jobs: shorebird_cli: - ./.github/actions/dart_package - packages/shorebird_cli/** - - packages/shorebird_code_push_api_client/** - shorebird_code_push_api: - - ./.github/actions/dart_package - - packages/shorebird_code_push_api/** + - packages/shorebird_code_push_api_client/** shorebird_code_push_api_client: - ./.github/actions/dart_package - packages/shorebird_code_push_api_client/** diff --git a/README.md b/README.md index 9e2ba6da..9c7c8862 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ This repository is a monorepo containing the following packages: | Package | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | [shorebird_cli](packages/shorebird_cli/README.md) | Command-line which allows developers to interact with various Shorebird services | -| [shorebird_code_push_api](packages/shorebird_code_push_api/README.md) | Server which exposes endpoints to support CodePush for Flutter applications | | [shorebird_code_push_api_client](packages/shorebird_code_push_api_client/README.md) | Dart library which allows Dart applications to interact with the ShoreBird CodePush API | | [shorebird_code_push_updater](updater/README.md) | Rust library which handles the CodePush logic and does the real update work | diff --git a/packages/shorebird_code_push_api/.dockerignore b/packages/shorebird_code_push_api/.dockerignore deleted file mode 100644 index 5ff18b62..00000000 --- a/packages/shorebird_code_push_api/.dockerignore +++ /dev/null @@ -1,9 +0,0 @@ -.dockerignore -Dockerfile -build/ -.dart_tool/ -.git/ -.github/ -.gitignore -.idea/ -.packages \ No newline at end of file diff --git a/packages/shorebird_code_push_api/.gitignore b/packages/shorebird_code_push_api/.gitignore deleted file mode 100644 index a4385834..00000000 --- a/packages/shorebird_code_push_api/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# See https://www.dartlang.org/guides/libraries/private-files - -# Files and directories created by pub -.dart_tool/ -.packages -build/ -pubspec.lock -coverage/ -cache/ \ No newline at end of file diff --git a/packages/shorebird_code_push_api/Dockerfile b/packages/shorebird_code_push_api/Dockerfile deleted file mode 100644 index 6907fdc3..00000000 --- a/packages/shorebird_code_push_api/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -# Official Dart image: https://hub.docker.com/_/dart -# Specify the Dart SDK base image version using dart: (ex: dart:2.19) -FROM dart:stable AS build - -# Resolve app dependencies. -WORKDIR /app - -# package:shorebird_code_push_api -COPY pubspec.* ./ -RUN dart pub get - -# Copy app source code and AOT compile it. -COPY . . - -# Ensure packages are still up-to-date if anything has changed -RUN dart pub get --offline -RUN dart compile exe bin/server.dart -o bin/server - -# Build minimal serving image from AOT-compiled `/server` and required system -# libraries and configuration files stored in `/runtime/` from the build stage. -FROM scratch -COPY --from=build /runtime/ / -COPY --from=build /app/bin/server /app/bin/ - -# Start server. -EXPOSE 8080 -CMD ["/app/bin/server"] \ No newline at end of file diff --git a/packages/shorebird_code_push_api/README.md b/packages/shorebird_code_push_api/README.md deleted file mode 100644 index 3bd67725..00000000 --- a/packages/shorebird_code_push_api/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## Shorebird CodePush API - -**🚧 This project is under heavy development 🚧** - -The Shorebird CodePush API is a server which exposes endpoints to support CodePush for Flutter applications. - -## Getting Started 🚀 - -The Shorebird CodePush API is written in [Dart](https://dart.dev) and uses [Shelf](https://pub.dev/packages/shelf). - -### Running Locally ☁️💻 - -To run the server locally, run the following command from the current directory: - -```sh -dart bin/server.dart -``` - -This will start the server on [localhost:8080](http://localhost:8080). - -### Running in Docker 🐳 - -To run the server in Docker, make sure you have [Docker installed](https://docs.docker.com/get-docker/). - -You can create an image: - -```sh -docker build -q . -``` - -Once you have created an image, you can run the image via: - -```sh -docker run -d -p 8080:8080 --rm -``` - -To kill the container: - -```sh -docker kill -``` - -If you wish to delete an image you can run: - -```sh -docker rmi -``` diff --git a/packages/shorebird_code_push_api/analysis_options.yaml b/packages/shorebird_code_push_api/analysis_options.yaml deleted file mode 100644 index d767e5d3..00000000 --- a/packages/shorebird_code_push_api/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:very_good_analysis/analysis_options.4.0.0.yaml -linter: - rules: - public_member_api_docs: false diff --git a/packages/shorebird_code_push_api/bin/server.dart b/packages/shorebird_code_push_api/bin/server.dart deleted file mode 100644 index 3fc6b968..00000000 --- a/packages/shorebird_code_push_api/bin/server.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:shelf/shelf.dart'; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_router/shelf_router.dart' as shelf_router; -import 'package:shorebird_code_push_api/src/middleware/middleware.dart'; -import 'package:shorebird_code_push_api/src/routes/routes.dart'; - -Future main() async { - final apiKeys = - (json.decode(Platform.environment['CODE_PUSH_API_KEYS']!) as List) - .cast(); - - final port = int.parse(Platform.environment['PORT'] ?? '8080'); - final router = shelf_router.Router() - ..all('/', (_) => Response(HttpStatus.noContent)) - ..post('/api/v1/updates', checkForUpdatesHandler) - ..get('/api/v1/releases/', downloadReleaseHandler) - ..post( - '/api/v1/releases', - const Pipeline() - .addMiddleware(apiKeyVerifier(apiKeys)) - .addHandler(uploadReleaseHandler), - ) - ..get('/api/v1/engines/', downloadEngineHandler); - - final handler = const Pipeline() - .addMiddleware(versionStoreProvider) - .addMiddleware(httpClientProvider()) - .addHandler(router.call); - - final server = await shelf_io.serve( - logRequests().addHandler(handler), - InternetAddress.anyIPv4, - port, - ); - - // ignore: avoid_print - print('Serving at http://${server.address.host}:${server.port}'); -} diff --git a/packages/shorebird_code_push_api/lib/src/config.dart b/packages/shorebird_code_push_api/lib/src/config.dart deleted file mode 100644 index bf28939f..00000000 --- a/packages/shorebird_code_push_api/lib/src/config.dart +++ /dev/null @@ -1 +0,0 @@ -const cachePath = 'cache'; diff --git a/packages/shorebird_code_push_api/lib/src/middleware/api_key_verifier.dart b/packages/shorebird_code_push_api/lib/src/middleware/api_key_verifier.dart deleted file mode 100644 index a8e7ec62..00000000 --- a/packages/shorebird_code_push_api/lib/src/middleware/api_key_verifier.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'dart:io'; - -import 'package:shelf/shelf.dart'; - -Middleware apiKeyVerifier([List keys = const []]) { - return (handler) { - return (request) async { - final apiKey = request.headers['x-api-key']; - if (!keys.contains(apiKey)) return Response(HttpStatus.unauthorized); - return handler(request); - }; - }; -} diff --git a/packages/shorebird_code_push_api/lib/src/middleware/http_client_provider.dart b/packages/shorebird_code_push_api/lib/src/middleware/http_client_provider.dart deleted file mode 100644 index f69bd176..00000000 --- a/packages/shorebird_code_push_api/lib/src/middleware/http_client_provider.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:http/http.dart' as http; -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; - -http.Client? _httpClient; - -Middleware httpClientProvider() { - return provider((_) => _httpClient ??= http.Client()); -} diff --git a/packages/shorebird_code_push_api/lib/src/middleware/middleware.dart b/packages/shorebird_code_push_api/lib/src/middleware/middleware.dart deleted file mode 100644 index 83dce027..00000000 --- a/packages/shorebird_code_push_api/lib/src/middleware/middleware.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'api_key_verifier.dart'; -export 'http_client_provider.dart'; -export 'version_store_provider.dart'; diff --git a/packages/shorebird_code_push_api/lib/src/middleware/version_store_provider.dart b/packages/shorebird_code_push_api/lib/src/middleware/version_store_provider.dart deleted file mode 100644 index 50f52335..00000000 --- a/packages/shorebird_code_push_api/lib/src/middleware/version_store_provider.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:shorebird_code_push_api/src/config.dart' as config; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/version_store.dart'; - -const _versionStore = VersionStore(cachePath: config.cachePath); - -final versionStoreProvider = provider((_) => _versionStore); diff --git a/packages/shorebird_code_push_api/lib/src/provider.dart b/packages/shorebird_code_push_api/lib/src/provider.dart deleted file mode 100644 index c5a8cf19..00000000 --- a/packages/shorebird_code_push_api/lib/src/provider.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:shelf/shelf.dart'; - -extension ProvideExtension on Request { - Request provide(T Function() create) { - return change(context: {...context, '$T': create}); - } - - T lookup() { - final value = context['$T']; - if (value == null) { - throw StateError( - ''' -request.lookup<$T>() called with a request that does not contain a $T. -''', - ); - } - return (value as T Function())(); - } -} - -Middleware provider(T Function(Request request) create) { - return (handler) { - return (req) => handler(req.provide(() => create(req))); - }; -} diff --git a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates.dart b/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates.dart deleted file mode 100644 index 63a00823..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'check_for_updates_handler.dart'; -export 'models/models.dart'; diff --git a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates_handler.dart b/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates_handler.dart deleted file mode 100644 index 1028a1f6..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/check_for_updates_handler.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/routes/check_for_updates/check_for_updates.dart'; -import 'package:shorebird_code_push_api/src/version_store.dart'; - -Future checkForUpdatesHandler(Request request) async { - late final CheckForUpdatesRequest checkForUpdatesRequest; - try { - checkForUpdatesRequest = CheckForUpdatesRequest.fromJson( - jsonDecode(await request.readAsString()) as Map, - ); - } catch (_) { - return Response.badRequest( - body: 'Invalid request body', - headers: {HttpHeaders.contentTypeHeader: ContentType.text.value}, - ); - } - - final store = request.lookup(); - final latestVersion = store.latestVersionForClient( - checkForUpdatesRequest.clientId, - currentVersion: checkForUpdatesRequest.version, - ); - - final response = latestVersion == null - ? const CheckForUpdatesResponse() - : CheckForUpdatesResponse( - updateAvailable: true, - update: Update(version: latestVersion, hash: ''), - ); - - return Response.ok( - json.encode(response.toJson()), - headers: {HttpHeaders.contentTypeHeader: ContentType.json.value}, - ); -} diff --git a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_request.dart b/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_request.dart deleted file mode 100644 index 0578b68a..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_request.dart +++ /dev/null @@ -1,31 +0,0 @@ -class CheckForUpdatesRequest { - const CheckForUpdatesRequest({ - required this.version, - required this.platform, - required this.arch, - required this.clientId, - }); - - factory CheckForUpdatesRequest.fromJson(Map json) { - return CheckForUpdatesRequest( - version: (json['version'] ?? '') as String, - platform: json['platform'] as String, - arch: json['arch'] as String, - clientId: json['client_id'] as String, - ); - } - - Map toJson() { - return { - 'version': version, - 'platform': platform, - 'arch': arch, - 'client_id': clientId, - }; - } - - final String version; - final String platform; - final String arch; - final String clientId; -} diff --git a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_response.dart b/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_response.dart deleted file mode 100644 index b6d59ddf..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/check_for_updates_response.dart +++ /dev/null @@ -1,35 +0,0 @@ -class CheckForUpdatesResponse { - const CheckForUpdatesResponse({ - this.updateAvailable = false, - this.update, - }); - - final bool updateAvailable; - final Update? update; - - Map toJson() { - return { - 'update_available': updateAvailable, - if (update != null) 'update': update!.toJson(), - }; - } -} - -class Update { - const Update({required this.version, required this.hash}); - - final String version; - final String hash; - - Map toJson() { - return { - 'version': version, - 'hash': hash, - 'download_url': downloadUrlForVersion(version), - }; - } - - String downloadUrlForVersion(String version) { - return 'https://shorebird-code-push-api-cypqazu4da-uc.a.run.app/api/v1/releases/$version.txt'; - } -} diff --git a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/models.dart b/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/models.dart deleted file mode 100644 index 030bbd45..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/check_for_updates/models/models.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'check_for_updates_request.dart'; -export 'check_for_updates_response.dart'; diff --git a/packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine.dart b/packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine.dart deleted file mode 100644 index 5cb510aa..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine.dart +++ /dev/null @@ -1 +0,0 @@ -export 'download_engine_handler.dart'; diff --git a/packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine_handler.dart b/packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine_handler.dart deleted file mode 100644 index 4fdbc418..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/download_engine/download_engine_handler.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'dart:io'; - -import 'package:http/http.dart' as http; -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; - -final _engineUrl = Uri.parse( - 'https://storage.googleapis.com/download/storage/v1/b/shorebird-code-push-api.appspot.com/o/${Uri.encodeComponent('engines/dev/engine.zip')}?alt=media', -); - -Future downloadEngineHandler(Request request, String revision) async { - final httpClient = request.lookup(); - final req = http.Request('GET', _engineUrl); - req.headers.addAll( - { - 'Content-Type': 'application/octet-stream', - 'Connection': 'close', - }, - ); - final response = await httpClient.send(req); - - if (response.statusCode != HttpStatus.ok) { - return Response(response.statusCode, body: response.stream); - } - - return Response.ok(response.stream); -} diff --git a/packages/shorebird_code_push_api/lib/src/routes/download_release/download_release.dart b/packages/shorebird_code_push_api/lib/src/routes/download_release/download_release.dart deleted file mode 100644 index d4a93c91..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/download_release/download_release.dart +++ /dev/null @@ -1 +0,0 @@ -export 'download_release_handler.dart'; diff --git a/packages/shorebird_code_push_api/lib/src/routes/download_release/download_release_handler.dart b/packages/shorebird_code_push_api/lib/src/routes/download_release/download_release_handler.dart deleted file mode 100644 index d198d46b..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/download_release/download_release_handler.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'dart:io'; - -import 'package:path/path.dart' as path; -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/version_store.dart'; - -Future downloadReleaseHandler( - Request request, - String versionWithExtension, -) async { - final version = path.withoutExtension(versionWithExtension); - final releasePath = - request.lookup().filePathForVersion(version); - final file = File(releasePath); - if (!file.existsSync()) return Response.notFound('Release not found'); - final bytes = file.openRead(); - return Response.ok(bytes); -} diff --git a/packages/shorebird_code_push_api/lib/src/routes/routes.dart b/packages/shorebird_code_push_api/lib/src/routes/routes.dart deleted file mode 100644 index 9832524a..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/routes.dart +++ /dev/null @@ -1,4 +0,0 @@ -export 'check_for_updates/check_for_updates.dart'; -export 'download_engine/download_engine.dart'; -export 'download_release/download_release.dart'; -export 'upload_release/upload_release.dart'; diff --git a/packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release.dart b/packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release.dart deleted file mode 100644 index f2ad5914..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release.dart +++ /dev/null @@ -1 +0,0 @@ -export 'upload_release_handler.dart'; diff --git a/packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release_handler.dart b/packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release_handler.dart deleted file mode 100644 index a998638a..00000000 --- a/packages/shorebird_code_push_api/lib/src/routes/upload_release/upload_release_handler.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:io'; - -import 'package:shelf/shelf.dart'; -import 'package:shelf_multipart/form_data.dart'; -import 'package:shelf_multipart/multipart.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/version_store.dart'; - -Future uploadReleaseHandler(Request request) async { - if (!request.isMultipart || !request.isMultipartForm) { - return Response.badRequest(body: 'Expected multipart form request'); - } - - final store = request.lookup(); - - store.cacheDir.createSync(recursive: true); - - final nextVersion = store.getNextVersion(); - final path = store.filePathForVersion(nextVersion); - - var foundFile = false; - - try { - await for (final formData in request.multipartFormData) { - // 'file' is just the name of the field we used in this form. - if (formData.name == 'file') { - if (foundFile) { - throw Exception('Unexpected form data: ${formData.name}'); - } - final file = File(path); - await file.create(); - await file.writeAsBytes(await formData.part.readBytes(), flush: true); - foundFile = true; - continue; - } else { - throw Exception('Unexpected form data: ${formData.name}'); - } - } - if (!foundFile) throw Exception('Missing file'); - } catch (error) { - return Response.badRequest(body: error.toString()); - } - - return Response(HttpStatus.created, body: 'OK'); -} diff --git a/packages/shorebird_code_push_api/lib/src/version_store.dart b/packages/shorebird_code_push_api/lib/src/version_store.dart deleted file mode 100644 index dcbd1148..00000000 --- a/packages/shorebird_code_push_api/lib/src/version_store.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:version/version.dart'; - -int _compareVersions(String a, String b) { - return Version.parse(a).compareTo(Version.parse(b)); -} - -class VersionStore { - const VersionStore({required this.cachePath}); - - final String cachePath; - - Directory get cacheDir { - return Directory(p.join(Directory.current.path, cachePath)); - } - - // Should take an api key/product name, etc. - String getNextVersion() { - final latest = latestVersionForClient('client') ?? '0.0.0'; - final next = Version.parse(latest).incrementPatch().toString(); - return next; - } - - void addVersion(String version, List bytes) { - cacheDir.createSync(recursive: true); - final path = filePathForVersion(version); - File(path).writeAsBytesSync(bytes); - } - - String? latestVersionForClient(String clientId, {String? currentVersion}) { - final versions = _versionsForClientId(clientId).toList() - ..sort(_compareVersions); - if (versions.isEmpty) return null; - if (versions.last == currentVersion) return null; - - return versions.last; - } - - String filePathForVersion(String version) { - return p.join(cacheDir.path, '$version.txt'); - } - - Iterable _versionsForClientId(String clientId) { - // This should use the clientId to get a productId and look up the versions - // based on productId/architecture, etc. - try { - final dir = cacheDir; - final files = dir.listSync(); - return files.map((e) => p.basenameWithoutExtension(e.path)); - } catch (e) { - return []; - } - } -} diff --git a/packages/shorebird_code_push_api/pubspec.yaml b/packages/shorebird_code_push_api/pubspec.yaml deleted file mode 100644 index fae5d360..00000000 --- a/packages/shorebird_code_push_api/pubspec.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: shorebird_code_push_api -description: Server which exposes endpoints to support CodePush for Flutter applications -version: 0.1.0+1 -repository: https://github.com/shorebirdtech/shorebird - -publish_to: none - -environment: - sdk: ">=2.19.0 <3.0.0" - -dependencies: - http: ^0.13.5 - path: ^1.8.3 - shelf: ^1.4.0 - shelf_multipart: ^1.0.0 - shelf_router: ^1.1.3 - version: ^3.0.2 - -dev_dependencies: - mocktail: ^0.3.0 - test: ^1.19.2 - very_good_analysis: ^4.0.0 diff --git a/packages/shorebird_code_push_api/test/fixtures/release.txt b/packages/shorebird_code_push_api/test/fixtures/release.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/shorebird_code_push_api/test/src/middleware/api_key_verifier_test.dart b/packages/shorebird_code_push_api/test/src/middleware/api_key_verifier_test.dart deleted file mode 100644 index c1aae192..00000000 --- a/packages/shorebird_code_push_api/test/src/middleware/api_key_verifier_test.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:io'; - -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/middleware/middleware.dart'; -import 'package:test/test.dart'; - -void main() { - group('apiKeyVerifier', () { - const keys = ['valid-key']; - - test('returns 401 if no key is provided', () async { - final handler = const Pipeline() - .addMiddleware(apiKeyVerifier()) - .addHandler((_) => Response.ok('OK')); - - final request = Request('GET', Uri.parse('http://localhost/')); - final response = await handler(request); - expect(response.statusCode, equals(HttpStatus.unauthorized)); - }); - - test('returns 401 if key is invalid', () async { - final handler = const Pipeline() - .addMiddleware(apiKeyVerifier(keys)) - .addHandler((_) => Response.ok('OK')); - - final request = Request( - 'GET', - Uri.parse('http://localhost/'), - headers: {'x-api-key': 'invalid-key'}, - ); - final response = await handler(request); - expect(response.statusCode, equals(HttpStatus.unauthorized)); - }); - - test('returns 200 if key is valid', () async { - final handler = const Pipeline() - .addMiddleware(apiKeyVerifier(keys)) - .addHandler((_) => Response.ok('OK')); - - final request = Request( - 'GET', - Uri.parse('http://localhost/'), - headers: {'x-api-key': 'valid-key'}, - ); - final response = await handler(request); - expect(response.statusCode, equals(HttpStatus.ok)); - }); - }); -} diff --git a/packages/shorebird_code_push_api/test/src/middleware/http_client_provider_test.dart b/packages/shorebird_code_push_api/test/src/middleware/http_client_provider_test.dart deleted file mode 100644 index 5b0b0b69..00000000 --- a/packages/shorebird_code_push_api/test/src/middleware/http_client_provider_test.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:http/http.dart' as http; -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/middleware/middleware.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:test/test.dart'; - -void main() { - group('httpClientProvider', () { - test('provides an http client instance', () async { - http.Client? client; - - final handler = httpClientProvider()( - (req) async { - client = req.lookup(); - return Response.ok(''); - }, - ); - final request = Request('GET', Uri.parse('http://localhost/')); - - await handler(request); - expect(client, isNotNull); - }); - }); -} diff --git a/packages/shorebird_code_push_api/test/src/middleware/version_store_provider_test.dart b/packages/shorebird_code_push_api/test/src/middleware/version_store_provider_test.dart deleted file mode 100644 index 7f6ded73..00000000 --- a/packages/shorebird_code_push_api/test/src/middleware/version_store_provider_test.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/middleware/middleware.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/version_store.dart'; -import 'package:test/test.dart'; - -void main() { - group('versionStoreProvider', () { - test('provides a version store instance', () async { - VersionStore? store; - - final handler = versionStoreProvider( - (req) { - store = req.lookup(); - return Response.ok(''); - }, - ); - final request = Request('GET', Uri.parse('http://localhost/')); - - await handler(request); - expect(store, isNotNull); - }); - }); -} diff --git a/packages/shorebird_code_push_api/test/src/provider_test.dart b/packages/shorebird_code_push_api/test/src/provider_test.dart deleted file mode 100644 index 73993d4f..00000000 --- a/packages/shorebird_code_push_api/test/src/provider_test.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:io'; - -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:test/test.dart'; - -void main() { - test('values can be provided and read via middleware', () async { - const value = '__test_value__'; - Handler middleware(Handler handler) { - return (request) { - return handler(request.provide(() => value)); - }; - } - - Response onRequest(Request request) { - final value = request.lookup(); - return Response.ok(value); - } - - final handler = - const Pipeline().addMiddleware(middleware).addHandler(onRequest); - - final request = Request('GET', Uri.parse('http://localhost/')); - final response = await handler(request); - - await expectLater(response.statusCode, equals(HttpStatus.ok)); - await expectLater(await response.readAsString(), equals(value)); - }); - - test('A StateError is thrown when reading an un-provided value', () async { - Response onRequest(Request request) { - request.lookup(); - return Response.ok(''); - } - - final handler = const Pipeline() - .addMiddleware((handler) => handler) - .addHandler(onRequest); - - final request = Request('GET', Uri.parse('http://localhost/')); - - await expectLater(() => handler(request), throwsStateError); - }); -} diff --git a/packages/shorebird_code_push_api/test/src/routes/check_for_updates/check_for_updates_handler_test.dart b/packages/shorebird_code_push_api/test/src/routes/check_for_updates/check_for_updates_handler_test.dart deleted file mode 100644 index 743cc118..00000000 --- a/packages/shorebird_code_push_api/test/src/routes/check_for_updates/check_for_updates_handler_test.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:mocktail/mocktail.dart'; -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/routes/check_for_updates/check_for_updates.dart'; -import 'package:shorebird_code_push_api/src/version_store.dart'; -import 'package:test/test.dart'; - -class _MockVersionStore extends Mock implements VersionStore {} - -void main() { - group('checkForUpdatesHandler', () { - final uri = Uri.parse('http://localhost/'); - - late VersionStore store; - - setUp(() { - store = _MockVersionStore(); - }); - - test('returns 400 if request body is invalid', () async { - final request = Request('POST', uri); - final response = await checkForUpdatesHandler(request); - - expect(response.statusCode, HttpStatus.badRequest); - }); - - test( - 'returns 200 no update available ' - 'when unable to get latest version', () async { - const payload = CheckForUpdatesRequest( - version: '1.0.0', - platform: 'android', - arch: 'arm64', - clientId: 'client-id', - ); - - when( - () => store.latestVersionForClient( - any(), - currentVersion: any(named: 'currentVersion'), - ), - ).thenReturn(null); - - final request = Request( - 'POST', - uri, - body: json.encode(payload.toJson()), - ).provide(() => store); - - final response = await checkForUpdatesHandler(request); - - expect(response.statusCode, HttpStatus.ok); - - final body = await response.readAsString(); - expect(body, equals('{"update_available":false}')); - }); - - test('returns 200 update available when version is not latest', () async { - const payload = CheckForUpdatesRequest( - version: '1.0.0', - platform: 'android', - arch: 'arm64', - clientId: 'client-id', - ); - - when( - () => store.latestVersionForClient( - any(), - currentVersion: any(named: 'currentVersion'), - ), - ).thenReturn('1.0.1'); - - final request = Request( - 'POST', - uri, - body: json.encode(payload.toJson()), - ).provide(() => store); - - final response = await checkForUpdatesHandler(request); - - expect(response.statusCode, HttpStatus.ok); - - final body = await response.readAsString(); - expect( - body, - equals( - '{"update_available":true,"update":{"version":"1.0.1","hash":"","download_url":"https://shorebird-code-push-api-cypqazu4da-uc.a.run.app/api/v1/releases/1.0.1.txt"}}', - ), - ); - }); - }); -} diff --git a/packages/shorebird_code_push_api/test/src/routes/download_engine/download_engine_handler_test.dart b/packages/shorebird_code_push_api/test/src/routes/download_engine/download_engine_handler_test.dart deleted file mode 100644 index ccab841d..00000000 --- a/packages/shorebird_code_push_api/test/src/routes/download_engine/download_engine_handler_test.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'dart:io'; - -import 'package:http/http.dart' as http; -import 'package:mocktail/mocktail.dart'; -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/routes/download_engine/download_engine.dart'; -import 'package:test/test.dart'; - -class _MockHttpClient extends Mock implements http.Client {} - -class _FakeBaseRequest extends Fake implements http.BaseRequest {} - -void main() { - group('downloadEngineHandler', () { - final uri = Uri.parse('http://localhost/'); - late http.Client httpClient; - - setUpAll(() { - registerFallbackValue(_FakeBaseRequest()); - }); - - setUp(() { - httpClient = _MockHttpClient(); - }); - - test('returns error on failure', () async { - when( - () => httpClient.send(any()), - ).thenAnswer((_) async { - return http.StreamedResponse( - const Stream.empty(), - HttpStatus.unauthorized, - ); - }); - final request = Request('GET', uri).provide(() => httpClient); - - final response = await downloadEngineHandler(request, 'revision'); - expect(response.statusCode, equals(HttpStatus.unauthorized)); - }); - - test('returns bytes on success', () async { - when( - () => httpClient.send(any()), - ).thenAnswer((_) async { - return http.StreamedResponse( - const Stream.empty(), - HttpStatus.ok, - ); - }); - final request = Request('GET', uri).provide(() => httpClient); - - final response = await downloadEngineHandler(request, 'revision'); - expect(response.statusCode, equals(HttpStatus.ok)); - }); - }); -} diff --git a/packages/shorebird_code_push_api/test/src/routes/download_release/download_release_handler_test.dart b/packages/shorebird_code_push_api/test/src/routes/download_release/download_release_handler_test.dart deleted file mode 100644 index 9c7b55be..00000000 --- a/packages/shorebird_code_push_api/test/src/routes/download_release/download_release_handler_test.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'dart:io'; - -import 'package:mocktail/mocktail.dart'; -import 'package:path/path.dart' as path; -import 'package:shelf/shelf.dart'; -import 'package:shorebird_code_push_api/src/provider.dart'; -import 'package:shorebird_code_push_api/src/routes/download_release/download_release.dart'; -import 'package:shorebird_code_push_api/src/version_store.dart'; -import 'package:test/test.dart'; - -class _MockVersionStore extends Mock implements VersionStore {} - -void main() { - group('downloadReleaseHandler', () { - final uri = Uri.parse('http://localhost/'); - late VersionStore store; - - setUp(() { - store = _MockVersionStore(); - }); - - test('returns 404 if release not found', () async { - when(() => store.filePathForVersion('1.0.0')).thenReturn('not-found'); - - final request = Request('GET', uri).provide(() => store); - final response = await downloadReleaseHandler(request, '1.0.0.txt'); - - expect(response.statusCode, HttpStatus.notFound); - }); - - test('returns 200 if release found', () async { - when( - () => store.filePathForVersion('1.0.0'), - ).thenReturn(path.join('test', 'fixtures', 'release.txt')); - - final request = Request('GET', uri).provide(() => store); - final response = await downloadReleaseHandler(request, '1.0.0.txt'); - - expect(response.statusCode, HttpStatus.ok); - }); - }); -} diff --git a/packages/shorebird_code_push_api/test/src/version_store_test.dart b/packages/shorebird_code_push_api/test/src/version_store_test.dart deleted file mode 100644 index e2ff346b..00000000 --- a/packages/shorebird_code_push_api/test/src/version_store_test.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'dart:io'; - -import 'package:shorebird_code_push_api/src/version_store.dart'; -import 'package:test/test.dart'; - -void main() { - group('VersionStore', () { - group('getNextVersion', () { - test('returns 0.0.1 when no versions exist', () { - final tempDir = Directory.systemTemp.createTempSync(); - final store = VersionStore(cachePath: tempDir.path); - expect(store.getNextVersion(), equals('0.0.1')); - }); - - test('returns 0.0.2 when 0.0.1 exists', () { - final tempDir = Directory.systemTemp.createTempSync(); - final store = VersionStore(cachePath: tempDir.path) - ..addVersion('0.0.1', []); - expect(store.getNextVersion(), equals('0.0.2')); - }); - }); - - group('latestVersionForClient', () { - test('returns null when cache does not exist', () { - const store = VersionStore(cachePath: 'invalid-path'); - expect(store.latestVersionForClient('empty-client-id'), isNull); - }); - - test('returns null when no versions exist', () { - final tempDir = Directory.systemTemp.createTempSync(); - final store = VersionStore(cachePath: tempDir.path); - expect(store.latestVersionForClient('empty-client-id'), isNull); - }); - - test('returns latest version when multiple versions exist', () { - final tempDir = Directory.systemTemp.createTempSync(); - final store = VersionStore(cachePath: tempDir.path) - ..addVersion('0.0.1', []) - ..addVersion('0.0.2', []); - expect( - store.latestVersionForClient('empty-client-id'), - equals('0.0.2'), - ); - }); - - test('returns null when current version is the latest version', () { - final tempDir = Directory.systemTemp.createTempSync(); - final store = VersionStore(cachePath: tempDir.path) - ..addVersion('0.0.1', []) - ..addVersion('0.0.2', []); - expect( - store.latestVersionForClient( - 'empty-client-id', - currentVersion: '0.0.2', - ), - isNull, - ); - }); - }); - }); -}