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 enable
if not already installed) - PostgreSQL v14
- dbmate (optional)
Run in project root:
pnpm install
-
Copy
server/.env.example
toserver/.env
. -
Edit the username, password, and/or database name in
.env
.- Note: Make sure
DATABASE_URL
reflects 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
server
directory 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
.env
file, 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.example
toclient/.env.local
. - Add your Firebase project variables for
VITE_FIREBASE_PROJECT_ID
,VITE_FIREBASE_APP_ID
,VITE_FIREBASE_API_KEY
andVITE_FIREBASE_AUTH_DOMAIN
. - Change the value of
VITE_API_URL
in.env.local
tohttp://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:server
Run client against remote prod api
pnpm dev:client:prod
The 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.production
and 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 apply
Example 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: inherit
The provided workflows use environment specific variables and secrets that need to be set in the repository settings.
Variables:
TF_STATE_BUCKET
The GCS bucket where the terraform state is storedSERVICE_ACCOUNT
The service account email used to authenticate with GCPBUILD_MODE
The vite build mode which determines the.env.[mode]
file to usePROJECT_ID
The GCP project idREGION
The GCP regionDOCKER_REPO
The name of the docker repository where the images are storedAPP_IMAGE
The name of the application imageDB_MIGRATION_IMAGE
The name of the db migration imageCUSTOM_DOMAIN
(optional) The custom domain for the application
Secrets:
GCP_CREDENTIALS
The service account key file used to authenticate with GCPDB_USER
(optional) The database user, defaults topostgres
DB_PASSWORD
(optional) The database password, generated if not set