feat: Add www to cloudflare pages (#105)

Co-authored-by: --global <--global>

Add our website to cloudflare pages
This commit is contained in:
Wanjohi
2024-09-03 06:55:51 +03:00
committed by GitHub
parent 62b7a841ed
commit e2e5497c62
44 changed files with 243 additions and 47 deletions

60
.github/workflows/sst.yml vendored Normal file
View File

@@ -0,0 +1,60 @@
name: sst
on:
workflow_dispatch:
concurrency:
group: ${{ github.ref }}
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/cache@v2
with:
path: |
.sst
key: ${{ runner.os }}-sst
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- uses: actions/setup-node@v1
with:
node-version: "20"
- run: "curl -fsSL https://ion.sst.dev/install | bash"
- if: github.ref == 'refs/heads/dev'
name: Configure Dev AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: arn:aws:iam::058264103289:role/terminal-shop-dev-github
aws-region: us-east-2
- if: github.ref == 'refs/heads/production'
name: Configure Production AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: arn:aws:iam::211125775473:role/terminal-shop-production-github
aws-region: us-east-2
- name: deps
run: bun install
- name: Deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
sst install
sst deploy --stage=${GITHUB_REF_NAME}

6
.gitignore vendored
View File

@@ -36,3 +36,9 @@ yarn-error.log*
# Misc
.DS_Store
*.pem
# sst
.sst
#Bun merging errors, EVERY time :(
bun.lockb

View File

@@ -31,9 +31,9 @@
"devDependencies": {
"@builder.io/qwik": "^1.8.0",
"@builder.io/qwik-city": "^1.8.0",
"@nestri/eslint-config": "workspace:*",
"@nestri/typescript-config": "workspace:*",
"@nestri/ui": "workspace:*",
"@nestri/eslint-config": "*",
"@nestri/typescript-config": "*",
"@nestri/ui": "*",
"@types/eslint": "8.56.10",
"@types/node": "20.14.11",
"@typescript-eslint/eslint-plugin": "7.16.1",

View File

@@ -16,7 +16,7 @@
"@jsquash/avif": "^1.3.0",
"@jsquash/jpeg": "^1.4.0",
"@jsquash/resize": "^2.0.0",
"@nestri/cache": "workspace:*",
"@nestri/cache": "*",
"tinycolor2": "^1.6.0",
"wrangler": "^3.72.2"
}

View File

@@ -32,9 +32,9 @@
"@builder.io/qwik": "^1.8.0",
"@builder.io/qwik-city": "^1.8.0",
"@builder.io/qwik-react": "0.5.0",
"@nestri/eslint-config": "workspace:*",
"@nestri/typescript-config": "workspace:*",
"@nestri/ui": "workspace:*",
"@nestri/eslint-config": "*",
"@nestri/typescript-config": "*",
"@nestri/ui": "*",
"@types/eslint": "8.56.10",
"@types/node": "^22.5.1",
"@types/react": "^18.2.28",

View File

@@ -1 +1,7 @@
module.exports = require("@nestri/ui/postcss.config");
// module.exports = require("@nestri/ui/postcss.config");
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -1,7 +1,5 @@
import { component$ } from "@builder.io/qwik";
import { Link } from "@builder.io/qwik-city";
import { buttonVariants, cn } from "@nestri/ui/design";
export default component$(() => {
return (

View File

@@ -1,3 +1,4 @@
/* eslint-disable qwik/jsx-img */
import { component$ } from "@builder.io/qwik";
import { Link } from "@builder.io/qwik-city";
import { NavBar, Footer } from "@nestri/ui";

View File

@@ -1,5 +1,5 @@
import { component$ } from "@builder.io/qwik";
import { GameCard, HomeNavBar, Card } from "@nestri/ui";
import { HomeNavBar, Card } from "@nestri/ui";
function getGreeting(): string {
const hour = new Date().getHours();

4
apps/www/sst-env.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
/* tslint:disable */
/* eslint-disable */
/// <reference path="../../sst-env.d.ts" />
export {}

View File

@@ -1,8 +1,8 @@
// import colors from "tailwindcss/colors";
import baseConfig from "@nestri/ui/tailwind.config";
/** @type {import('tailwindcss').Config} */
module.exports = {
module.exports = {
content: [
"./{src,components,app}/**/*.{ts,tsx,html}",
"../../packages/ui/src/**/*.{ts,tsx}",

View File

@@ -11,6 +11,7 @@
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "Bundler",
"allowImportingTsExtensions": true,
"esModuleInterop": true,
"skipLibCheck": true,
"incremental": true,
@@ -24,7 +25,7 @@
}
},
"files": [
".eslintrc.js"
".eslintrc.cjs"
],
"include": [
"src",

BIN
bun.lockb

Binary file not shown.

9
infra/domain.ts Normal file
View File

@@ -0,0 +1,9 @@
export const domain =
{
production: "fst.so",
dev: "dev.fst.so",
}[$app.stage] || $app.stage + ".dev.fst.so";
export const zone = cloudflare.getZoneOutput({
name: "fst.so",
});

38
infra/github.ts Normal file
View File

@@ -0,0 +1,38 @@
import { isPermanentStage } from "./stage";
if (isPermanentStage) {
const github = new aws.iam.OpenIdConnectProvider("GithubProvider", {
url: "https://token.actions.githubusercontent.com",
clientIdLists: ["sts.amazonaws.com"],
thumbprintLists: [
"6938fd4d98bab03faadb97b34396831e3780aea1",
"1c58a3a8518e8759bf075b76b750d4f2df264fcd",
],
});
const githubRole = new aws.iam.Role("GithubRole", {
name: [$app.name, $app.stage, "github"].join("-"),
assumeRolePolicy: {
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: {
Federated: github.arn,
},
Action: "sts:AssumeRoleWithWebIdentity",
Condition: {
StringLike: github.url.apply((url) => ({
[`${url}:sub`]: "repo:nestriness/nestri:*",
})),
},
},
],
},
});
new aws.iam.RolePolicyAttachment("GithubRolePolicy", {
policyArn: "arn:aws:iam::aws:policy/AdministratorAccess",
role: githubRole.name,
});
}

5
infra/secrets.ts Normal file
View File

@@ -0,0 +1,5 @@
export const secret = {
CloudflareAccountIdSecret: new sst.Secret("CloudflareAccountId"),
};
export const allSecrets = Object.values(secret);

2
infra/stage.ts Normal file
View File

@@ -0,0 +1,2 @@
export const isPermanentStage =
$app.stage === "production" || $app.stage === "dev";

36
infra/www.ts Normal file
View File

@@ -0,0 +1,36 @@
//Deploys the website to cloudflare pages under the domain nestri.io (redirects all requests to www.nestri.io to avoid duplicate content)
// const cloudflareAccountId = new sst.Secret("CloudflareAccountId");
export const www = new cloudflare.PagesProject("www", {
name: "nestri",
accountId: "8405b2acb6746935b975bc2cfcb5c288",
productionBranch: "main",
buildConfig: {
rootDir: "apps/www",
// buildCommand: "bun run build",
destinationDir: "dist"
},
deploymentConfigs: {
production: {
compatibilityFlags: ["nodejs_compat"]
},
preview: {
compatibilityFlags: ["nodejs_compat"]
}
},
source: {
type: "github",
config: {
owner: "nestriness",
deploymentsEnabled: true,
productionBranch: "main",
repoName: "nestri",
productionDeploymentEnabled: true,
prCommentsEnabled: true,
}
}
});
export const outputs = {
www: www.subdomain,
};

View File

@@ -4,10 +4,12 @@
"scripts": {
"build": "turbo build",
"dev": "turbo dev",
"lint": "turbo lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"lint": "turbo lint"
},
"devDependencies": {
"@cloudflare/workers-types": "4.20240821.1",
"@types/aws-lambda": "8.10.145",
"prettier": "^3.2.5",
"sst": "^3.0.91",
"turbo": "^2.0.12",
@@ -25,5 +27,8 @@
"core-js-pure",
"esbuild",
"workerd"
]
],
"dependencies": {
"sst": "3.0.94"
}
}

View File

@@ -14,9 +14,9 @@
"@builder.io/qwik": "^1.8.0",
"@builder.io/qwik-city": "^1.8.0",
"@builder.io/qwik-react": "0.5.0",
"@nestri/eslint-config": "workspace:*",
"@nestri/typescript-config": "workspace:*",
"@nestri/core": "workspace:*",
"@nestri/eslint-config": "*",
"@nestri/typescript-config": "*",
"@nestri/core": "*",
"@types/eslint": "^8.56.5",
"@types/node": "^20.11.24",
"autoprefixer": "^10.4.20",

View File

@@ -4,7 +4,7 @@
"private": true,
"sideEffects": false,
"files": [
"tailwind.config.ts",
"tailwind.config.js",
"postcss.config.js",
"globals.css"
],
@@ -26,9 +26,9 @@
"@builder.io/qwik-react": "0.5.0",
"@fontsource/bricolage-grotesque": "^5.0.7",
"@fontsource/geist-sans": "^5.0.3",
"@nestri/eslint-config": "workspace:*",
"@nestri/typescript-config": "workspace:*",
"@nestri/core": "workspace:*",
"@nestri/eslint-config": "*",
"@nestri/typescript-config": "*",
"@nestri/core": "*",
"@turbo/gen": "^1.12.4",
"@types/eslint": "^8.56.5",
"@types/node": "^20.11.24",

View File

@@ -1,4 +1,4 @@
export default {
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},

View File

@@ -10,7 +10,6 @@ type Props = {
export const Card = component$(({ game }: Props) => {
const imageUrl = `http://localhost:8787/image/cover/${game.id}.avif`
const backgroundColor = useSignal<string | undefined>(undefined);
const ringColor = useSignal<string | undefined>(undefined);
const imgRef = useSignal<HTMLImageElement>();
const extractColor = $((img: HTMLImageElement) => {

View File

@@ -1,5 +1,5 @@
import { component$ } from "@builder.io/qwik";
import { MotionComponent, transition } from "@/react/motion";
import { MotionComponent, transition } from "@nestri/ui/react";
import { Link } from "@builder.io/qwik-city";
export const GithubBanner = component$(() => {

View File

@@ -1,5 +1,5 @@
import { $, component$, useOnDocument, useSignal } from "@builder.io/qwik";
import { cn } from "@/design";
import { cn } from "./design";
export const HomeNavBar = component$(() => {
const hasScrolled = useSignal(false);

View File

@@ -1,6 +1,6 @@
/* eslint-disable qwik/no-use-visible-task */
import { cn } from '@/design';
import { component$, useSignal, useTask$, useStyles$, useVisibleTask$, $ } from '@builder.io/qwik';
import { cn } from '@nestri/ui/design';
import { component$, useSignal, useTask$, useStyles$, useVisibleTask$ } from '@builder.io/qwik';
interface ImageLoaderProps {
src: string;

View File

@@ -1,5 +1,5 @@
/* eslint-disable qwik/no-use-visible-task */
import { cn } from '@/design';
import { cn } from '@nestri/ui/design';
import { component$, useSignal, useTask$, useStyles$, useVisibleTask$, $ } from '@builder.io/qwik';
interface ImageLoaderProps {

View File

@@ -2,7 +2,7 @@ import {
form,
cn,
type InputProps as InputVariants,
} from "@/design"
} from "./design"
import { type QwikIntrinsicElements, component$ } from '@builder.io/qwik';
export interface InputComponentProps extends Omit<QwikIntrinsicElements["input"], 'size'>, InputVariants {

View File

@@ -1,6 +1,6 @@
import { $, component$, useOnDocument, useSignal } from "@builder.io/qwik";
import { Link, useLocation } from "@builder.io/qwik-city";
import { buttonVariants, cn } from "@/design";
import { buttonVariants, cn } from "./design";
const navLinks = [
{

View File

@@ -1,7 +1,7 @@
/** @jsxImportSource react */
import React from 'react'
import { motion } from 'framer-motion'
import { cn } from '@/design'
import { cn } from "@nestri/ui/design"
import { qwikify$ } from '@builder.io/qwik-react';
export const CursorSVG = ({ flip }: { flip?: boolean }) => (

View File

@@ -6,9 +6,9 @@ import {
type DisplayProps as DisplayVariants,
type TextAlignProp,
type TextWeightProp
} from "@/design"
} from "@nestri/ui/design"
import * as ReactBalancer from "react-wrap-balancer"
import { cn } from "@/design"
import { cn } from "@nestri/ui/design"
import { qwikify$ } from "@builder.io/qwik-react"
type DisplaySize = DisplayVariants["size"]

View File

@@ -2,7 +2,7 @@
/** @jsxImportSource react */
import { qwikify$ } from "@builder.io/qwik-react";
import { motion } from "framer-motion"
import { ReactDisplay } from "@/react/display"
import { ReactDisplay } from "./display"
import * as React from "react"
// type Props = {
// children?: React.ReactElement[]

View File

@@ -1,4 +1,4 @@
import { cn } from "@/design";
import { cn } from "@nestri/ui/design";
import { component$, useStore, type Component } from "@builder.io/qwik";

View File

@@ -1,7 +1,6 @@
/** @jsxImportSource react */
import React from 'react'
import { motion } from 'framer-motion'
import { cn } from '@/design'
import { cn } from "@nestri/ui/design"
import { qwikify$ } from '@builder.io/qwik-react';
export const CursorSVG = ({ flip }: { flip?: boolean }) => (

View File

@@ -1,5 +1,5 @@
/** @jsxImportSource react */
import { cn } from "@/design";
import { cn } from "@nestri/ui/design";
import { qwikify$ } from "@builder.io/qwik-react";
import React, { useEffect, useRef, useState } from "react";
import {

View File

@@ -7,7 +7,7 @@ import {
type TextAlignProp,
type TextWeightProp,
cn
} from "@/design"
} from "@nestri/ui/design"
// import * as ReactBalancer from "react-wrap-balancer"
import { qwikify$ } from "@builder.io/qwik-react"

View File

@@ -2,7 +2,7 @@
/** @jsxImportSource react */
import { qwikify$ } from "@builder.io/qwik-react";
import { motion } from "framer-motion"
import { ReactDisplay } from "@/react/display"
import { ReactDisplay } from "./display"
// type Props = {
// children?: React.ReactElement[]
// }

View File

@@ -7,7 +7,7 @@ import {
type TextAlignProp,
type TextWeightProp,
cn
} from "@/design"
} from "@nestri/ui/design"
import { qwikify$ } from "@builder.io/qwik-react";

View File

@@ -3,10 +3,7 @@
"compilerOptions": {
"outDir": "tmp",
"rootDir": ".",
"allowImportingTsExtensions": true,
"paths": {
"@/*": ["./src/*"]
}
"allowImportingTsExtensions": true
},
"files": [".eslintrc.js"],
"include": ["src", "./*.d.ts"]

View File

@@ -2,6 +2,7 @@
"extends": "@nestri/typescript-config/base.json",
"compilerOptions": {
"outDir": "dist",
"allowImportingTsExtensions": true
},
"include": ["src", "./*.config.js","./.eslintrc.js"],
"exclude": ["node_modules", "dist"]

8
sst-env.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
/* tslint:disable */
/* eslint-disable */
import "sst"
declare module "sst" {
export interface Resource {
}
}
export {}

20
sst.config.ts Normal file
View File

@@ -0,0 +1,20 @@
/// <reference path="./.sst/platform/config.d.ts" />
import { readdirSync } from "fs";
export default $config({
app(input) {
return {
name: "nestri",
removal: input?.stage === "production" ? "retain" : "remove",
home: "aws",
providers: { cloudflare: "5.37.1" },
};
},
async run() {
const outputs = {};
for (const value of readdirSync("./infra/")) {
const result = await import("./infra/" + value);
if (result.outputs) Object.assign(outputs, result.outputs);
}
return outputs;
},
});

1
tsconfig.json Normal file
View File

@@ -0,0 +1 @@
{}