Skip to content

Commit

Permalink
Merge branch 'codeforboston:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
thatoldplatitude authored Dec 12, 2023
2 parents b54d63f + 1571ddd commit 6151eb2
Show file tree
Hide file tree
Showing 92 changed files with 6,623 additions and 4,056 deletions.
93 changes: 47 additions & 46 deletions .github/workflows/heat-stack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ on:
push:
branches:
- main
# - dev
- gha-deployment
- dev
pull_request: {}

env:
Expand All @@ -24,7 +25,7 @@ permissions:
jobs:
lint:
name: ⬣ ESLint
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v3
Expand All @@ -50,7 +51,7 @@ jobs:

typecheck:
name: ʦ TypeScript
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v3
Expand All @@ -73,7 +74,7 @@ jobs:

vitest:
name: ⚡ Vitest pyodide.test.ts
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v3
Expand All @@ -100,7 +101,7 @@ jobs:
# playwright tests work great but slight jank/inconsistency passing, and not used yet, so disabling for now
# playwright:
# name: 🎭 Playwright
# runs-on: ubuntu-latest
# runs-on: ubuntu-22.04
# timeout-minutes: 60
# steps:
# - name: ⬇️ Checkout repo
Expand Down Expand Up @@ -155,46 +156,46 @@ jobs:
# path: playwright-report/
# retention-days: 30

# deploy:
# name: 🚀 Deploy
# runs-on: ubuntu-latest
# needs: [lint, typecheck, vitest, playwright]
# # only build/deploy main branch on pushes
# if:
# ${{ (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') &&
# github.event_name == 'push' }}
deploy:
name: 🚀 Deploy
runs-on: ubuntu-latest
needs: [lint, typecheck, vitest] #, playwright]
# only build/deploy main branch on pushes
if:
${{ (github.ref == 'refs/heads/gha-deployment' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') &&
github.event_name == 'push' }}

# steps:
# - name: ⬇️ Checkout repo
# uses: actions/checkout@v3
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v3

# - name: 👀 Read app name
# uses: SebRollen/[email protected]
# id: app_name
# with:
# file: 'fly.toml'
# field: 'app'

# # move Dockerfile to root
# - name: 🚚 Move Dockerfile
# run: |
# mv ./other/Dockerfile ./Dockerfile
# mv ./other/.dockerignore ./.dockerignore

# - name: 🎈 Setup Fly
# uses: superfly/flyctl-actions/[email protected]

# - name: 🚀 Deploy Staging
# if: ${{ github.ref == 'refs/heads/dev' }}
# run:
# flyctl deploy --remote-only --build-arg COMMIT_SHA=${{ github.sha }}
# --app ${{ steps.app_name.outputs.value }}-staging
# env:
# FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

# - name: 🚀 Deploy Production
# if: ${{ github.ref == 'refs/heads/main' }}
# run:
# flyctl deploy --remote-only --build-arg COMMIT_SHA=${{ github.sha }}
# env:
# FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
- name: 👀 Read app name
uses: SebRollen/[email protected]
id: app_name
with:
file: '${{ env.working-directory }}/fly.toml'
field: 'app'

# move Dockerfile to root
- name: 🚚 Move Dockerfile
run: |
mv ./other/Dockerfile ./Dockerfile
mv ./other/.dockerignore ./.dockerignore
- name: 🎈 Setup Fly
uses: superfly/flyctl-actions/[email protected]

- name: 🚀 Deploy Staging
if: ${{ github.ref == 'refs/heads/dev' }}
run:
flyctl deploy --remote-only --build-arg COMMIT_SHA=${{ github.sha }}
--app ${{ steps.app_name.outputs.value }}-staging
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

- name: 🚀 Deploy Production
if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/gha-deployment' }}
run:
flyctl deploy --remote-only --build-arg COMMIT_SHA=${{ github.sha }}
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ node_modules

# Easy way to create temporary files/folders that won't accidentally be added to git
*.local.*

#local temporary folders
heat-app
venv
heat-tmp
11 changes: 11 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"recommendations": [
"bradlc.vscode-tailwindcss",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"prisma.prisma",
"qwtel.sqlite-viewer",
"yoavbls.pretty-ts-errors",
"github.vscode-github-actions"
]
}
1 change: 1 addition & 0 deletions heat-stack/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ DATABASE_PATH="./prisma/data.db"
DATABASE_URL="file:./data.db?connection_limit=1"
CACHE_DATABASE_PATH="./other/cache.db"
SESSION_SECRET="super-duper-s3cret"
HONEYPOT_SECRET="super-duper-s3cret"
INTERNAL_COMMAND_TOKEN="some-made-up-token"
RESEND_API_KEY="re_blAh_blaHBlaHblahBLAhBlAh"
SENTRY_DSN="your-dsn"
Expand Down
4 changes: 4 additions & 0 deletions heat-stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ npm install
npm run dev
```


### Set up in a new GitHub CodingSpace:

```
Expand All @@ -30,6 +31,9 @@ npm run dev

If you have the node version manager (`nvm`), then `nvm use 18` avoids engine error with node v19+ or newer which is default. nvm is preinstalled in coding spaces.


In Coding Spaces VSCode always go to hamburger menu -> File-> untick AutoSave. For a pic, see https://stackoverflow.com/a/76659316/14144258

### Under special circumstances:

Assume you don't need to, but if the version of pyodide changes run:
Expand Down
21 changes: 0 additions & 21 deletions heat-stack/app/components/confetti.tsx

This file was deleted.

4 changes: 3 additions & 1 deletion heat-stack/app/components/error-boundary.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {
type ErrorResponse,
isRouteErrorResponse,
useParams,
useRouteError,
} from '@remix-run/react'
import { type ErrorResponse } from '@remix-run/router'
import { captureRemixErrorBoundaryError } from '@sentry/remix'
import { getErrorMessage } from '#app/utils/misc.tsx'

type StatusHandler = (info: {
Expand All @@ -25,6 +26,7 @@ export function GeneralErrorBoundary({
unexpectedErrorHandler?: (error: unknown) => JSX.Element | null
}) {
const error = useRouteError()
captureRemixErrorBoundaryError(error)
const params = useParams()

if (typeof document !== 'undefined') {
Expand Down
4 changes: 2 additions & 2 deletions heat-stack/app/components/forms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function ErrorList({
return (
<ul id={id} className="flex flex-col gap-1">
{errorsToRender.map(e => (
<li key={e} className="text-[10px] text-foreground-danger">
<li key={e} className="text-foreground-destructive text-[10px]">
{e}
</li>
))}
Expand Down Expand Up @@ -64,7 +64,7 @@ export function TextareaField({
className,
}: {
labelProps: React.LabelHTMLAttributes<HTMLLabelElement>
textareaProps: React.InputHTMLAttributes<HTMLTextAreaElement>
textareaProps: React.TextareaHTMLAttributes<HTMLTextAreaElement>
errors?: ListOfErrors
className?: string
}) {
Expand Down
63 changes: 63 additions & 0 deletions heat-stack/app/components/progress-bar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useNavigation } from '@remix-run/react'
import { useEffect, useRef, useState } from 'react'
import { useSpinDelay } from 'spin-delay'
import { cn } from '#app/utils/misc.tsx'
import { Icon } from './ui/icon.tsx'

function EpicProgress() {
const transition = useNavigation()
const busy = transition.state !== 'idle'
const delayedPending = useSpinDelay(busy, {
delay: 600,
minDuration: 400,
})
const ref = useRef<HTMLDivElement>(null)
const [animationComplete, setAnimationComplete] = useState(true)

useEffect(() => {
if (!ref.current) return
if (delayedPending) setAnimationComplete(false)

const animationPromises = ref.current
.getAnimations()
.map(({ finished }) => finished)

Promise.allSettled(animationPromises).then(() => {
if (!delayedPending) setAnimationComplete(true)
})
}, [delayedPending])

return (
<div
role="progressbar"
aria-hidden={delayedPending ? undefined : true}
aria-valuetext={delayedPending ? 'Loading' : undefined}
className="fixed inset-x-0 left-0 top-0 z-50 h-[0.20rem] animate-pulse"
>
<div
ref={ref}
className={cn(
'h-full w-0 bg-foreground duration-500 ease-in-out',
transition.state === 'idle' &&
(animationComplete
? 'transition-none'
: 'w-full opacity-0 transition-all'),
delayedPending && transition.state === 'submitting' && 'w-5/12',
delayedPending && transition.state === 'loading' && 'w-8/12',
)}
/>
{delayedPending && (
<div className="absolute flex items-center justify-center">
<Icon
name="update"
size="md"
className="m-1 animate-spin text-foreground"
aria-hidden
/>
</div>
)}
</div>
)
}

export { EpicProgress }
6 changes: 4 additions & 2 deletions heat-stack/app/components/search-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Form, useSearchParams, useSubmit } from '@remix-run/react'
import { useId } from 'react'
import { useDebounce, useIsPending } from '#app/utils/misc.tsx'
import { Icon } from './ui/icon.tsx'
import { Input } from './ui/input.tsx'
Expand All @@ -14,6 +15,7 @@ export function SearchBar({
autoFocus?: boolean
autoSubmit?: boolean
}) {
const id = useId()
const [searchParams] = useSearchParams()
const submit = useSubmit()
const isSubmitting = useIsPending({
Expand All @@ -33,13 +35,13 @@ export function SearchBar({
onChange={e => autoSubmit && handleFormChange(e.currentTarget)}
>
<div className="flex-1">
<Label htmlFor="search" className="sr-only">
<Label htmlFor={id} className="sr-only">
Search
</Label>
<Input
type="search"
name="search"
id="search"
id={id}
defaultValue={searchParams.get('search') ?? ''}
placeholder="Search"
className="w-full"
Expand Down
1 change: 1 addition & 0 deletions heat-stack/app/components/spinner.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* deprecated by epic stack 2.3, delete me */
export function Spinner({ showSpinner }: { showSpinner: boolean }) {
return (
<div
Expand Down
6 changes: 3 additions & 3 deletions heat-stack/app/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import * as React from 'react'
import { cn } from '#app/utils/misc.tsx'

const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors outline-none focus-visible:ring-4 focus-within:ring-4 ring-ring ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
default: 'bg-primary text-primary-foreground hover:bg-primary/80',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
'bg-destructive text-destructive-foreground hover:bg-destructive/80',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary:
Expand Down
14 changes: 14 additions & 0 deletions heat-stack/app/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { PassThrough } from 'stream'
import {
createReadableStreamFromReadable,
type DataFunctionArgs,
type HandleDocumentRequestFunction,
} from '@remix-run/node'
import { RemixServer } from '@remix-run/react'
import * as Sentry from '@sentry/remix'
import isbot from 'isbot'
import { getInstanceInfo } from 'litefs-js'
import { renderToPipeableStream } from 'react-dom/server'
Expand Down Expand Up @@ -72,6 +74,7 @@ export default async function handleRequest(...args: DocRequestArgs) {

console.error(error)
},
nonce,
},
)

Expand All @@ -88,3 +91,14 @@ export async function handleDataRequest(response: Response) {

return response
}

export function handleError(
error: unknown,
{ request }: DataFunctionArgs,
): void {
if (error instanceof Error) {
Sentry.captureRemixServerException(error, 'remix.server', request)
} else {
Sentry.captureException(error)
}
}
Loading

0 comments on commit 6151eb2

Please sign in to comment.