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

The main channels of communication are:


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. ⚠️ Does this need to be public?
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.

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.

talento.laboratoria.la

Job Placement App

It's public website to show your graduate's profile to the hiring companies.

admission.laboratoria.la

An application for applicants of Laboratoria to go through the admission process.

aprende.laboratoria.la (Corporate Training)

laboratoria-admin

CLI tool used for amdin tasks related to API and LMS.

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

  • JavaScript (E6, ES7, ES8)
  • Node.js / NPM / Yarn
  • Git + GitHub
  • Markdown

Backend

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).

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

Jest

Continuous Integration

Travis CI

.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

eslint-config-airbnb-base

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

eslint-config-airbnb

CSS

airbnb/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:

  1. Pass all tests (npm test).
  2. Have coverage above 80% (npx jest --coverage).
  3. Increase the version number in package.json.
  4. Be tagged using the following format: v followed by a semver version (ie: v1.0.0, v2.3.11, v2.0.0-alpha.1, ...).
  5. Push tag to upstream's master branch.
  6. Include title, description, changelog, upgrade instructions, ... in GitHub release.
  7. Be installable via npm i Laboratoria/repo-name#version-tag is an npm module or CLI tool.
  8. 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

???

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.