The guidelines assume the usage of a Ubuntu workstation.
asdfis a tool to manage the required packages with specific versions.- All the packages are defined in
tool-versionsin the root directory of the repository.
-
If running Ubuntu, make sure that you have all the following packages installed.
sudo apt-get install libsqlite3-dev bzip2sudo apt-get install icu-devtoolssudo apt-get install uuid-devsudo apt install git curlsudo apt install libreadline-devsudo apt install pre-commitsudo apt install gitlint
-
Navigate to the root directory of the repository.
-
Install
asdfaccording to theasdfinstallation guide. -
Install
asdfby picking theBuild from Sourceoption and install the plugin. -
Install
asdfpackages defined in.tool-versions.cat .tool-versions | cut -f 1 -d ' ' | xargs -n 1 asdf plugin-add || true asdf plugin-update --all asdf install asdf reshim
-
Confirm the libraries have been properly installed by running
asdf current. The output will tell you if any packages failed to download. -
Run
pip install -r requirements.txtto install Python packages- Note: If running into as asdf error, try running
asdf reshim
- Note: If running into as asdf error, try running
-
Run
pre-commit install -
Run
gitlint install-hook
- Postgres in particular has issues installing on Ubuntu systems. There are some instalation instructions here asdf-postgres. Postgres needs to be manually started with
pg_ctl startand stopped withpg_ctl stopbefore and after running the app.
-
Copy environment variables
make setup_env
Note: The defaults will get you up and running, but actual credentials are required for full functionality.
These secrets and configuration variables can be requested from other team developers or found in the dev test and prod sandbox environments. (dev., test.,'')sandbox.loginproxy.gov.bc.ca.
You could run the apps locally on your host machine using npm commands or in your docker environment using docker compose
-
Install dependencies
make app_install
Note: Installing all dependencies the first time will take a while.
-
Start the local
postgresserver (pg_ctl startif you installed it withasdf) -
Generate initial database schemas, fields, functions and related objects.
make local_db
-
Generate initial test database schemas
make local_test_db
Note: If the script has logged migration done but won't close, you can exit with ctrl + c.
-
Create .env files in the app and db folders. Use the .env.example files for reference.
-
Start the app
make app
- Docker (preferebly docker engine and CLI)
- Details here: https://docs.docker.com/engine/install/ubuntu/
- Install Docker Compose:
sudo apt install docker-compose - After the install: Add your current user to the docker group.
sudo usermod -aG docker $USER - Logout/Login to activate
- Install Microsoft Docker Plugin in VC
- Connect to DockerHub with your password and valid access token (https://hub.docker.com/settings/security)
- In VC terminal run to test:
docker run hello-world
-
Build sso-requests:latest and sso-requests-api:latest images using below commands
docker buildx build --build-arg NEXT_PUBLIC_API_URL=http://localhost:3000/api --build-arg NEXT_PUBLIC_SSO_URL=https://dev.loginproxy.gov.bc.ca/auth --build-arg NEXT_PUBLIC_SSO_CLIENT_ID=css-app-in-gold-4128 --build-arg NEXT_PUBLIC_SSO_REDIRECT_URI=http://localhost:3000 --build-arg NEXT_PUBLIC_SSO_AUTHORIZATION_RESPONSE_TYPE=code --build-arg NEXT_PUBLIC_SSO_AUTHORIZATION_SCOPE=openid --build-arg NEXT_PUBLIC_SSO_TOKEN_GRANT_TYPE=authorization_code --build-arg NEXT_PUBLIC_SSO_CONFIGURATION_ENDPOINT=https://dev.loginproxy.gov.bc.ca/auth/realms/standard/.well-known/openid-configuration --build-arg NEXT_PUBLIC_ENABLE_GOLD=true --build-arg NEXT_PUBLIC_APP_URL=http://localhost:3000 --build-arg NEXT_PUBLIC_INCLUDE_DIGITAL_CREDENTIAL=true --build-arg NEXT_PUBLIC_INCLUDE_BC_SERVICES_CARD=true --build-arg NEXT_PUBLIC_ALLOW_BC_SERVICES_CARD_PROD=true --build-arg NEXT_PUBLIC_INCLUDE_OTP=true --build-arg NEXT_PUBLIC_APP_ENV=local --build-arg NEXT_PUBLIC_SSO_IDP_HINT: azureidir -t sso-requests:latest . cd ./api docker-buildx build -t sso-requests-api . -
Run
make setup_envfrom the root directory to generate,.envfile under./appfolder
-
To build and start the containers (postgres, next app and backend app)
docker-compose up -d
-
To stop the containers
docker-compose down
Add the --volume flag to the previous command to clean up volumes after completion.
- Since
amd64based keycloak images cannot run on Macbooks anymore, below steps are required to setup keycloak - Build base keycloak docker image using
https://github.com/keycloak/keycloak-containers/blob/18.0.2/server/Dockerfile - Use
https://github.com/bcgov/sso-keycloak/blob/dev/docker/keycloak/Dockerfile-7.6for reference to build sso-keycloak:latest - Update
./docker-compose.yamlusing below service configuration
dev-keycloak:
container_name: dev-keycloak
image: sso-keycloak:26.0.6
command: ['-Djboss.socket.binding.port-offset=1000']
depends_on:
- sso-db
ports:
- 9080:9080
environment:
DB_VENDOR: POSTGRES
DB_PORT: 5432
DB_USER: keycloak
DB_PASSWORD: keycloak
DB_ADDR: sso-db:5432
DB_DATABASE: keycloak
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: admin
KEYCLOAK_LOGLEVEL: INFO
ROOT_LOGLEVEL: INFO
networks:
- css-net
We use pre-commit to run local linting when committing changes. To install this as a hook, run
pre-commit installTo run tests for the front-end application, run
make app_testFor the backend application, run:
make api_testWe now have a cypress test suite built out. These can be run against a local version of the app using the docker instances.
- nodejs version 22
- docker-compose 2.39.1
Using docker-compose, run the app locally.
docker-compose build
docker-compose up
Confirm the containers are up using docker ps, there should be six containers running. Confirm the standard realm has been created in the keycloak containers. Local username and password are created by the docker-compose file.
Pull a copy of the sso-requests-e2e repo. The environment will need to be changed to run against the local CSS app. In the file /testing/cypress.env.json set {"host": "http://localhost:3000", "smoketest": true, "localtest": true}.
Currently there are two pieces of seed data needed in the test environment for the tests to run. Any time the local database volumes are purged they will need to be recreated. There is a WIP to automate this using cypress, the documentation will be updated when this is possible.
There is a WIP to do this using cypress, however until that change is merged we need to create a team and integration manually.
Log into the local css app with the default account from the cypress.config.ts file.
The team name is: "Roland and Training Account" and and admin with email "pathfinder.ssotraining2@gov.bc.ca" is added to that team.
The integration that must be created is: "Test Automation do not delete".
- Connect it to the "Roland and Training Account" team.
- It needs three IDPs "Idir", "Idir - MFA", and "Basic or Business BCeID".
- It is integrated with dev, test, and prod.
- The redirect urls are
*,*,any-valid-url.com.
To delete old data run:
npm run delete:local
npm run deleteteams:local
These many not complete successfully, but that will not block the actual tests.
To run all the integration tests, use the command:
npm run integrations:local
Our repository uses commit linting. If pre-commit is installed it will tell you if your commit message is valid.
In general, commits should have the format <type>:name followed by a descriptive lower-case message, e.g:
git commit -m "feat: button" -m "add a button to the landing page".
- When adding functions to call out to APIs (including our backend), those should be included in
app/services. To prevent application errors when using these services, we add error handling in the service function, and return and array[data, error]wheredatawil be null if there was an error, anderrorwill be null if the request succeeded. e.g:
export const getTeamMembers = async (id?: number) => {
try {
const result = await instance.get(`teams/${id}/members`).then((res) => res.data);
return [result, null];
} catch (err) {
return handleAxiosError(err);
}
};-
To help with organization when adding new react components, we have broken them into the following folders:
app/page-partials/<page-name>: Include a component here if it is specific to a page and won't be reusedhtml-components: Include a component here if it is a styled html component, e.gtableorbuttonform-components: Components specific to the form flow should be included here`components: Include other components here
- Most error handling can be done at the route level with
tryandcatch, seelambda/app/src/routes.ts. Controllers will then be caught. More custom error-handling in controller or helper functions should only be added if the specific function failing should still return a 200 status.
The AWS API Gateway is served on custom domains with free public AWS certificates; the main point here is to validate the ownership of the domains via AWS ACM to issue the valid certificate. The steps to attach the validated certificate to the API Gateway servies are:
-
Request a certificate: the following Terraform script creates the certificate: -
Create a CNAME record for validation: once the certificate is created, create aCNAMErecord based on the DNS configuration in DNS panel.- the DNS configuration,
CNAME nameandCNAME value, can be found in theAWS Certificate Manager (ACM).
- the DNS configuration,
-
Wait for the DNS lookup change applied; you can use the online DNS lookup tool to confirm the change:
-
Domain name & API Gateway service binding: after theAWS Certificate Manager (ACM)flags the status of the domain certificate asSuccess, then you can attach the domain address to the API Gateway service. -
Create a CNAME record for the domain: once the API Gateway is properly configured with the random domain endpoint created, create anotherCNAMEthat points to the random domain endpoint.