Laboratoria Developers Chapter
The Developers Chapter at Laboratoria is a community made up of all the developers within the organisation. That includes any Laboratorian that fits the developer profile: developers working on software products, coaches, ...
The DevsChapter's main goal is to promote peer learning, sharing and cross-pollination across teams. The community has a bunch of resources to enable collaboration, sharing and support among devs.
The DevsChapter also serves the purpose of providing design, implementation and collaboration guidelines.
As part of the team at Laboratoria, we invite you to familiarise yourself with our digital etiquette.
TOC
- Resources
- Rituals
- Products
- Stack
- Coding standards
- Git Workflow
- Dependency management
- Internationalisation
- Releases
- Deployment
- Code of conduct
Resources
The main channels of communication are:
- The website at developers.laboratoria.la
- The #developers channel Laboratoria's Slack
- The DevsChapter category on our forum at community.laboratoria.la
- This repo with info and guidelines.
- The repos under the Laboratoria org on GitHub (repos, projects, issues, milestones, ...)
- The developers blog on Medium
- The YouTube channel
- The mailing list (developers@laboratoria.la)
Rituals
Monthly hangouts
Announced in the DevsChapter category on our forum at community.laboratoria.la.
NOTE: This is currently being discussed here.
View calendar.
Pair programming
As part of the chapter, we encourage peer-learning and peer-review. As such, we recommend devs pairing up with peers (both product devs and coaches) when designing and implmenting software.
A clearer way for achieving this in practice still needs to be agreed.
Code review
As a rule of thumb, every PR that will potentially end up in production (as in a release that will be used by other people), should have been reviewed by at least two people. Each product/project has its own rules and conventions, but ideally repos will enforce reviews.
When sending a PR with new features always include context, design proposal and instructions on how to test/verify the changes. Reviewing is hard, let's always try to make it as easy as possible for potential reviewers.
Office hours
All devs are encouraged to seek office hours with more senior devs (or other peers) in order to answer questions, ask for help, deep dive into a topic, ... or whatever you may be struggling with.
In order to book office hours please contact directly the dev you'd like to book time with (via Slack). The following devs have offered themeselves to provide these office hours:
Contributing
We tag issues as help-wanted
😉
Each repository should have a CONTRIBUTING.md
file with a contributing guide
for potential contributors.
Products
Open Source
Product | Maintainers | Description |
---|---|---|
bootcamp | @lupomontero, @lalogf, @rafaelbcerri | Bootcamp Curriculum (JavaScript + UX). |
curriculum-parser | @lupomontero, @MaiaRojas | CLI tool used to parse curriculum topics and projects in Markdown format and produce a JSON representation to be later pushed to the database. |
schemas | @raulingg | Mongoose schemas describing shared entities. This module is meant to be used both in Node.js and in the browser. |
models | @raulingg | Mongoose models based on schemas . This module is meant to be used ONLY in Node.js. |
firemin [DEPRECATED] | @lupomontero | Firebase/Firestore extra CLI features. This is mainly used to interact with firestore as the official firebase CLI tool doesn't include much functionality for firestore . |
mdlint | @lupomontero | Markdown linter (CLI) used in bootcamp . |
developers.laboratoria.la | @lupomontero, @bouli, @raulingg | DevsChapter's conventions, guidelines and website. |
laboratoria-ui | @lalogf | It's our React Components library, extended from Material-UI. The proposal is to standardize our components and Laboratoria's brand in our products. |
fetch-gsheets | @lupomontero | CLI tool used to extract data from Google spreadsheets as JSON. |
Private repos
api.laboratoria.la
HTTP JSON API sitting on top of our databases (Firestore and MongoDB), offering a single point of access for authentication and data from any of our apps. This app is currently hosted as Firebase Cloud Functions.
- PM: @bouli
- Tech lead: @raulingg
- Devs: @MaiaRojas, @RuthMeryCardenas, @arku, @AnaSalazar, @lizzie136
lms.laboratoria.la
Learning Management System (LMS). This is the main web interface used by our students (both Bootcamp and L4B) in order to follow our different training programs.
- PM: @chamodev
- Tech lead: @MaiaRojas
- Devs: @jaunjordan, @lupomontero
talento.laboratoria.la
Job Placement App
It's public website to show your graduate's profile to the hiring companies.
- PM: @gaposx
- Tech lead: @AnaSalazar
- Devs: @RuthMeryCardenas
admission.laboratoria.la
An application for applicants of Laboratoria to go through the admission process.
- PM: @rocioalberdi
- Tech lead: @raulingg
- Devs: @arku
aprende.laboratoria.la (Corporate Training)
- PM: @danijc60s
- Tech lead: @arku
- Devs: @lizzie136
laboratoria-admin
CLI tool used for amdin tasks related to API and LMS.
- Tech lead: @lupomontero
www.laboratoria.la
Instapage???
community.laboratoria.la
???
Stack
tl;dr
: Full Stack JavaScript, and we favor the functional paradigm,
TDD, and if it can be a pure function, it must be one.
Core
Backend
- Firebase (hosting)
- Firebase functions (hosting)
- Firestore (database)
- MongoDB / Atlas
- Express
Frontend
In this blog post you can find a description of the basic JavaScript stack we use in the front-end (article is in spanish).
- Babel
- Webpack
- Redux
- React
- Material UI ????
create-react-app
???- Boilerplate ???
Testing, building and CI
npm-scripts
As a task runner we use vanilla npm-scripts
.
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"pretest": "eslint .",
"test": "jest --verbose --coverage",
"build": "./scripts/build.sh",
"deploy": "gh-pages -d build"
},
...
}
Linter
All projects containing JavaScript should lint the source code using
ESLint. Check the Coding standards
section for details on the different eslint
configurations used in different
environments.
Make sure your package.json
includes a pretest
script (as in
npm-scripts
). For example:
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"pretest": "eslint .",
"test": "jest --verbose --coverage"
},
"devDependencies": {
"eslint": "^5.13.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.16.0",
"jest": "^24.1.0"
}
}
Unit tests
Continuous Integration
.travis.yml
language: node_js
node_js:
- 8
- 10
Status badge
Code coverage
npx jest --coverage
xdg-open coverage/lcov-report/index.html
Coveralls??
Other
- Zapier
- TypeForm
- Spreadsheets
- Mandrill
- ...
Coding standards
All text formats should follow the guidelines provided in our etiquette, including plain text and markdown.
Javascript
yarn add -D eslint eslint-config-airbnb-base eslint-plugin-import
.eslintrc
.eslintignore
Node.js
v8
vs v10
require
vs import
???
Package manager? yarn
vs npm
???
npm
in cli apps ???
React/JSX
CSS
JSS??? Styled Components???
HTML
???
Shell
Bash???
Git Workflow
Git Hooks?? Husky? @gmoura???
See GIT_WORKFLOW.md.
Dependency management
When and how to upgrade deps.
Semver (^
, ~
and pinning deps).
npm
vs yarn
Lock files (when to add to git and when not to).
Internationalisation, localisaion and translation
react-intl
Releases
We aim to use Git, GitHub, NPM and Travis for all (or most) repos, and our release process relies heavily on these. By this we mean that releases MUST:
- Pass all tests (
npm test
). - Have coverage above 80% (
npx jest --coverage
). - Increase the version number in
package.json
. - Be tagged using the following format:
v
followed by asemver
version (ie:v1.0.0
,v2.3.11
,v2.0.0-alpha.1
, ...). - Push tag to upstream's
master
branch. - Include title, description, changelog, upgrade instructions, ... in GitHub release.
- Be installable via
npm i Laboratoria/repo-name#version-tag
is annpm
module or CLI tool. - Be deployable via
npm deploy
.
Example using git
and npm
(with manual deploy):
# Releases are normally tagged from `master`, so we switch to `master` if we are
# on a different branch.
git checkout master
# Merge in `develop` branch if not already merged.
git merge develop
npm test
npx jest --coverage
# Run build if required
npm run build
# The following command increases the "patch" number in `package.json` and adds
# a new `git` "tag" (ie: for version 1.0.0 it creates tag "v1.0.0").
npm version patch -m "bump to %s"
# We can also increase minor and major numbers with `npm version`:
# npm version minor -m "bump to %s"
# npm version major -m "bump to %s"
# Once we have tagged our release we push the new tag to upstream master
git push upstream master --tags
# Check Travis build
npm run deploy
# Go back to develop branch and update it with master's changes
git checkout develop
git merge master
git push upstream develop
A few notes on version numbers and semver
We adhere to the Semantic Versioning as described here: https://semver.org/
We also use git
tags with a v
followed by the release number.
Releases
- Major (new API, breaking changes)
- Minor (new features, internals, backwards compatible non-breaking changes)
- Patch (hot fixes and minor patches)
Example: 2.1.3
(major: 2
, minor: 1
, patch: 3
)
Pre-releases
The same as with releases, but adding the alpha
, beta
or bc
plus a
number. Pre-releases are not normally used for patches.
alpha
: implies unstable implementation in design stage.beta
: denotes a pre-release is ready to be tested with users in a controlled environment, still open to changes and redesign.rc
: (release candidate) is used when design is locked and only minor issues are still to be addressed.
For example:
2.0.0-alpha.1
< 2.0.0-alpha.2
< 2.0.0-beta.1
< 2.0.0-rc.1
< 2.0.0-rc.2
< 2.0.0
< 2.0.1
< 2.1.0
< 3.0.0-alpha.1
Deployment
Each repo should have detailed deployment documentation available in the repo's
README.md
file. In this document we aim to provide some context and guidelines
for different kind of repos.
Domains
Our domain name registrations are managed via Digital Ocean.
laboratoria.la
DNS
We currently use Digital Ocean to manage DNS. A proposal was made a while ago to move DNS to CloudFlare in order to get DDoS protection as well as free SSL and other useful features.
SSL
???
- https://www.laboratoria.la/ (???)
- https://api.laboratoria.la/ (SSL provided by Firebase)
- https://lms.laboratoria.la/ (SSL provided by Firebase)
- https://app.talento.laboratoria.la/ (???)
- http://developers.laboratoria.la/ (SSL provided by GitHub Pages)
- http://community.laboratoria.la/
⚠️
Node.js modules and CLI tools
For the time being we are using GitHub releases for our npm
modules and CLI
tools. This means that modules can be installed via
npm i Laboratoria/repo-name#tag
, or adding to your package.json
.
Example as dependency in package.json
:
{
"dependencies": {
"schemas": "Laboratoria/schemas#v1.0.0-alpha.3"
}
}
Example installing the curriculum-parser
globally:
# install current release
npm i -g Laboratoria/curriculum-parser
# install a specific version
npm i -g "Laboratoria/curriculum-parser#v2.0.0-alpha.2"
GitHub vs NPM Orgs???
Node.js Servers
Zeit.co vs Docker vs VM
talento.laboratoria.la y api-next???
Cloud functions
Firebase functions
Static hosting
- Firebase hosting
- ...
Databases
Firestore
MongoDB
Atlas vs Docker vs VM
Continuous delivery
Projects requiring deployment to 3rd party service (ie: Firebase, Zeit, NPM, ...) should aim to use continuous delivery using Travis' Deployment features.
Let's see an example using a custom script to deploy Firebase.
Let's start with the package.json
. The important thing here is that we have
a deploy
key in scripts
:
{
"scripts": {
"deploy": "firebase deploy"
},
"dependencies": {
"firebase-tools": "6.4.0"
}
}
This will allow us to manually invoke our deploy command:
npm run deploy
# or passing some flags...
npm run deploy --project staging-env
npm run deploy --only functions
Now that we have defined our deploy
task as an npm-script
, let's look at the
deploy script that we want Travis to trigger. In this example we will use a
shell script (ie: scripts/deploy.sh
):
#! /usr/bin/env bash
deploy() {
echo "Deploying to project ${1}..."
npm run deploy --project ${1} --token "$FIREBASE_TOKEN"
}
if [[ "${TRAVIS_TAG}" == v* ]]; then
deploy production-env
elif [[ "$TRAVIS_BRANCH" == "develop" ]]; then
deploy staging-env
else
echo "ignoring branch ${TRAVIS_BRANCH}..."
exit 0
fi
As we see in our script, we are assuming an environment variable called
FIREBASE_TOKEN
exists (and hopefully with the right value). We do not want to
add secrets like this token to the source code, and we want to make sure they
remain secret. To achieve this we use encrypted environment variables.
To do so you will need to install the travis
CLI tool.
gem install travis -v 1.8.9 --no-rdoc --no-ri
Now that we have the travis
CLI, we can create a Firebase CI token and then
encrypt it.
# This generates a token, e.g. "1/AD7sdasdasdKJA824OvEFc1c89Xz2ilBlaBlaBla"
firebase login:ci
# Encrypt the token
travis encrypt FIREBASE_TOKEN="1/AD7sdasdasdKJA824OvEFc1c89Xz2ilBlaBlaBla" --add
The --add
flag in the previous command should automatically add the encrypted
variable to your .travis.yml
. Now it's time to add the deploy
(and
optionally before_deploy
keys to our .travis.yml
:
language: node_js
node_js:
- 10
env:
- secure: "XXXXXXXXXXXX="
before_deploy:
- echo "Do something before deploying!"
deploy:
provider: script
script: ./scripts/deploy.sh
skip_cleanup: true
on:
repo: Laboratoria/some-repo
all_branches: true
Code of conduct
See CODE_OF_CONDUCT.md.