From 8a58025fef9e1446342dad4570a53eefb0852cc1 Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Mon, 9 Dec 2024 14:06:53 +0000 Subject: [PATCH] sst stuff --- .github/workflows/deploy_examples.yml | 17 +++- .../.sst/platform/config.d.ts | 8 +- examples/linearlite/package.json | 1 + examples/linearlite/sst-env.d.ts | 10 ++ examples/linearlite/sst.config.ts | 99 +++++++++++++++++++ examples/linearlite/tsconfig.json | 3 +- pnpm-lock.yaml | 3 + 7 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 examples/linearlite/sst-env.d.ts create mode 100644 examples/linearlite/sst.config.ts diff --git a/.github/workflows/deploy_examples.yml b/.github/workflows/deploy_examples.yml index 358c8abf84..96473c0b05 100644 --- a/.github/workflows/deploy_examples.yml +++ b/.github/workflows/deploy_examples.yml @@ -25,6 +25,8 @@ jobs: NEON_PROJECT_ID: ${{ secrets.NEON_PROJECT_ID }} ELECTRIC_API: ${{ secrets.ELECTRIC_API }} ELECTRIC_ADMIN_API: ${{ secrets.ELECTRIC_ADMIN_API }} + LINEARLITE_SUPABASE_PROJECT_ID: ${{ secrets.LINEARLITE_SUPABASE_PROJECT_ID }} + LINEARLITE_SUPABASE_PROJECT_PASSWORD: ${{ secrets.LINEARLITE_SUPABASE_PROJECT_PASSWORD }} # HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY }} TODO steps: @@ -48,6 +50,18 @@ jobs: restore-keys: | sst-cache-main-${{ runner.os }} + - name: Deploy Linearlite + working-directory: examples/linearlite + run: | + pnpm sst deploy --stage ${{ env.DEPLOY_ENV }} + if [ -f ".sst/outputs.json" ]; then + linearlite=$(jq -r '.website' .sst/outputs.json) + echo "linearlite=$linearlite" >> $GITHUB_ENV + else + echo "sst outputs file not found. Exiting." + exit 1 + fi + - name: Deploy Linearlite Read Only working-directory: examples/linearlite-read-only run: | @@ -60,7 +74,6 @@ jobs: exit 1 fi - - name: Deploy NextJs example working-directory: examples/nextjs-example run: | @@ -79,11 +92,13 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | + const linearlite = process.env.linearlite; const linearlite_read_only = process.env.linearlite_read_only; const nextjs = process.env.nextjs; const prNumber = context.issue.number; const commentBody = `## Examples + - linearlite: ${linearlite} - linearlite-read-only: ${linearlite_read_only} - nextjs: ${nextjs} `; diff --git a/examples/linearlite-read-only/.sst/platform/config.d.ts b/examples/linearlite-read-only/.sst/platform/config.d.ts index 08a1c1a1c1..012a6e7551 100644 --- a/examples/linearlite-read-only/.sst/platform/config.d.ts +++ b/examples/linearlite-read-only/.sst/platform/config.d.ts @@ -2,22 +2,22 @@ import "./src/global.d.ts" import "../types.generated" import { AppInput, App, Config } from "./src/config" import * as _neon from "@sst-provider/neon"; -import * as _cloudflare from "@pulumi/cloudflare"; import * as _aws from "@pulumi/aws"; +import * as _cloudflare from "@pulumi/cloudflare"; declare global { // @ts-expect-error export import neon = _neon // @ts-expect-error - export import cloudflare = _cloudflare - // @ts-expect-error export import aws = _aws + // @ts-expect-error + export import cloudflare = _cloudflare interface Providers { providers?: { "neon"?: (_neon.ProviderArgs & { version?: string }) | boolean | string; - "cloudflare"?: (_cloudflare.ProviderArgs & { version?: string }) | boolean | string; "aws"?: (_aws.ProviderArgs & { version?: string }) | boolean | string; + "cloudflare"?: (_cloudflare.ProviderArgs & { version?: string }) | boolean | string; } } export const $config: ( diff --git a/examples/linearlite/package.json b/examples/linearlite/package.json index 0f37687734..8d49b8cec9 100644 --- a/examples/linearlite/package.json +++ b/examples/linearlite/package.json @@ -94,6 +94,7 @@ "fs-extra": "^10.0.0", "globals": "^15.13.0", "postcss": "^8.4.39", + "sst": "3.3.7", "supabase": "^1.226.3", "tailwindcss": "^3.4.4", "tsx": "^4.19.1", diff --git a/examples/linearlite/sst-env.d.ts b/examples/linearlite/sst-env.d.ts new file mode 100644 index 0000000000..e973cf25d9 --- /dev/null +++ b/examples/linearlite/sst-env.d.ts @@ -0,0 +1,10 @@ +/* This file is auto-generated by SST. Do not edit. */ +/* tslint:disable */ +/* eslint-disable */ +/* deno-fmt-ignore-file */ +import "sst" +export {} +declare module "sst" { + export interface Resource { + } +} diff --git a/examples/linearlite/sst.config.ts b/examples/linearlite/sst.config.ts new file mode 100644 index 0000000000..b43d0abd6d --- /dev/null +++ b/examples/linearlite/sst.config.ts @@ -0,0 +1,99 @@ +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// + +import { execSync } from 'child_process' + +const isProduction = (stage: string) => + stage.toLocaleLowerCase() === `production` + +export default $config({ + app(input) { + return { + name: `linearlite`, + removal: isProduction(input?.stage) ? `retain` : `remove`, + home: `aws`, + providers: { + cloudflare: `5.42.0`, + aws: { + version: `6.57.0`, + }, + }, + } + }, + async run() { + try { + const databaseUri = $interpolate`postgresql://postgres:${process.env.LINEARLITE_SUPABASE_PROJECT_PASSWORD}@db.${process.env.LINEARLITE_SUPABASE_PROJECT_ID}.supabase.co:5432/postgres` + + // applyMigrations() + databaseUri.apply(applyMigrations) + + const electricInfo = databaseUri.apply((uri) => + addDatabaseToElectric(uri) + ) + + if (!process.env.ELECTRIC_API) { + throw new Error(`ELECTRIC_API environment variable is required`) + } + + const website = new sst.aws.StaticSite('linearlite-website', { + build: { + command: 'npm run build', + output: 'dist', + }, + environment: { + VITE_ELECTRIC_URL: process.env.ELECTRIC_API, + VITE_ELECTRIC_TOKEN: electricInfo.token, + VITE_ELECTRIC_DATABASE_ID: electricInfo.id, + }, + domain: { + name: `linearlite${isProduction($app.stage) ? `` : `-stage-${$app.stage}`}.examples.electric-sql.com`, + dns: sst.cloudflare.dns(), + }, + dev: { + command: 'npm run vite', + }, + }) + + return { + databaseUri, + database_id: electricInfo.id, + electric_token: electricInfo.token, + website: website.url, + } + } catch (e) { + console.error(`Failed to deploy todo app ${$app.stage} stack`, e) + } + }, +}) + +function applyMigrations(uri: string) { + execSync(`pnpm exec pg-migrations apply --directory ./db/migrations`, { + env: { + ...process.env, + DATABASE_URL: uri, + }, + }) +} + +async function addDatabaseToElectric( + uri: string +): Promise<{ id: string; token: string }> { + const adminApi = process.env.ELECTRIC_ADMIN_API + + const result = await fetch(`${adminApi}/v1/databases`, { + method: `PUT`, + headers: { 'Content-Type': `application/json` }, + body: JSON.stringify({ + database_url: uri, + region: `us-east-1`, + }), + }) + + if (!result.ok) { + throw new Error( + `Could not add database to Electric (${result.status}): ${await result.text()}` + ) + } + + return await result.json() +} diff --git a/examples/linearlite/tsconfig.json b/examples/linearlite/tsconfig.json index a462695a92..b2078d7e10 100644 --- a/examples/linearlite/tsconfig.json +++ b/examples/linearlite/tsconfig.json @@ -21,5 +21,6 @@ "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, - "include": ["src"] + "include": ["src"], + "exclude": ["sst.config.ts"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1f0b210a5..7b5eb115dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -350,6 +350,9 @@ importers: postcss: specifier: ^8.4.39 version: 8.4.47 + sst: + specifier: 3.3.7 + version: 3.3.7(hono@4.6.13) supabase: specifier: ^1.226.3 version: 1.226.4