Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam McKee committed Jan 22, 2024
0 parents commit bfdbcef
Show file tree
Hide file tree
Showing 71 changed files with 4,349 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.idea
docker-compose.yml
node_modules
dist
*/tsconfig.tsbuildinfo
*/lib
backend/.env
backend/public
84 changes: 84 additions & 0 deletions .github/workflows/blah.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: blah

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

concurrency: blah-ci

jobs:

verified:
runs-on: ubuntu-latest
needs:
- verify-backend
- verify-frontend
- verify-template
steps:
- uses: actions/checkout@v3
- run: echo "44.481800,-88.054413"

verify-backend:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
ports:
- 5432:5432
env:
POSTGRES_DB: eighty4
POSTGRES_USER: eighty4
POSTGRES_PASSWORD: eighty4
options: >-
--health-cmd pg_isready
--health-interval 5s
--health-timeout 5s
--health-retries 10
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- name: sql
run: |
sudo apt-get install -y postgresql-client
PGPASSWORD=eighty4 psql -h localhost -U eighty4 -f backend/sql/v001-init-schema.sql eighty4
- name: verify
run: |
corepack enable && corepack prepare pnpm@latest --activate
pnpm i
pnpm build
pnpm test
working-directory: backend

verify-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- name: verify
run: |
corepack enable && corepack prepare pnpm@latest --activate
pnpm i
pnpm build
pnpm svg
working-directory: frontend

verify-template:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- name: verify
run: |
corepack enable && corepack prepare pnpm@latest --activate
pnpm i
pnpm build
pnpm test
working-directory: template
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.DS_Store
.idea
node_modules
tsconfig.tsbuildinfo

dist
backend/lib
backend/public
template/lib
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM node:20-alpine as build

WORKDIR /install.sh
COPY . .

RUN corepack enable && corepack prepare pnpm@latest --activate
RUN pnpm i
RUN pnpm --filter @eighty4/install-frontend build && mv frontend/dist backend/public
RUN pnpm --filter @eighty4/install-backend build
RUN pnpm --filter @eighty4/install-backend --prod deploy dist

FROM node:20-alpine

WORKDIR /install.sh
COPY --from=build /install.sh/dist /install.sh

EXPOSE 5741

CMD ["node", "lib/Server.js"]
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# install.eighty4.tech (unfortunately not install.sh)

## todos

- minify html, inline css and inline js
- gzip, deflate, br compression

## features

- explain how screen
- open graph paper animation
- #features animation
- graph paper loader animation
- lookup repository release ui
- configure binary distributions ui
- generate script
- cli auth sequence
- cli write script to local dir

## cicd

- write playwright tests
- docker build after verified
- run e2e tests against docker image
- docker push
- trigger deploy to linode
10 changes: 10 additions & 0 deletions backend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# https://github.com/settings/developers
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""

# https://node-postgres.com/features/connecting#environment-variables
PGHOST="localhost"
PGPORT="5432"
PGDATABASE="eighty4"
PGUSER="eighty4"
PGPASSWORD="eighty4"
38 changes: 38 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@eighty4/install-backend",
"version": "0.0.1",
"private": true,
"author": "Adam McKee <[email protected]",
"license": "BSD-3-Clause",
"type": "module",
"main": "lib/Domain.js",
"types": "lib/Domain.d.ts",
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"dev": "tsx -r dotenv/config --watch src/Server.ts",
"build": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@eighty4/install-template": "workspace:^0.0.1",
"cookie-parser": "^1.4.6",
"express": "^5.0.0-beta.1",
"pg": "^8.11.3",
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/cookie-parser": "^1.4.6",
"@types/express": "^4.17.21",
"@types/pg": "^8.10.9",
"@types/uuid": "^9.0.7",
"dotenv": "^16.3.1",
"tsx": "^4.6.2",
"typescript": "^5.3.3",
"vitest": "^1.0.4"
},
"files": [
"public/**/*",
"lib/**/*",
"package.json"
]
}
24 changes: 24 additions & 0 deletions backend/sql/v001-init-schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
drop schema if exists install_sh cascade;

create schema install_sh;

create table install_sh.users
(
id bigint primary key,
email varchar not null,
access_token varchar not null,
created_when timestamp not null default now(),
authed_when timestamp not null default now()
);

create table install_sh.scripts
(
id bigserial primary key,
user_id integer not null references install_sh.users (id),
repo_owner varchar not null,
repo_name varchar not null,
template_version varchar not null,
created_when timestamp not null default now(),
generated_when timestamp not null default now(),
constraint script_user_repo_key unique (user_id, repo_owner, repo_name)
);
105 changes: 105 additions & 0 deletions backend/src/Database.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import pg from 'pg'
import {describe, expect, it} from 'vitest'
import {loadGeneratedScripts, saveGeneratedScript, saveUserLogin} from './Database.js'

const db = new pg.Pool()

const randomUserId = () => (Math.floor(Math.random() * 10000000))

describe('Database', () => {

describe('saveUserLogin', () => {

it('saves new user', async () => {
const userId = randomUserId()
const newUser = await saveUserLogin(userId, '[email protected]', 'open sesame')
expect(newUser).toBe(true)
const result = await db.query('select * from install_sh.users where id = $1', [userId])
expect(result.rows.length).toBe(1)
expect(result.rows[0].email).toBe('[email protected]')
expect(result.rows[0].access_token).toBe('open sesame')
expect(result.rows[0].authed_when).toBeDefined()
expect(result.rows[0].authed_when).toStrictEqual(result.rows[0].created_when)
})

it('saves login for existing user', async () => {
const userId = randomUserId()
let newUser = await saveUserLogin(userId, '[email protected]', 'accessToken0')
expect(newUser).toBe(true)
const result1 = await db.query('select * from install_sh.users where id = $1', [userId])
expect(result1.rows[0].email).toBe('[email protected]')
expect(result1.rows[0].access_token).toBe('accessToken0')
newUser = await saveUserLogin(userId, '[email protected]', 'accessToken1')
expect(newUser).toBe(false)
const result2 = await db.query('select * from install_sh.users where id = $1', [userId])
expect(result2.rows[0].email).toBe('[email protected]')
expect(result2.rows[0].access_token).toBe('accessToken1')
expect(result2.rows[0].authed_when).not.toStrictEqual(result1.rows[0].created_when)
expect(result2.rows[0].created_when < result2.rows[0].authed_when).toBe(true)
})
})

describe('loadGeneratedScripts', () => {

it('returns empty array if no generated scripts for user', async () => {
const userId = randomUserId()
const result = await loadGeneratedScripts(userId)
expect(result).toStrictEqual([])
})

it('retrieves generated scripts', async () => {
const userId = randomUserId()
await db.query('insert into install_sh.users (id, email, access_token) values ($1, $2, $3)', [userId, '[email protected]', 'open sesame'])
await db.query('insert into install_sh.scripts (user_id, repo_owner, repo_name, template_version) values ($1, $2, $3, $4)', [userId, 'eighty4', 'maestro', '1'])
await db.query('insert into install_sh.scripts (user_id, repo_owner, repo_name, template_version) values ($1, $2, $3, $4)', [userId, 'eighty4', 'cquill', '2'])
const result = await loadGeneratedScripts(userId)
expect(result).toHaveLength(2)
expect(result[0]).toStrictEqual({
repository: {
owner: 'eighty4',
name: 'cquill',
},
templateVersion: '2',
})
expect(result[1]).toStrictEqual({
repository: {
owner: 'eighty4',
name: 'maestro',
},
templateVersion: '1',
})
})
})

describe('saveGeneratedScript', () => {

it('saves generated script for new repository', async () => {
const userId = randomUserId()
await db.query('insert into install_sh.users (id, email, access_token) values ($1, $2, $3)', [userId, '[email protected]', 'open sesame'])
const repository = {owner: 'eighty4', name: 'maestro'}
await saveGeneratedScript(userId, repository, '1')
const result = await db.query('select * from install_sh.scripts where user_id = $1', [userId])
expect(result.rows).toHaveLength(1)
const {template_version, repo_name, repo_owner, created_when, generated_when} = result.rows[0]
expect(repo_owner).toBe('eighty4')
expect(repo_name).toBe('maestro')
expect(template_version).toBe('1')
expect(created_when).toStrictEqual(generated_when)
})

it('updates generated script template version', async () => {
const userId = randomUserId()
await db.query('insert into install_sh.users (id, email, access_token) values ($1, $2, $3)', [userId, '[email protected]', 'open sesame'])
const repository = {owner: 'eighty4', name: 'maestro'}
await saveGeneratedScript(userId, repository, '1')
await saveGeneratedScript(userId, repository, '2')
const result = await db.query('select * from install_sh.scripts where user_id = $1', [userId])
expect(result.rows).toHaveLength(1)
const {template_version, repo_name, repo_owner, created_when, generated_when} = result.rows[0]
expect(repo_owner).toBe('eighty4')
expect(repo_name).toBe('maestro')
expect(template_version).toBe('2')
expect(generated_when > created_when).toBe(true)
})
})
})
Loading

0 comments on commit bfdbcef

Please sign in to comment.