Phase 0 · One-time setup

Get your machine and your repository ready.

By the end you’ll have a working development environment, the opentrash repository created and cloned, an empty documentation site skeleton ready to grow, and the package name claimed. Works on macOS, Windows, and Linux. Plan about 90 minutes the first time.

Naming note: this guide uses opentrash as the package and repository name throughout. Name yours anything — wherever you see opentrash, substitute your own name. Just be consistent.

1 Development environment

Five tools: Python (via miniforge), VS Code, git, the GitHub CLI, and UV. If you already have any, skip that step.

1 Install miniforge (Python 3.11)

Miniforge is a minimal Python distribution using conda-forge by default — lighter and cleaner than full Anaconda.

macOS (Apple Silicon)
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh"
bash Miniforge3-MacOSX-arm64.sh

When prompted: accept the license (yes), accept the default location, answer yes to initialize. Then close and reopen Terminal.

macOS (Intel)
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-x86_64.sh"
bash Miniforge3-MacOSX-x86_64.sh
Windows

Download Miniforge3-Windows-x86_64.exe from the miniforge releases page and run it. Choose Just Me, and on Advanced Options check “Add Miniforge3 to my PATH.” Afterwards use the Miniforge Prompt from the Start menu.

Linux
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh"
bash Miniforge3-Linux-x86_64.sh
Verify (all platforms)
conda --version

Shows conda 24.x.x or similar. “Command not found” means the terminal didn’t reload — close it completely and reopen.

2 Install VS Code

Download from code.visualstudio.com and install. Open the Extensions panel and install:

  • Python (Microsoft)
  • Jupyter (Microsoft)
  • GitLens (GitKraken) — optional but helpful

macOS: make the code command available — press Cmd+Shift+P, run “Shell Command: Install 'code' command in PATH.” Windows/Linux installers handle this.

code --version

3 Install git (and Homebrew on macOS)

macOS — Homebrew first, then git

Homebrew is the standard macOS package manager and makes the rest easy.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Follow the on-screen instructions to add Homebrew to your PATH (the installer prints the exact lines). Then:

brew install git
Windows

Download from git-scm.com. Choose VS Code as default editor if offered, and “Git from the command line and also from 3rd-party software” for PATH.

Linux
sudo apt install git
Configure your identity (all platforms)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git --version

4 Install the GitHub CLI and sign in

The GitHub CLI (gh) is the fastest way to authenticate — no manual SSH keys. It handles credentials through a quick browser login.

macOS
brew install gh
Windows
winget install --id GitHub.cli

Or download from cli.github.com.

Linux

Follow the steps at cli/cli install guide.

Sign in (all platforms)
gh auth login

Choose GitHub.comHTTPSYes (authenticate Git) → Login with a web browser. Copy the one-time code, press Enter, approve in your browser. Far simpler than SSH keys.

Prefer SSH? Generate a key with ssh-keygen -t ed25519 -C "you@example.com", add the public key at github.com/settings/keys, verify with ssh -T git@github.com. The gh HTTPS path is recommended for most people.
gh auth status

5 Install UV

UV is a fast Python package manager for project dependencies.

macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Restart your terminal, then verify:

uv --version

2 Create the repository

The opentrash package lives in its own repository, separate from any website repo. This keeps it clean, independently versioned, and ready for PyPI — the standard layout for a real Python package.

6 Create and clone the repo

Create it on GitHub with the CLI (replace opentrash with your chosen name; set the owner to your user or org):

macOS / Linux
mkdir -p ~/Projects && cd ~/Projects
gh repo create opentrash --public --description "Cloud-native geospatial tools for residential waste operations" --clone
Windows
mkdir %USERPROFILE%\Projects
cd %USERPROFILE%\Projects
gh repo create opentrash --public --description "Cloud-native geospatial tools for residential waste operations" --clone

Use --private instead of --public while you work. For an org repo: gh repo create YOUR-ORG/opentrash .... --clone downloads it locally.

Then enter the repo and open it in VS Code:

cd opentrash
code .

3 The package skeleton + docs site

Create a minimal but complete skeleton: the Python package folder, a documentation site (MkDocs Material), packaging config, and a workflow that auto-builds the docs to GitHub Pages. Every later lesson grows this.

7 Build the skeleton structure

This is the target layout. Starter files are provided with the course materials — drop them into your cloned repo so it looks like this:

opentrash/ ├── opentrash/ # the Python package (code goes here) │ └── __init__.py # marks it a package; holds __version__ ├── docs/ # documentation site content │ └── index.md # docs homepage (placeholder for now) ├── .github/ │ └── workflows/ │ └── docs.yml # auto-build + deploy docs to GitHub Pages ├── mkdocs.yml # docs site config (Material theme) ├── pyproject.toml # packaging config; claims the name "opentrash" ├── README.md # repo front page ├── LICENSE # add your chosen license text └── .gitignore # Python ignores + project-specific

In plain terms: your code lives in opentrash/. Your docs pages live in docs/. Config sits at the root. The .github/workflows/docs.yml file publishes the docs site automatically on every push.

8 Create the environment and install tools

Create a dedicated conda environment, then install MkDocs Material and build tooling:

conda create -n opentrash python=3.11 -y
conda activate opentrash
pip install mkdocs-material build twine

mkdocs-material is the docs theme, build creates the package distribution, twine uploads to PyPI (Part 4).

9 Preview the docs site locally

From the repo root:

mkdocs serve

Open http://127.0.0.1:8000. You’ll see the skeleton docs homepage. Edits to anything in docs/ reload live. Ctrl+C stops it.

10 Enable GitHub Pages for the docs

The included docs.yml workflow builds the site and pushes it to a gh-pages branch on every commit to main. After your first push (Step 12), enable Pages:

  1. Repo → SettingsPages.
  2. Under Build and deployment, set Source to “Deploy from a branch.”
  3. Branch gh-pages, folder / (root). Save.
Default URL (no custom domain)

Docs go live at https://<owner>.github.io/opentrash/. Nothing else to do.

Optional: custom domain

If you own a domain (e.g. opentrash.app), point it at this repo’s Pages site. Each repo supports one custom domain, so a dedicated package repo can use its own independently of any other site you host.

  1. Settings → Pages → Custom domain: enter the domain, Save (writes a CNAME file).
  2. At your DNS provider, add the records GitHub specifies — a CNAME pointing to <owner>.github.io (and/or A records for an apex domain).
  3. After DNS propagates, enable “Enforce HTTPS.”

You can switch between default URL and custom domain any time — it’s a setting, not a one-way door. Start with the default if unsure.

4 Claim the package name on PyPI

PyPI names are first-come, first-served, claimed by uploading a release. Publishing a tiny 0.0.0 placeholder now reserves your name while it’s available. (You’ll learn the full publishing workflow in Lesson 12 — this just holds the name.)

11 Build and upload a placeholder release

Create a free account at pypi.org and check your name is free at https://pypi.org/project/opentrash/.

With pyproject.toml set to name = "opentrash" and version = "0.0.0", from the repo root:

python -m build
twine upload dist/*

twine prompts for PyPI credentials (use an API token from your account settings). Once uploaded, the name is yours. Verify at https://pypi.org/project/opentrash/.

Naming reminder: if you chose a different name, make sure pyproject.toml, the repo, and the package folder all match it.

5 Commit and verify

12 First commit and push

git add .
git commit -m "Phase 0: package skeleton, docs scaffold, packaging config"
git push origin main

If your default branch is master, use that instead of main.

Final checklist

  • conda, code, git, gh, uv all report a version
  • gh auth status shows you signed in
  • Repo created and cloned locally
  • Skeleton structure in place (package folder, docs, mkdocs.yml, pyproject.toml, workflow)
  • mkdocs serve renders the docs homepage locally
  • First push succeeded; GitHub Pages enabled (default URL or custom domain)
  • Package name claimed on PyPI
When every box is checked, Phase 0 is complete. You have a working machine, a live (or ready-to-go-live) docs site, and your package name secured. Lesson 1 picks up here — turning this skeleton into a real package.

Troubleshooting

  • conda: command not found — the terminal didn’t reload. Close it completely and open a fresh one.
  • gh: command not found — reopen the terminal; on macOS confirm brew finished and is on your PATH.
  • Auth fails in browser — rerun gh auth login and copy the full one-time code.
  • Pages shows 404 — check Settings → Pages: source is the gh-pages branch, root folder. First build takes a couple minutes.
  • twine rejects upload — the name may be taken, or that version already exists. Bump the version or pick another name.
  • Anything else — capture the exact error text and ask. A clear question is half the fix.