add knowledge
This commit is contained in:
@@ -1,12 +1,61 @@
|
||||
# devops-guide
|
||||
# DevOps Guide
|
||||
|
||||
>DevOps is a set of practices that integrates software development and operations to deliver changes faster, more reliably, and with continuous feedback.
|
||||
> DevOps is the practice of reducing friction between writing code and running it reliably in production — giving you **reproducibility**, **fast feedback**, and **confidence at scale**.
|
||||
|
||||

|
||||
|
||||
---------
|
||||
---
|
||||
|
||||
## Getting started
|
||||
## Problem → Tool Category
|
||||
|
||||
- install cli tooling: https://git.roxautomation.com/sjev/cli-tools
|
||||
- python cli template: https://git.roxautomation.com/sjev/python-cli-template
|
||||
| Problem | Tool Category |
|
||||
|---|---|
|
||||
| Code gets lost, no change history | [Version Control](docs/version-control.md) |
|
||||
| "Works on my machine" | [Containerization](docs/containerization.md) |
|
||||
| Dependency conflicts between projects | [Package Management](docs/package-management.md) |
|
||||
| Style drift, bugs slip through review | [Linting & Formatting](docs/linting-formatting.md) |
|
||||
| Type errors discovered at runtime | [Type Checking](docs/type-checking.md) |
|
||||
| Regressions go undetected | [Testing](docs/testing.md) |
|
||||
| Manual, repetitive dev commands | [Task Automation](docs/task-automation.md) |
|
||||
| Nobody knows how to run the project | [Documentation](docs/documentation.md) |
|
||||
| Slow, manual deployments | [CI/CD](docs/ci-cd.md) |
|
||||
|
||||
---
|
||||
|
||||
## Tool Matrix by Language
|
||||
|
||||
### Language-Agnostic
|
||||
|
||||
| Category | Tool(s) |
|
||||
|---|---|
|
||||
| Version control | Git + GitHub / GitLab / Gitea |
|
||||
| Containerization | Docker |
|
||||
| CI/CD platform | GitHub Actions, GitLab CI, Gitea Actions, Jenkins |
|
||||
|
||||
### Language-Specific
|
||||
|
||||
| Category | Python | JavaScript | Go | C++ |
|
||||
|---|---|---|---|---|
|
||||
| **Package management** | uv, pip, poetry | npm, pnpm, yarn | go mod | conan, vcpkg, cmake |
|
||||
| **Linting / formatting** | ruff, pylint, flake8 | eslint, prettier, biome | golangci-lint, gofmt | clang-tidy, clang-format |
|
||||
| **Type checking** | mypy, pyright | tsc, flow | built-in | built-in + clang-tidy |
|
||||
| **Testing** | pytest, hypothesis | vitest, jest, mocha | testing (stdlib), testify | googletest, catch2 |
|
||||
| **Task automation** | invoke, make, tox | npm scripts, turbo, nx | make, mage, task | cmake, make, ninja |
|
||||
| **Docs** | mkdocs-material, sphinx | VitePress, Docusaurus | pkgsite, godoc | doxygen, sphinx |
|
||||
|
||||
---
|
||||
|
||||
## Minimal "Good Enough" Stack
|
||||
|
||||
If you strip it to essentials:
|
||||
|
||||
| Tool | Purpose |
|
||||
|---|---|
|
||||
| `git` + GitHub | History + collaboration |
|
||||
| `uv` | Env + dependencies |
|
||||
| `ruff` + `mypy` | Correctness |
|
||||
| `pytest` | Confidence |
|
||||
| `invoke` | Dev UX |
|
||||
| Docker | Reproducibility |
|
||||
|
||||
Add a tool only when you feel the pain it fixes.
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# CI/CD
|
||||
|
||||
Automatically run tests, linting, and deployment on every push — catch problems before they reach users.
|
||||
|
||||
## Tools
|
||||
|
||||
| Platform | Trigger | Self-hosted runner |
|
||||
|---|---|---|
|
||||
| GitHub Actions | push, PR, schedule | yes |
|
||||
| GitLab CI | push, MR, schedule | yes |
|
||||
| Gitea Actions | push, PR | yes |
|
||||
| Jenkins | any (webhook/poll) | yes |
|
||||
|
||||
CI/CD is a platform-level choice, not a language one. The pipeline calls your existing `invoke`/`make` tasks.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
- **CI (Continuous Integration)** — run tests on every commit; fail fast
|
||||
- **CD (Continuous Delivery/Deployment)** — automatically ship passing builds
|
||||
- **Pipeline as code** — the config lives in the repo (`*.yml`), versioned alongside the code
|
||||
- **Local CI first** — Docker-based local runs before pushing; remote CI is the final net, not the primary feedback loop
|
||||
|
||||
## GitHub Actions — Minimal Python Pipeline
|
||||
|
||||
```yaml
|
||||
# .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- run: pip install uv && uv pip install --system -e ".[dev]"
|
||||
- run: ruff check .
|
||||
- run: mypy .
|
||||
- run: pytest
|
||||
```
|
||||
|
||||
## GitLab CI — Equivalent
|
||||
|
||||
```yaml
|
||||
# .gitlab-ci.yml
|
||||
image: python:3.12-slim
|
||||
|
||||
test:
|
||||
script:
|
||||
- pip install uv && uv pip install -e ".[dev]"
|
||||
- ruff check .
|
||||
- mypy .
|
||||
- pytest
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Keep pipelines fast — slow CI gets ignored
|
||||
- Cache dependency installs (e.g. `actions/cache` on `~/.cache/uv`)
|
||||
- Use matrix builds to test across Python/Node versions when it matters
|
||||
@@ -0,0 +1,49 @@
|
||||
# Containerization
|
||||
|
||||
Package your app and its environment together so it runs identically on every machine — dev, CI, and production.
|
||||
|
||||
## Tools
|
||||
|
||||
**Docker** is the standard. Everything else (Podman, containerd) is compatible with Docker images.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
- **Image** — a snapshot of your app + OS + dependencies
|
||||
- **Container** — a running instance of an image
|
||||
- **Dockerfile** — the recipe for building an image
|
||||
- **Local CI pattern** — run your test suite inside a container before pushing; catches environment drift before it reaches remote CI
|
||||
|
||||
## Minimal Dockerfile (Python)
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
COPY pyproject.toml .
|
||||
RUN pip install uv && uv pip install --system -e ".[dev]"
|
||||
|
||||
COPY . .
|
||||
CMD ["python", "-m", "mypackage"]
|
||||
```
|
||||
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
# build
|
||||
docker build -t myapp .
|
||||
|
||||
# run
|
||||
docker run --rm myapp
|
||||
|
||||
# local CI — run tests inside the container
|
||||
docker run --rm myapp pytest
|
||||
|
||||
# interactive shell for debugging
|
||||
docker run --rm -it myapp bash
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Use `.dockerignore` to exclude `__pycache__`, `.git`, `.venv`, `*.pyc`
|
||||
- Pin the base image tag (`python:3.12-slim`, not `python:latest`)
|
||||
- Layer ordering matters: copy dependency files before source so the install layer is cached
|
||||
@@ -0,0 +1,51 @@
|
||||
# Documentation
|
||||
|
||||
Make it easy to understand, run, and contribute to your project — for future you and for teammates.
|
||||
|
||||
## Tools by Language
|
||||
|
||||
| Language | Recommended | Alternatives |
|
||||
|---|---|---|
|
||||
| Python | `mkdocs` + Material | sphinx, pdoc |
|
||||
| JavaScript/TS | VitePress | Docusaurus, JSDoc |
|
||||
| Go | `pkgsite`, `godoc` | (built-in tooling is strong) |
|
||||
| C++ | Doxygen | sphinx, mkdocs |
|
||||
|
||||
## Python — MkDocs + Material
|
||||
|
||||
Fast setup, Markdown-based, deploys to GitHub Pages in one command.
|
||||
|
||||
```bash
|
||||
uv add --dev mkdocs-material
|
||||
mkdocs new .
|
||||
mkdocs serve # live preview at localhost:8000
|
||||
mkdocs build # generate static site
|
||||
mkdocs gh-deploy # push to GitHub Pages
|
||||
```
|
||||
|
||||
`mkdocs.yml`:
|
||||
|
||||
```yaml
|
||||
site_name: My Project
|
||||
theme:
|
||||
name: material
|
||||
nav:
|
||||
- Home: index.md
|
||||
- API Reference: api.md
|
||||
```
|
||||
|
||||
## What to Document
|
||||
|
||||
Minimum viable docs for any project:
|
||||
|
||||
1. **What it does** — one paragraph
|
||||
2. **How to install** — exact commands, no assumptions
|
||||
3. **How to run** — quickstart example
|
||||
4. **How to develop** — how to run tests, linting, CI locally
|
||||
|
||||
## Tips
|
||||
|
||||
- Docs live in the repo — version them alongside the code
|
||||
- A README is documentation; don't skip it even for internal projects
|
||||
- Generate API docs from docstrings (`pdoc`, `pkgsite`) rather than writing them twice
|
||||
- Often skipped, always regretted — write docs when the code is fresh
|
||||
@@ -0,0 +1,57 @@
|
||||
# Linting & Formatting
|
||||
|
||||
Catch bugs and style issues automatically — before review, before CI, ideally before saving.
|
||||
|
||||
## Tools by Language
|
||||
|
||||
| Language | Recommended | Alternatives |
|
||||
|---|---|---|
|
||||
| Python | `ruff` | flake8 + isort + black |
|
||||
| JavaScript/TS | `biome` | eslint + prettier |
|
||||
| Go | `gofmt`, `golangci-lint` | staticcheck |
|
||||
| C++ | `clang-tidy`, `clang-format` | cppcheck |
|
||||
|
||||
## Python — `ruff`
|
||||
|
||||
Replaces flake8, isort, and black in one tool. Extremely fast.
|
||||
|
||||
```bash
|
||||
ruff check . # lint
|
||||
ruff check --fix . # lint + auto-fix
|
||||
ruff format . # format (replaces black)
|
||||
```
|
||||
|
||||
Configure in `pyproject.toml`:
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
target-version = "py312"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["E", "F", "I", "UP"]
|
||||
```
|
||||
|
||||
## JavaScript — `biome`
|
||||
|
||||
Single tool for lint + format, no config needed to start.
|
||||
|
||||
```bash
|
||||
biome check . # lint + format check
|
||||
biome check --write . # auto-fix
|
||||
```
|
||||
|
||||
## Go
|
||||
|
||||
`gofmt` is part of the toolchain — just run it.
|
||||
|
||||
```bash
|
||||
gofmt -w .
|
||||
golangci-lint run # broader lint suite
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Run on save in your editor (not just in CI)
|
||||
- Auto-fix on commit via a pre-commit hook or `invoke lint --fix`
|
||||
- Format is non-negotiable; lint violations should be treated as errors in CI
|
||||
@@ -0,0 +1,56 @@
|
||||
# Package Management
|
||||
|
||||
Declare dependencies explicitly, resolve them reproducibly, and isolate environments so projects don't interfere.
|
||||
|
||||
## Tools by Language
|
||||
|
||||
| Language | Recommended | Alternatives |
|
||||
|---|---|---|
|
||||
| Python | `uv` | pip, poetry, pipenv |
|
||||
| JavaScript | `pnpm` | npm, yarn |
|
||||
| Go | `go mod` | (built-in, no alternative needed) |
|
||||
| C++ | `conan`, `vcpkg` | cmake FetchContent |
|
||||
|
||||
## Python — `uv`
|
||||
|
||||
Fast resolver with lock files. Drop-in for pip + venv.
|
||||
|
||||
```bash
|
||||
# create venv and install
|
||||
uv venv
|
||||
uv pip install -e ".[dev]"
|
||||
|
||||
# add a dependency (updates pyproject.toml + lockfile)
|
||||
uv add requests
|
||||
|
||||
# sync from lock file (reproducible installs)
|
||||
uv sync
|
||||
```
|
||||
|
||||
`pyproject.toml` is the single source of truth for dependencies and tool config (PEP 517/518).
|
||||
|
||||
## JavaScript — `pnpm`
|
||||
|
||||
Faster and more disk-efficient than npm; compatible with npm ecosystem.
|
||||
|
||||
```bash
|
||||
pnpm install # install from lockfile
|
||||
pnpm add lodash # add dependency
|
||||
pnpm dlx create-vite # run one-off tool
|
||||
```
|
||||
|
||||
## Go — `go mod`
|
||||
|
||||
Built into the toolchain; no extra install needed.
|
||||
|
||||
```bash
|
||||
go mod init github.com/you/myproject
|
||||
go get github.com/some/package@v1.2.3
|
||||
go mod tidy # remove unused deps
|
||||
```
|
||||
|
||||
## Key Principles
|
||||
|
||||
- Always commit the lock file (`uv.lock`, `pnpm-lock.yaml`, `go.sum`)
|
||||
- Pin to a specific version in production; use ranges only in libraries
|
||||
- Separate dev dependencies from runtime dependencies
|
||||
@@ -0,0 +1,83 @@
|
||||
# Task Automation
|
||||
|
||||
One entry point for all dev workflows — so you don't have to remember long commands or teach them to teammates.
|
||||
|
||||
## Tools by Language
|
||||
|
||||
| Language | Recommended | Alternatives |
|
||||
|---|---|---|
|
||||
| Python | `invoke` | make, tox |
|
||||
| JavaScript/TS | `npm scripts`, `turbo` | nx |
|
||||
| Go | `make`, `task` | mage |
|
||||
| C++ | `cmake`, `make` | ninja |
|
||||
|
||||
## Python — `invoke`
|
||||
|
||||
Define tasks in `tasks.py`:
|
||||
|
||||
```python
|
||||
from invoke import task
|
||||
|
||||
@task
|
||||
def lint(c):
|
||||
c.run("ruff check . && mypy .")
|
||||
|
||||
@task
|
||||
def test(c):
|
||||
c.run("pytest")
|
||||
|
||||
@task
|
||||
def ci(c, lint=True, test=True):
|
||||
if lint:
|
||||
lint(c)
|
||||
if test:
|
||||
test(c)
|
||||
```
|
||||
|
||||
```bash
|
||||
invoke lint
|
||||
invoke test
|
||||
invoke ci
|
||||
```
|
||||
|
||||
## Make (universal fallback)
|
||||
|
||||
Works everywhere, no install needed.
|
||||
|
||||
```makefile
|
||||
.PHONY: lint test ci
|
||||
|
||||
lint:
|
||||
ruff check . && mypy .
|
||||
|
||||
test:
|
||||
pytest
|
||||
|
||||
ci: lint test
|
||||
```
|
||||
|
||||
```bash
|
||||
make ci
|
||||
```
|
||||
|
||||
## JavaScript — npm scripts
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"lint": "biome check .",
|
||||
"test": "vitest run",
|
||||
"ci": "npm run lint && npm run test"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
npm run ci
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Keep task names consistent across projects (`lint`, `test`, `ci`, `build`)
|
||||
- Tasks should call your other tools — they're orchestration, not implementation
|
||||
- `make` is the lowest common denominator; use it when portability matters
|
||||
@@ -0,0 +1,62 @@
|
||||
# Testing
|
||||
|
||||
Verify behavior automatically so you can change code with confidence.
|
||||
|
||||
## Tools by Language
|
||||
|
||||
| Language | Recommended | Alternatives |
|
||||
|---|---|---|
|
||||
| Python | `pytest` | unittest, hypothesis |
|
||||
| JavaScript/TS | `vitest` | jest, mocha |
|
||||
| Go | `testing` (stdlib) | testify |
|
||||
| C++ | `googletest` | catch2, doctest |
|
||||
|
||||
## Python — `pytest`
|
||||
|
||||
```bash
|
||||
pytest # run all tests
|
||||
pytest -x # stop on first failure
|
||||
pytest -k "test_login" # run matching tests
|
||||
pytest --cov=src # with coverage
|
||||
```
|
||||
|
||||
Minimal test:
|
||||
|
||||
```python
|
||||
def add(a: int, b: int) -> int:
|
||||
return a + b
|
||||
|
||||
def test_add():
|
||||
assert add(2, 3) == 5
|
||||
```
|
||||
|
||||
Configure in `pyproject.toml`:
|
||||
|
||||
```toml
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
addopts = "-ra -q"
|
||||
```
|
||||
|
||||
## JavaScript — `vitest`
|
||||
|
||||
```bash
|
||||
vitest run # run once
|
||||
vitest # watch mode
|
||||
vitest --coverage
|
||||
```
|
||||
|
||||
## Go
|
||||
|
||||
```bash
|
||||
go test ./... # run all tests
|
||||
go test -race ./... # with race detector
|
||||
go test -cover ./...
|
||||
```
|
||||
|
||||
## Key Principles
|
||||
|
||||
- Test behavior, not implementation — tests that break on refactors aren't useful
|
||||
- Fast tests get run; slow tests get skipped
|
||||
- Don't mock more than necessary — integration tests catch what unit tests miss
|
||||
- Add a test when you fix a bug; the bug was a missing test
|
||||
@@ -0,0 +1,53 @@
|
||||
# Type Checking
|
||||
|
||||
Catch type mismatches at analysis time, not at runtime. Especially valuable in large codebases and across refactors.
|
||||
|
||||
## Tools by Language
|
||||
|
||||
| Language | Tool | Notes |
|
||||
|---|---|---|
|
||||
| Python | `mypy`, `pyright` | not built-in; add type hints manually |
|
||||
| JavaScript/TS | `tsc`, `flow` | TypeScript is the dominant choice |
|
||||
| Go | built-in | the compiler enforces types |
|
||||
| C++ | built-in + `clang-tidy` | compiler + static analysis |
|
||||
|
||||
## Python — `mypy`
|
||||
|
||||
```bash
|
||||
mypy src/
|
||||
```
|
||||
|
||||
Configure in `pyproject.toml`:
|
||||
|
||||
```toml
|
||||
[tool.mypy]
|
||||
python_version = "3.12"
|
||||
strict = true
|
||||
ignore_missing_imports = true
|
||||
```
|
||||
|
||||
Start with `strict = false` and tighten incrementally. Add `# type: ignore` sparingly — only where third-party stubs are missing.
|
||||
|
||||
## TypeScript — `tsc`
|
||||
|
||||
```bash
|
||||
tsc --noEmit # type-check without emitting JS
|
||||
```
|
||||
|
||||
`tsconfig.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"target": "ES2022"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Type checking and linting are separate concerns — run both
|
||||
- In Python, annotate function signatures first; body annotations add less value
|
||||
- `pyright` (Pylance) gives faster feedback in VS Code; `mypy` is CI-standard
|
||||
@@ -0,0 +1,48 @@
|
||||
# Version Control
|
||||
|
||||
Track every change to your code, collaborate without stepping on each other, and roll back anything.
|
||||
|
||||
## Tools
|
||||
|
||||
**Git** is the universal standard. Pair it with a hosting platform for collaboration and access control.
|
||||
|
||||
| Platform | Self-hosted | Cloud |
|
||||
|---|---|---|
|
||||
| GitHub | — | github.com |
|
||||
| GitLab | yes | gitlab.com |
|
||||
| Gitea | yes | — |
|
||||
|
||||
## Key Concepts
|
||||
|
||||
- **Commit often** — small, atomic commits are easier to review and revert
|
||||
- **Branch per feature** — keeps main stable and deployable at all times
|
||||
- **Merge/rebase before pushing** — resolve conflicts locally, not in CI
|
||||
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
git init
|
||||
git add .
|
||||
git commit -m "initial commit"
|
||||
|
||||
# branch workflow
|
||||
git checkout -b feature/my-thing
|
||||
# ... make changes ...
|
||||
git add -p # stage interactively
|
||||
git commit -m "feat: describe the change"
|
||||
git push origin feature/my-thing
|
||||
```
|
||||
|
||||
## Minimal Config
|
||||
|
||||
```bash
|
||||
git config --global user.name "Your Name"
|
||||
git config --global user.email "you@example.com"
|
||||
git config --global init.defaultBranch main
|
||||
git config --global pull.rebase true
|
||||
```
|
||||
|
||||
## Helpful tools
|
||||
|
||||
- `lazygit`
|
||||
- VSCode Git Graph extension
|
||||
Reference in New Issue
Block a user