Skip to content

Commit

Permalink
docs: start developer best practices docs
Browse files Browse the repository at this point in the history
  • Loading branch information
spwoodcock committed Nov 27, 2023
1 parent 6362114 commit 84644d8
Show file tree
Hide file tree
Showing 15 changed files with 366 additions and 0 deletions.
106 changes: 106 additions & 0 deletions docs/dev-guide/containers_101.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Containers Intro

## Why Use Containers

### The Traditional Setup

- Host machine resources divided up into multiple virtual machines.
- Each virtual machine running an application.
- This has no ability to scale resources on the virtual machines:
- At times of heavy load the machine resources are limited.
- At times of low load the resources are under-utilised.

![ContainersVsVMS](../images/containers_vs_vms.png)

### The New Way

- Containers remove the need for virtual machines, by providing the
isolation required between applications while retaining access to the
essential low level operating system components on the main machine.
- Instead of multiple separate operating systems running, a single
operating system is required. Much more efficient.

## Cool. What can I use them for?

- Managing dependencies: isolating your code and dependencies from the
host operating system allows you to have different versions of
software installed in different containers.
- Running software without an install: for example the utility `rclone`
can be used from it's container image (a pre-packaged environment,
with all required dependencies: docker.io/rclone/rclone), instead of
installing directly on your machine. Clean.
- Packaging your code for distribution or deployment: written a
backend in Django? It can be packaged up into an image and deployed
anywhere that has a container engine. Your laptop, WSL server,
AWS, Azure… you name it.

**Containers are now the de-facto way to distribute software.
Software developers are required to know the basics of what they are,
how to build an image, and how to use a container.**

## Definitions

> Note: 'Docker' is often used in place of the word 'Container',
> as this was the main project to popularise containers.
- **Container (Docker Image)**: essentially a frozen state of an
operating system, including filesystem, built-in command line tools,
and your application code. This is built from a series of build
instructions, almost exactly how you would have deployed your
application onto a virtual machine.
- **Container**: a container image is used to create a running container.
When you run a container, you may wish to specify a network to attach
to, files to mount into the container, and other things.
- **Volume**: when a container is shut down, the filesystem is normally
lost - it is ephemeral. A volume allows you to keep data after
the containers lifecycle.

## Docker vs Kubernetes vs Other

- In the graphic above, Docker would be the **Container Engine**. It is
what actually executes the commands to run the container and keep it running.
- Docker runs on your local machine with single containers.
The Docker Inc made a product called Docker Swarm, to allow for the
management of containers across a fleet of servers.
It essentially lost the battle to a Google-backed tool called Kubernetes.
- Kubernetes is a container orchestration tool and now the standard for
how businesses deploy their software, in a way that is resilient to
server crashes, code logic errors, etc.
- If a process fails on one server, e.g. a Django API server, it
will automatically be replaced by an equivalent container on another server.

## Show Me the Code

### Running containers

[https://docs.docker.com/engine/reference/commandline/run/](https://docs.docker.com/engine/reference/commandline/run/)

- Run a simple Ubuntu container, based off the Ubuntu Focal image:

```bash
docker run -it docker.io/ubuntu:focal bash
```

- The -it flag is to tell docker to open an interactive ('i') terminal
('t') for you to type commands into the container.
- The command after the image name is simply `bash`, which runs a bash
terminal (as opposed to a basic shell terminal: `sh`).
- The other mode to run containers is detached (-d), but for this you
need a process to run, for example python /app/code/main.py

### Building Images

Two components are required here:

- A Dockerfile (Containerfile). This contains the commands, in order,
that install the dependencies from base image (e.g. Ubuntu), then add
your application code into the image.
- A build instruction. The command line instruction to build an image,
giving it a name etc:
[https://docs.docker.com/engine/reference/commandline/build/](https://docs.docker.com/engine/reference/commandline/build/)

Example build:
[https://docs.docker.com/get\-started/02_our_app/](https://docs.docker.com/get-started/02_our_app/)

Lots of good tutorials can be found online, search for:
Dockerfile build example / tutorial.
25 changes: 25 additions & 0 deletions docs/dev-guide/dep_management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Dependency Management

## Javascript

This section will be brief.

Javascript already has a great dependency management ecosystem.

Tools like NPM, Yarn, PNPM all work in a Node environment to
solve dependency version compatibility and install them locally
within your repo, in a `node_modules` directory.

The only recommendation would be to **use PNPM**, as it has a much neater
concept then the other two tools. Dependency locking is fast, and
package installation is _shared_ across repositories using a global
package store on your system.

This sets the standard for dependency management that some Python
tools have attempted to replicate.

## Python

### Using pyproject.toml

### Dependency Solvers
5 changes: 5 additions & 0 deletions docs/dev-guide/doc_gen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Auto Documentation Generation

## Python

## Javascript
140 changes: 140 additions & 0 deletions docs/dev-guide/git.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Git and Pre-Commit Hooks

## Git - The Basics

Is is a tool we all know and love.

There are a few basic concepts that would be good to master.

### Development Lifecycle

The concept of Continuous Integration means that code is
continually developed and merged into a branch, for testing
or deployment.

CI/CD:

- **CI**: merge frequently into master.
- Minimise merge issues from multiple collaborators.
- **CD**: deploy master frequently to production.
- Regular updates for new features and bug fixes.

The primary branches, in order:

- **Development**: the branch that fixes or features are continually merged.
- **Staging**: where development branch fixes/features are grouped and tested
together, with the intention to push to production once QA/QC passes.
- **Production**: where staging is stabilised and released at intervals as actual
versions of your tool/software.

Additional supporting branches:

- **Fix**: fixes a bug or issue.
- **Feature**: add a new feature that didn't exist before.
- **Hotfix**: if an issue is found after a production release is made, a hotfix
can be used to patch the production code.

### Git Flow

Git flow is a branching model.

The most basic version of this would be:

`feature` or `fix` --> `main` (production)

![GitFlow](../images/git_flow.png)

Adding in the extra steps of the described development lifecycle, we get:

`feature` or `fix` --> `development` --> `staging` --> `main` (production)

![GitFlow](../images/git_flow_plus.png)

The number of additional stages can be flexible depending on requirements.

### Forking

To work on an open-source repository, generally you may not have
direct access to the repo from the start.

A common pattern is to make your own copy of the repo, a 'fork'
of it to work on.

Within this repo you create a new branch:

```bash
git checkout -b feat/some-new-feature
```

Then when you push the branch to your fork, generally a code hosting
platform like Github/Gitlab will prompt you to create a **Pull Request**
or **Merge Request** (the same thing).

### Pull Requests

A pull requests (PR) is used to merge the code from your forked
repository into the original code repository.

You should describe as accurately as possible what solution your
code provides, or feature it adds, and why it is necessary.

Ideally try to link it to an existing Issue in the repository issue board.

The maintainer of the repo will review your code, comment, and merge it in.

### Rebasing

This is often a scary concept to many.

It essentially re-writes the Git history on a branch, so
use with care.

**Use case**: sometimes your code gets out of sync with the target
branch you originally branched from.

For example you branched from `develop` to a branch `feat/some-new-thing`.

If you wish to pull in the latest updates from the `develop` branch into
your feature branch, you can do a rebase:

```bash
git checkout develop
git pull
git checkout feat/some-new-thing
git rebase develop
```

This will insert the updates **below** your code edits. I.e. the history
will show your commits on top of the most recent `develop` commits.

Visually this will be:

![Rebase](../images/rebase.png)

### Merge vs Rebase

- Use merge for feature → main (work finished).
- When on develop use merge to include a (idealy finished) feature
- Use rebase for develop → feature (work in progress).
- When on the feature branch use rebase from develop to include
the latest changes
- Regularly rebasing feature branches will keep them up to
date with current features (either from main or develop).
- This means that conflicts can be resolved gradually,
instead of in one go during a merge.

[The Perils of Rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)

**The most important take away**: rebase is a powerful tool, but be wary using
it if you are collaborating with someone on the **same** feature branch.

If a teammate happens to rebase a branch that you are working on, the
easiest solution is to stash and reset to get the rebased edits:

```bash
git stash -u
git fetch origin feat/new-thing
git reset --hard feat/new-thing
git stash apply
git stash drop
```
Binary file added docs/dev-guide/image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dev-guide/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions docs/dev-guide/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Development Guide

The HOT Tech Team comprises a dynamic assembly of highly skilled
individuals, each bringing a diverse range of expertise and
backgrounds. United by a shared commitment, our goal is clear:
leveraging technology to contribute to a better world.

The tech team includes a core of software developers who co-develop
many of the tools listed in this documentation index.

There is also a large community of developers who helps to facilitate
this work: from consultants, NGOs, and innovative tech agencies
distributed throughout the world.

The aim of this development guide is twofold:

## Guidelines for Collaborators

Open-source is at the heart of everything we do. In order to collaborate
effectively, it is important to have a set of agreed upon standards and
practices that developers must loosely follow.

## A Resource for New Developers

We encourage new developers to start their open-source contribution
journey with us. We are a welcoming, considerate, and patient bunch.

The consensus-based information here is not an authoritative source
of the only approach to software development.
Nevertheless, we firmly believe that adhering to the recommendations
in this guide will undoubtedly set you on the path to becoming a skilled
software professional, grounded in our collective experiences at HOT.

If these documents help a single new developer on their journey
from coding zero to hero, then it has been a success.
32 changes: 32 additions & 0 deletions docs/dev-guide/pre_commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Pre-Commit Hooks

## Git Hooks

Git has **hooks**, which can run code on various events:

- Prior to commiting code (pre-commit).
- After committing code (post-commit).
- After checking out a branch (post-checkout).
- Before rebasing (pre-rebase).
- Etc.

## Pre-Commit

- Pre-commit Git hooks run checks before a commit is accepted.
- Pre-commit is a package to automate the setup.
- After config, issues such as syntax errors and security flaws are picked up.
- Used mostly for formatting and linting.
- Linting is checking code against a set of formatting rules
and for syntax errors.

## Pre-Commit (Python Tool)

...

### Add pre-commit-config.yaml

...

### Add Hooks

...
9 changes: 9 additions & 0 deletions docs/dev-guide/version_control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Version Control

## Semantic Versioning

## Conventional Commits

## Tools

### Commitizen
5 changes: 5 additions & 0 deletions docs/dev-guide/web_frameworks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Web Frameworks

## Python

## JavaScript
Binary file added docs/images/containers_vs_vms.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/git_flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/git_flow_plus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/rebase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,14 @@ nav:
- Underpass UI: https://hotosm.github.io/underpass-ui/
- DevOps:
- Reusable Workflows: https://hotosm.github.io/gh-workflows/
- Developer Guidelines:
- Intro: dev-guide/intro.md
- Git: dev-guide/git.md
- Pre-Commit: pre_commit.md
- Containers 101: dev-guide/containers_101.md
- Dependency Management: dev-guide/dep_management.md
- Version Control: dev-guide/version_control.md
- Generating Docs: dev-guide/doc_gen.md
- Web Frameworks: dev-guide/web_frameworks.md
- E2E Diagrams:
- TODO: https://hotosm.org

0 comments on commit 84644d8

Please sign in to comment.