diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..cf7e1452 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules +tests +.git +.github +.next +.swc +.vscode +coverage +certs +.env +.env.test +tsconfig.tsbuildinfo \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 00000000..c9800a26 --- /dev/null +++ b/.env.production @@ -0,0 +1,5 @@ +# Only put NEXT_PUBLIC variables here! +# We have to include these at build time, so this file is used to inject them into the build process. +NEXT_PUBLIC_API_URL=/api/ +NEXT_PUBLIC_SLACK_CLIENT_ID=10831824934.7404945710466 +NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=G-1BFJYBDC76 \ No newline at end of file diff --git a/.env.test b/.env.test index 9268380c..67bb80a9 100644 --- a/.env.test +++ b/.env.test @@ -1,3 +1,7 @@ NEXT_PUBLIC_API_URL=http://localhost:3000/api -DEVELOPER_EMAILS=["test@gmail.com"] \ No newline at end of file +DEVELOPER_EMAILS=["test@gmail.com"] + +TOA_URL=https://example.com +TOA_APP_ID=123 +TOA_KEY=456 \ No newline at end of file diff --git a/.github/workflows/auto_approve_dependabot_prs.yml b/.github/workflows/auto_approve_dependabot_prs.yml new file mode 100644 index 00000000..be0ff28f --- /dev/null +++ b/.github/workflows/auto_approve_dependabot_prs.yml @@ -0,0 +1,16 @@ +name: Dependabot auto-approve +on: pull_request + +permissions: + pull-requests: write + +jobs: + dependabot: + runs-on: ubuntu-latest + if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'Decatur-Robotics/Gearbox' + steps: + - name: Approve a PR + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index ffabb7af..60323ed3 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -1,33 +1,34 @@ name: CD -on: [workflow_call, workflow_dispatch] +on: + workflow_call: + secrets: + AWS_ACCESS_KEY_ID: + required: true + AWS_SECRET_ACCESS_KEY: + required: true + workflow_dispatch: permissions: packages: write jobs: - build_and_push: + push: runs-on: ubuntu-latest - environment: Test + environment: Production steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - - name: Create certs directory - run: mkdir certs - - name: Build and export - uses: docker/build-push-action@v6 - env: - DOCKER_BUILD_SUMMARY: false + - name: Download artifact + uses: actions/download-artifact@v4 with: - tags: ghcr.io/decatur-robotics/gearbox:latest - outputs: type=docker,dest=/tmp/gearbox.tar - context: . # Needed for Docker to find files made during the workflow - + name: gearbox + path: /tmp + - name: Load image run: | docker load --input /tmp/gearbox.tar @@ -37,4 +38,13 @@ jobs: run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u decatur-robotics --password-stdin - name: Push to GHCR - run: docker push ghcr.io/decatur-robotics/gearbox:latest \ No newline at end of file + run: docker push ghcr.io/decatur-robotics/gearbox:latest + + - name: Install AWS CLI + uses: unfor19/install-aws-cli-action@v1 + + - name: Configure AWS + run: aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} && aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} && aws configure set region us-east-1 + + - name: Deploy to ECS + run: aws ecs update-service --cluster gearbox --service gearbox --force-new-deployment \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b679f80..90f805e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,12 @@ jobs: with: tags: ghcr.io/decatur-robotics/gearbox:latest outputs: type=docker,dest=/tmp/gearbox.tar + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: gearbox + path: /tmp/gearbox.tar unit_test: runs-on: ubuntu-latest diff --git a/.github/workflows/increment_version.yml b/.github/workflows/increment_version.yml new file mode 100644 index 00000000..a021286e --- /dev/null +++ b/.github/workflows/increment_version.yml @@ -0,0 +1,37 @@ +name: Increment Version + +on: + workflow_call: + workflow_dispatch: + pull_request_target: + branches: [main] + types: [opened] + +jobs: + increment: + runs-on: ubuntu-latest + if: + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} # We need to checkout the head branch, not the temporary merge branch + persist-credentials: false + + - name: Setup Node.js environment + uses: actions/setup-node@v4.1.0 + + - name: Set name + run: git config user.name "Gearbox Bot" + + - name: Set email + run: git config user.email "gearbox@decaturrobotics.org" + + - name: Increment patch number + run: npm version patch + + - name: Push changes + uses: ad-m/github-push-action@v0.8.0 + with: + github_token: ${{ secrets.GIT_PUSH_TOKEN }} + branch: ${{ github.head_ref }} diff --git a/.github/workflows/onpush.yml b/.github/workflows/onpush.yml index 3164a1e9..af6b3f82 100644 --- a/.github/workflows/onpush.yml +++ b/.github/workflows/onpush.yml @@ -11,7 +11,10 @@ jobs: ci: uses: ./.github/workflows/ci.yml - # cd: - # needs: - # - ci - # uses: ./.github/workflows/cd.yml + cd: + needs: + - ci + uses: ./.github/workflows/cd.yml + secrets: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/.gitignore b/.gitignore index 04cafac3..40dfa349 100644 --- a/.gitignore +++ b/.gitignore @@ -37,9 +37,8 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts -/public/sw.js -/public/sw.js.map -/public/workbox-* -/public/fallback-* +/certs/*.* -/certs/*.* \ No newline at end of file +# PWA +public/sw.js +public/swe-worker* \ No newline at end of file diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index e43643f7..00000000 --- a/.gitpod.yml +++ /dev/null @@ -1,11 +0,0 @@ -# This configuration file was automatically generated by Gitpod. -# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) -# and commit this file to your remote git repository to share the goodness with others. - -# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart - -tasks: - - init: npm install && npm run build - command: npm run start - - diff --git a/Dockerfile b/Dockerfile index a62f994d..6cbd2ca9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,12 +7,13 @@ LABEL org.opencontainers.image.licenses=CC-BY-NC-SA-4.0 WORKDIR /app COPY package*.json ./ -RUN npm i +RUN npm ci COPY . . RUN npm run build -EXPOSE 443 +EXPOSE 80 -CMD npm run start \ No newline at end of file +# ENTRYPOINT [ "bash" ] # Uncomment to operate the terminal in the container +CMD ["/usr/local/bin/npm", "run", "start"] \ No newline at end of file diff --git a/README.md b/README.md index cd5f5724..e05a572b 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # Gearbox: Intuitive, Powerful Scouting at [4026.org](https://4026.org) + The final incarnation of Scout Janssen. Rewritten fully in Typescript, written to be easy to maintain and modular. Features full feature parity with SJ2, whilst remaining simpler, faster and cooler. ## Features + - Automatic match generation - Match assignment (both automatic and manual) - Pre-generated forms @@ -17,9 +19,16 @@ Features full feature parity with SJ2, whilst remaining simpler, faster and cool - Public data sharing (optional) - Sub-5-minute setup +## Status + +![CI Checks](https://github.com/Decatur-Robotics/Gearbox/actions/workflows/ci.yml/badge.svg)
+![Formatting](https://github.com/Decatur-Robotics/Gearbox/actions/workflows/format.yml/badge.svg)
+![Autoversioning](https://github.com/Decatur-Robotics/Gearbox/actions/workflows/increment_version.yml/badge.svg) + ## Setup ### Prerequisites + - Node.js - NPM - A MongoDB instance @@ -36,6 +45,7 @@ Features full feature parity with SJ2, whilst remaining simpler, faster and cool - A Resend audience ID ### Installation + 1. Clone the repository 1. Run `npm install` 1. Add the secrets to a `.env` file @@ -43,21 +53,34 @@ Features full feature parity with SJ2, whilst remaining simpler, faster and cool ### Running #### Development + 1. Run `npm run dev` #### Production + 1. Run `npm run build` 1. Run `npm run start` +##### Deployment + +See the [Gearbox-Terraform](https://github.com/Decatur-Robotics/Gearbox-Terraform) repo. + #### Tests + 1. Run `npm run test` +#### Scripts + +There's a few scripts in the /scripts folder that can be run with `npx tsx scripts/.ts`. + ## Contributing + You've made it past set up and are ready to contibure to the future of scouting - here's how. We recommend you start with issues labelled `good first issue` to get a feel for the codebase. Fork the repo (unless you're part of Decatur Robotics, in which case make a new branch) and then make a pull request to the main branch. We'll review it and, if it looks good, merge it. ## Contibutors + @@ -65,4 +88,5 @@ We recommend you start with issues labelled `good first issue` to get a feel for Made with [contrib.rocks](https://contrib.rocks). ## Licensed under a CC BY-NC-SA 4.0 license + Read the license [here](LICENSE.md). diff --git a/components/Avatar.tsx b/components/Avatar.tsx index 22b57242..3b38e26b 100644 --- a/components/Avatar.tsx +++ b/components/Avatar.tsx @@ -1,17 +1,17 @@ import { useCurrentSession } from "@/lib/client/useCurrentSession"; -import { User } from "@/lib/Types"; import { levelToClassName } from "@/lib/Xp"; import { BsGearFill } from "react-icons/bs"; export default function Avatar(props: { - user?: User | undefined; - scale?: string | undefined; + user?: { image: string | undefined; level: number; admin?: boolean }; + scale?: string | undefined; // Use "scale-75" for 75% scale, etc. imgHeightOverride?: string | undefined; showLevel?: boolean | undefined; borderThickness?: number | undefined; onClick?: () => void | undefined; className?: string | undefined; online?: boolean; + gearSize?: number; }) { const { session, status } = useCurrentSession(); const user = props.user ?? session?.user; @@ -39,7 +39,7 @@ export default function Avatar(props: { {admin ? (
- +
) : ( <> diff --git a/components/Container.tsx b/components/Container.tsx index c04cd4d4..a3ee606d 100644 --- a/components/Container.tsx +++ b/components/Container.tsx @@ -226,6 +226,7 @@ export default function Container(props: ContainerProps) { imgHeightOverride="h-11" showLevel={false} borderThickness={2} + gearSize={24} /> ) : ( @@ -361,7 +362,8 @@ export default function Container(props: ContainerProps) { diff --git a/components/Footer.tsx b/components/Footer.tsx index 6a93661d..9889c3da 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -7,12 +7,14 @@ import { FaGithub, FaInstagram, FaList, + FaTrophy, } from "react-icons/fa"; import { TbUfo } from "react-icons/tb"; import Link from "next/link"; import { MdAlternateEmail } from "react-icons/md"; import { HiStatusOnline } from "react-icons/hi"; import { useEffect, useState } from "react"; +import Leaderboard from "../pages/leaderboard"; export default function Footer() { const [swStatus, setSwStatus] = useState("Finding service worker..."); @@ -24,11 +26,9 @@ export default function Footer() { ? `SW Status: ${registration.active?.state}` : "Service worker not found", ); - console.log("Service worker registration: ", registration); if (registration) { registration.addEventListener("updatefound", () => { setSwStatus("Service worker update found"); - console.log("Service worker update found"); registration.installing?.addEventListener("statechange", () => { console.log( "Service worker state change: ", @@ -39,14 +39,6 @@ export default function Footer() { registration.active?.addEventListener("statechange", () => { setSwStatus(`SW Status: ${registration.active?.state}`); - console.log( - "Service worker state change: ", - registration.active?.state, - ); - }); - - registration.update().then(() => { - console.log("Service worker update initiated"); }); } }); @@ -136,11 +128,22 @@ export default function Footer() { /> About Us + + + Leaderboard +