Competence Assistant is a tool to manage competence events. Admins can create events and schedules. Other users can create and vote for sessions.
- Node.js v20 (LTS)
- pnpm v9 (run
corepack enableif not already installed) - PostgreSQL v14
- dbmate (optional)
Run in project root:
pnpm install-
Copy
server/.env.exampletoserver/.env. -
Edit the username, password, and/or database name in
.env.- Note: Make sure
DATABASE_URLreflects thePOSTGRES_*values. - Note: The password must be at least 1 character long.
- Note: Make sure
-
Start the PostgreSQL server. A docker-compose file is provided in the
serverdirectory including PostgreSQL and adminer. To start the database run:cd server docker compose up -f db.compose.yml -d -
Create a user with the name and password in your
.envfile, if one does not exist.CLI example
psql --dbname=postgres --command="CREATE USER <username> WITH PASSWORD '<password>' CREATEDB;"(Replace
<username>and<password>with the username and password, respectively.) -
Create the database if needed and set up the schema. Run in project root:
pnpm migrate up
-
Populate the database with mock data. Run in project root:
pnpm --filter server cli mock
The frontend uses Vite as the build tool, which in turn injects environment variables using build modes
- Copy
client/.env.exampletoclient/.env.local. - Add your Firebase project variables for
VITE_FIREBASE_PROJECT_ID,VITE_FIREBASE_APP_ID,VITE_FIREBASE_API_KEYandVITE_FIREBASE_AUTH_DOMAIN. - Change the value of
VITE_API_URLin.env.localtohttp://localhost:3000/api/.
-
Run in project root to start firebase auth emulator, server and client:
pnpm dev
-
Open a browser to http://localhost:5173.
Run firebase auth emulator and server
pnpm dev:serverRun client against remote prod api
pnpm dev:client:prodThe application is packaged as a docker image and deployed to Google Cloud Run using Terraform.
The deplyment steps below assume that:
- The first time setup outlined in the Terraform README is completed.
- You are using Google Cloud Artifact Registry to store the docker images.
Copy client/.env.example to client/.env.productionand specify the production variables.
Note: If you are using a custom domain you need to set the VITE_API_URL to https://<your-domain>/api/. If not it should be set to the Cloud Run url, which unfortunately is not known until after the deployment. This means that you will have to update the .env.production file after the deployment, and do another deployment.
docker build --tag <region>-docker.pkg.dev/<gcp-project-id>/<docker-repo>/<app-image> --build-arg BUILD_MODE=production .
docker push <region>-docker.pkg.dev/<gcp-project-id>/<docker-repo>/<app-image>cd server
docker build --tag <region>-docker.pkg.dev/<gcp-project-id>/<docker-repo>/<db-image> -f db.Dockerfile .
docker push <region>-docker.pkg.dev/<gcp-project-id>/<docker-repo>/<db-image>cd terraform/cd
terraform applyExample workflows for CI/CD are located in the .github/workflows directory. In order to trigger a deployment on a push to the main branch, a trigger is needed.
Example:
name: Test and Deploy on push to main
on:
push:
branches: [main]
jobs:
ci:
name: CI
uses: ./.github/workflows/lint-and-test.yaml
cd:
name: CD
needs: ci
uses: ./.github/workflows/gcp-deploy.yaml
with:
BUILD_ENV: development
secrets: inheritThe provided workflows use environment specific variables and secrets that need to be set in the repository settings.
Variables:
TF_STATE_BUCKETThe GCS bucket where the terraform state is storedSERVICE_ACCOUNTThe service account email used to authenticate with GCPBUILD_MODEThe vite build mode which determines the.env.[mode]file to usePROJECT_IDThe GCP project idREGIONThe GCP regionDOCKER_REPOThe name of the docker repository where the images are storedAPP_IMAGEThe name of the application imageDB_MIGRATION_IMAGEThe name of the db migration imageCUSTOM_DOMAIN(optional) The custom domain for the application
Secrets:
GCP_CREDENTIALSThe service account key file used to authenticate with GCPDB_USER(optional) The database user, defaults topostgresDB_PASSWORD(optional) The database password, generated if not set