Skip to content

Commit

Permalink
examples: add public deployment of LinearLite (#1929)
Browse files Browse the repository at this point in the history
Took changes from #1915 on
top of main

---------

Co-authored-by: Kyle Mathews <[email protected]>
Co-authored-by: rob <[email protected]>
  • Loading branch information
3 people authored Nov 15, 2024
1 parent b507743 commit 032a71d
Show file tree
Hide file tree
Showing 31 changed files with 3,961 additions and 3,219 deletions.
115 changes: 115 additions & 0 deletions .github/workflows/deploy_examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Deploy Examples

on:
push:
branches: ['main']
pull_request:
paths: ['examples/*/**']

concurrency:
group: ${{ github.event_name == 'push' && 'prod-deploy-group' || format('examples-pr-{0}', github.event.number) }}

jobs:
deploy-examples:
name: Deploy Examples
environment: ${{ github.event_name == 'push' && 'Production' || 'Pull request' }}
runs-on: ubuntu-latest

env:
DEPLOY_ENV: ${{ github.event_name == 'push' && 'production' || format('pr-{0}', github.event.number) }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_DEFAULT_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_DEFAULT_ACCOUNT_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
NEON_API_KEY: ${{ secrets.NEON_API_KEY }}
NEON_PROJECT_ID: ${{ secrets.NEON_PROJECT_ID }}
ELECTRIC_API: ${{ secrets.ELECTRIC_API }}
ELECTRIC_ADMIN_API: ${{ secrets.ELECTRIC_ADMIN_API }}
# HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY }} TODO

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Cache SST state
uses: actions/cache@v4
with:
path: .sst
key: sst-cache-main-${{ runner.os }}
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 NextJs example
working-directory: examples/nextjs-example
run: |
pnpm sst deploy --stage ${{ env.DEPLOY_ENV }}
if [ -f ".sst/outputs.json" ]; then
nextjs=$(jq -r '.website' .sst/outputs.json)
echo "nextjs=$nextjs" >> $GITHUB_ENV
else
echo "sst outputs file not found. Exiting."
exit 1
fi
- name: Add comment to PR
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const linearlite = process.env.linearlite;
const nextjs = process.env.nextjs;
const prNumber = context.issue.number;
const commentBody = `## Examples
- linearlite: ${linearlite}
- nextjs: ${nextjs}
`;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const existingComment = comments.find(comment => comment.user.login ==='github-actions[bot]' && comment.body.startsWith("## Examples"));
if (existingComment) {
// Update the existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: commentBody,
});
} else {
// Create a new comment if none exists
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody,
});
}
62 changes: 62 additions & 0 deletions .github/workflows/teardown_examples_pr_stack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Teardown Examples PR stack

on:
pull_request:
paths: ['examples/*/**']
types: [closed]

concurrency:
group: examples-pr-${{ github.event.number }}

jobs:
teardown-pr-stack:
name: Teardown Examples PR stack
environment: Pull request
runs-on: ubuntu-latest

env:
DEPLOY_ENV: ${{ github.event_name == 'push' && 'production' || format('pr-{0}', github.event.number) }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_DEFAULT_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_DEFAULT_ACCOUNT_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
NEON_API_KEY: ${{ secrets.NEON_API_KEY }}
NEON_PROJECT_ID: ${{ secrets.NEON_PROJECT_ID }}
ELECTRIC_API: ${{ secrets.ELECTRIC_API }}
ELECTRIC_ADMIN_API: ${{ secrets.ELECTRIC_ADMIN_API }}
# HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY }} TODO

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Cache SST state
uses: actions/cache@v4
with:
path: .sst
key: sst-cache-${{ github.event.number }}-${{ runner.os }}
restore-keys: |
sst-cache-${{ runner.os }}
- name: Remove Linearlite
working-directory: examples/linearlite
run: |
export PR_NUMBER=${{ github.event.number }}
echo "Removing stage pr-$PR_NUMBER"
pnpm sst remove --stage "pr-$PR_NUMBER"
- name: Remove NextJs example
working-directory: examples/nextjs-example
run: |
export PR_NUMBER=${{ github.event.number }}
echo "Removing stage pr-$PR_NUMBER"
pnpm sst remove --stage "pr-$PR_NUMBER"
3 changes: 1 addition & 2 deletions examples/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
"db:migrate": "dotenv -e ../../.env.dev -- pnpm exec pg-migrations apply --directory ./db/migrations",
"dev": "next dev --turbo -p 5173",
"start": "next start",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"stylecheck": "eslint . --quiet",
"stylecheck": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"typecheck": "tsc --noEmit"
},
"dependencies": {
Expand Down
1 change: 1 addition & 0 deletions examples/basic-example/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build/**
41 changes: 41 additions & 0 deletions examples/basic-example/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
`eslint:recommended`,
`plugin:@typescript-eslint/recommended`,
`plugin:prettier/recommended`,
],
parserOptions: {
ecmaVersion: 2022,
requireConfigFile: false,
sourceType: `module`,
ecmaFeatures: {
jsx: true,
},
},
parser: `@typescript-eslint/parser`,
plugins: [`prettier`],
rules: {
quotes: [`error`, `backtick`],
"no-unused-vars": `off`,
"@typescript-eslint/no-unused-vars": [
`error`,
{
argsIgnorePattern: `^_`,
varsIgnorePattern: `^_`,
caughtErrorsIgnorePattern: `^_`,
},
],
},
ignorePatterns: [
`**/node_modules/**`,
`**/dist/**`,
`tsup.config.ts`,
`vitest.config.ts`,
`.eslintrc.js`,
],
};
2 changes: 1 addition & 1 deletion examples/basic-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"db:migrate": "dotenv -e ../../.env.dev -- pnpm exec pg-migrations apply --directory ./db/migrations",
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"stylecheck": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"typecheck": "tsc --noEmit"
},
Expand Down
8 changes: 4 additions & 4 deletions examples/basic-example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import logo from './assets/logo.svg'
import './App.css'
import './style.css'
import logo from "./assets/logo.svg"
import "./App.css"
import "./style.css"

import { Example } from './Example'
import { Example } from "./Example"

export default function App() {
return (
Expand Down
2 changes: 1 addition & 1 deletion examples/basic-example/src/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const baseUrl = import.meta.env.ELECTRIC_URL ?? `http://localhost:3000`
export const Example = () => {
const { data: items } = useShape<Item>({
url: `${baseUrl}/v1/shape`,
table: `items`
table: `items`,
})

/*
Expand Down
8 changes: 4 additions & 4 deletions examples/basic-example/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './style.css'
import React from "react"
import ReactDOM from "react-dom/client"
import App from "./App"
import "./style.css"

ReactDOM.createRoot(document.getElementById(`root`)!).render(
<React.StrictMode>
Expand Down
4 changes: 2 additions & 2 deletions examples/basic-example/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"

// https://vitejs.dev/config/
export default defineConfig({
Expand Down
3 changes: 2 additions & 1 deletion examples/linearlite/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist
.env.local
db/data/
db/data/
.sst/
28 changes: 28 additions & 0 deletions examples/linearlite/.sst/platform/config.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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";


declare global {
// @ts-expect-error
export import neon = _neon
// @ts-expect-error
export import cloudflare = _cloudflare
// @ts-expect-error
export import aws = _aws
interface Providers {
providers?: {
"neon"?: (_neon.ProviderArgs & { version?: string }) | boolean | string;
"cloudflare"?: (_cloudflare.ProviderArgs & { version?: string }) | boolean | string;
"aws"?: (_aws.ProviderArgs & { version?: string }) | boolean | string;
}
}
export const $config: (
input: Omit<Config, "app"> & {
app(input: AppInput): Omit<App, "providers"> & Providers;
},
) => Config;
}
15 changes: 8 additions & 7 deletions examples/linearlite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
"private": true,
"type": "module",
"scripts": {
"backend:up": "PROJECT_NAME=linearlite pnpm -C ../../ run example-backend:up && pnpm db:migrate && pnpm db:load-data",
"backend:down": "PROJECT_NAME=linearlite pnpm -C ../../ run example-backend:down",
"db:migrate": "dotenv -e ../../.env.dev -- pnpm exec pg-migrations apply --directory ./db/migrations",
"backend:up": "PROJECT_NAME=linearlite pnpm -C ../../ run example-backend:up && pnpm db:migrate && pnpm db:load-data",
"build": "vite build",
"db:load-data": "dotenv -e ../../.env.dev -- node ./db/load_data.js",
"db:migrate": "dotenv -e ../../.env.dev -- pnpm exec pg-migrations apply --directory ./db/migrations",
"dev": "vite",
"build": "vite build",
"stylecheck": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"typecheck": "tsc --noEmit",
"process-data": "node ./db/process_data.js"
"process-data": "node ./db/process_data.js",
"stylecheck": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@electric-sql/client": "workspace:*",
"@electric-sql/react": "workspace:*",
"@firefox-devtools/react-contextmenu": "^5.1.1",
"@headlessui/react": "^1.7.17",
Expand All @@ -35,7 +36,6 @@
"classnames": "^2.5.1",
"dayjs": "^1.11.11",
"dotenv": "^16.4.5",
"@electric-sql/client": "workspace:*",
"fractional-indexing": "^3.2.0",
"jsonwebtoken": "^9.0.2",
"lodash.debounce": "^4.0.8",
Expand Down Expand Up @@ -79,6 +79,7 @@
"eslint-plugin-react-refresh": "^0.4.3",
"fs-extra": "^10.0.0",
"postcss": "^8.4.39",
"sst": "3.3.7",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.3",
"vite": "^4.4.5"
Expand Down
6 changes: 5 additions & 1 deletion examples/linearlite/src/electric.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export const baseUrl = import.meta.env.ELECTRIC_URL ?? `http://localhost:3000`
export const baseUrl = import.meta.env.VITE_ELECTRIC_URL
? new URL(import.meta.env.VITE_ELECTRIC_URL).origin
: `http://localhost:3000`
export const token = import.meta.env.VITE_ELECTRIC_TOKEN ?? ``
export const databaseId = import.meta.env.VITE_DATABASE_ID ?? ``
6 changes: 5 additions & 1 deletion examples/linearlite/src/pages/Issue/Comments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { formatDate } from '../../utils/date'
import { showWarning } from '../../utils/notification'
import { Comment, Issue } from '../../types/types'
import { useShape } from '@electric-sql/react'
import { baseUrl } from '../../electric'
import { baseUrl, databaseId, token } from '../../electric'

export interface CommentsProps {
issue: Issue
Expand All @@ -19,6 +19,10 @@ function Comments(commentProps: CommentsProps) {
const allComments = useShape({
url: `${baseUrl}/v1/shape`,
table: `comment`,
databaseId,
params: {
token,
},
})! as Comment[]

const comments = allComments.data.filter(
Expand Down
Loading

0 comments on commit 032a71d

Please sign in to comment.