Developer Guide
Want to contribute and work on FindNUS? This is the guide for you.
This guide covers how to setup the development environment for the Frontend and Backend respectively.
You will need Node.js to be installed to run npm. We recommend the LTS version of Node.js >= 16.13, which can be downloaded here for Windows/MacOS. For installation via package managers, refer to this page instead.
Firebase CLI is required for running tests, or if you wish to make amendments to the Emulator Suite. To install, run the following command:
npm install -g firebase-tools
git clone https://github.com/FindNUS/frontend.git
cd frontend
npm install
There are two environment variables required for the Google Maps API integration. You will need to set the following configurations in the Google Cloud console under “APIs & Services” > “Credentials”
Variable Name | API Restrictions | Application Restrictions | Website Restrictions |
---|---|---|---|
REACT_APP_MAPS_EMBED_KEY | Maps Embed API | HTTP referrers (web sites) | example.com/* example.com/*/* |
REACT_APP_MAPS_GEOCODING_KEY | Geocoding API Maps JavaScript API | Same as above | Same as above |
Note: It is possible to skip this step and use one API key for both environment variables with no application/website restrictions during development. However we do not recommend this to be done in production to prevent unauthorised use of your API key, as it is accessible by the user (Click here for more information).
An authentication token is required for running tests on the Emulator Suite. You may generate the token with the following command:
firebase login:ci
Upon logging in to your Google account, you will be provided with an access token in the command line. Store this key as FIREBASE_TOKEN
.
Make a copy of .env.example and rename it as
.env
Configure the project in the
.env
file by setting the parameters corresponding to your firebase project, the path to API, and the parameters as described aboveDepending on your application environment,
REACT_APP_DEPLOY_ENV
should be set accordingly toproduction
,development
ortest
.Note: The backend setup must be linked to the same firebase project
- Run
npm start
to initialise the local server
We follow the Gitflow branching strategy to ensure we always have a production-ready branch (main
). All pull requests for feature branches (feature/*
) should be merged into the dev
branch.
We follow the Semantic Versioning 2.0.0 standard when publishing releases.
You need to have golang >=1.18 installed.
Install guide for Windows/MacOS.
Install via Linux Package Managers or MacOS Brew:
# This varies based on your package manager
$ sudo apt install golang-go
If you wish to directly build and test the docker microservices for whatever reason, you need to install docker.
Install guide for Windows/MacOS.
Install via Linux Package Managers or Macos Brew -> This is a more involved process.
If you are working on the backend
microservice and changing the HTTP endpoints that interfaces with the Frontend, you must download this in order to work on the Backend RESTul API documentation.
# Assumes you have npm installed
npm install -g openapi3-generator
Simply clone the project and branch out from dev
.
git clone https://github.com/FindNUS/backend.git
# Switch to the dev branch
git branch dev
# Create your own branch to work on some feature
# Branch naming convention example: feat/CatPicture-Integration-120622
git checkout -b <type>/<descripton>-<date DDMMYY> dev
Each microservice is logically separated in /internal/{Microservice Name}
.
If you are working on, say the item
microservice, you need to install item
’s go package dependecies.
cd /internal/{Microservice Name}
go get .
After that, you are free to work on the files in the project and develop on FindNUS’ backend!
If you are modifying/adding a new endpoint or changing anything that interfaces directly with Frontend, you MUST update the API documentation.
The backend API documentation is kept in /api
. Edit the documentation via findnus.yaml
in accordance to OpenAPI3.0 Specs. Once you are done, build the human-friendly docs via the build script provided under /scripts
.
# Root directory of project
cd /scripts
bash build_api_docs.sh
Where possible, unit test critical functions. This is easily done in golang.
For example, to test foo.go
, create foo_test.go
in the same folder.
Then, in foo_test.go
, prepend the function to be tested with Test.
Trivial Example:
// foo.go
func Add(x int, y int) int{
return x+y
}
// foo_test.go
func TestAdd(t *testing.T){
x1 := 2
x2 := 40
res := Add(x1, x2)
if res != 42 {
t.Fail()
t.Log("Expected 42 but got", res)
}
}
The above is a trivial test case for demonstration purposes. It is not rigorous enough for production You should ideally design your testcases to cover all sorts of edge cases. If you need to use a file to store testcase data, simply make a test
directory within internal/{Microservice Name}
and store your txt/json/whatever data there. You can get inspiration from some of our actual unit test examples here.
Secrets are exposed to the Docker container via environment variables.
- If you are adding features that need secrets such as an API key, ping the maintainer to have it registered under the official findnus email and to be added to the repository secrets list on Github.
- Update the following files to ensure that the secrets are being passed to the program at Deploy time
/.github/workflows/deploy_<microservice>.yml
/.github/workflows/test_<microservice>.yml
/build/<microservice>.Dockerfile
Secrets should NEVER be exposed as plaintext in your code. If you need to test locally, consider creating a secrets
folder that is added to the .gitignore
to store the confidential information that can be loaded on demand. A boilerplate example used in our live codebase:
someSecret := os.Getenv("SOME_SECRET")
var err error
if someSecret == "" {
// Read from secrets file
f, err := os.Open("../../secrets/someSecret.txt")
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(f)
defer f.Close()
for scanner.Scan() {
someSecret = scanner.Text()
}
}
We follow a strict PR flow to ensure changes do not break FindNUS backend.
- We compile all experimental/fresh changes into the dev branch
- The dev branch is put through regression unit testing. Once passed, it is PR-ed into UAT (staging) environment for system testing
- The UAT environment, once tested will be merged with
main
as a release
PR into UAT
and MAIN
will be done by key appointment holders/maintainers as they involve Heroku deployment checking and debugging. For all other purposes, when you PR into dev, you will be subject to a Unit Test of your code as well as a code review by the maintainer before it gets accepted into dev.
<feat>/<name>-<date>
-> dev
-> uat
-> main
Your PR should be descriptive and have a detailed changelog, referencing issues where appropriate.