From bf9cc8a6a24ab9be8f724be1e5013e49ecdc6954 Mon Sep 17 00:00:00 2001 From: Bryce Adelstein Lelbach aka wash Date: Wed, 11 Mar 2026 13:04:43 -0400 Subject: [PATCH 1/2] Docs: Expand CONTRIBUTING.md and update Brev Launchable architecture docs. --- CONTRIBUTING.md | 225 +++++++++++++++++++++++---- docs/brev_launchable_architecture.md | 100 ++++++++++-- 2 files changed, 281 insertions(+), 44 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7ab5716..83e1089b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,23 +2,136 @@ Please use the following guidelines when contributing to this project. -Before contributing signficicant changes, please begin a discussion of the -desired changes via a GitHub Issue to prevent doing unnecessary or overlapping -work. +Before contributing significant changes, please begin a discussion of the desired changes via a GitHub Issue to prevent doing unnecessary or overlapping work. ## Development Scripts -You can use the following scripts to help with development: +The `brev/` directory contains scripts for building, running, and testing tutorial Docker containers locally, as well as validation and CI helper scripts. -* **`brev/dev-build.bash []`** - Builds Docker containers for tutorials. If a tutorial name is provided (e.g., `accelerated-python`), builds only that tutorial; if no argument is provided, builds all tutorials. Automatically generates Dockerfiles from HPCCM recipes if present. +### Docker Workflow (`brev/dev-*`) -* **`brev/dev-start.bash `** - Starts Docker containers for a tutorial, mounting your local repository as `/accelerated-computing-hub` in the containers. +These are the primary scripts for local development. They all accept a tutorial name (the directory name under `tutorials/`, e.g. `accelerated-python`) and manage Docker Compose services for that tutorial. -* **`brev/dev-stop.bash `** - Stops Docker containers for a tutorial. +* **`brev/dev-build.bash []`** - Builds Docker images. If a tutorial name is provided, builds only that tutorial; if omitted, builds all tutorials discovered by `discover-tutorials.bash`. Automatically generates Dockerfiles from HPCCM recipes if present. -* **`brev/dev-shell.bash `** - Starts an interactive bash shell in a Docker container for a tutorial. Can accept either a tutorial name or a path to docker-compose.yml file, plus the service name (e.g., `base`, `jupyter`, `nsight`). +* **`brev/dev-start.bash [--mount|--no-mount] `** - Starts containers for a tutorial. By default (`--mount`), bind-mounts the local repository into the containers at `/accelerated-computing-hub` so edits are reflected immediately. Use `--no-mount` to run from the image content only. Rebinds ports to `0.0.0.0` for local access. -* **`brev/dev-test.bash `** - Tests a Docker Compose file with the local repository mounted. Calls `test-docker-compose.bash` to run the tutorial's tests. +* **`brev/dev-stop.bash `** - Stops and tears down containers for a tutorial. + +* **`brev/dev-shell.bash [--mount|--no-mount] `** - Opens an interactive bash shell inside a running container. Accepts either a tutorial name or a path to a `docker-compose.yml` file, plus the service name (e.g. `base`, `jupyter`, `nsys`, `ncu`). + +* **`brev/dev-test.bash [--mount|--no-mount] [test-args...]`** - Runs the tutorial's test suite inside Docker. Defaults to `--no-mount` (tests the image as-built). Extra arguments are forwarded to the tutorial's `test.bash` script (e.g. `brev/dev-test.bash accelerated-python test/test_notebooks.py -k "03"`). + +### Validation Scripts (`brev/test-*`) + +These scripts are used by the pre-commit hooks and CI. You can also run them directly. + +* **`brev/test-notebook-format.py [] [--fix]`** - Checks that notebooks are in canonical format (1-space indentation, sorted keys, standard metadata, clean outputs for non-SOLUTION notebooks). Pass `--fix` to auto-rewrite notebooks to canonical form. + +* **`brev/test-git-lfs.bash [...]`** - Verifies that binary files (images, PDFs, presentations) are properly tracked by Git LFS and that no `.gitattributes` files exist in subdirectories. + +* **`brev/test-git-signatures.bash []`** - Checks that all commits on the current branch (since `origin/main` by default) are cryptographically signed. + +* **`brev/test-links.bash `** - Converts notebooks to markdown, then runs [lychee](https://github.com/lycheeverse/lychee) to check for broken links. Operates on a temporary copy to avoid polluting the working tree. + +* **`brev/test-docker-compose.bash [--mount|--no-mount] [test-args...]`** - The lower-level test runner that `dev-test.bash` delegates to. Starts containers, checks for restart loops, runs the tutorial's tests, verifies restart behavior, and tears everything down. + +### Other Utility Scripts + +* **`brev/discover-tutorials.bash`** - Prints one line per tutorial directory (relative to repo root) for every tutorial that has a `brev/docker-compose.yml`. Used by `dev-build.bash` and CI. + +* **`brev/generate-tagged-docker-composes.py`** - Generates Docker Compose files with specific image tags for a given branch/commit. Used by CI to produce versioned artifacts that are pushed to the `generated` branch. + +## Pre-Commit Hooks + +This repository uses [pre-commit](https://pre-commit.com/) to run automated checks before commits and pushes. Install the hooks after cloning: + +```bash +pip install pre-commit +pre-commit install +pre-commit install --hook-type pre-push +``` + +The following hooks are configured: + +| Hook | Stage | Files | What it checks | +|---|---|---|---| +| **`notebook-format`** | pre-commit | `*.ipynb` | Validates that notebooks are in canonical format (consistent cell metadata, output ordering, etc.) to prevent noisy diffs from editor reformatting. | +| **`git-lfs`** | pre-commit | Binary files (`*.pptx`, `*.pdf`, `*.png`, `*.jpg`, etc.) | Ensures binary files are tracked by Git LFS rather than committed directly to the repository. | +| **`git-signatures`** | pre-push | All commits | Verifies that all commits being pushed have valid cryptographic signatures (see [Signing Your Commits](#signing-your-commits)). | +| **`test-links`** | manual | `*.md`, `*.ipynb` | Checks for broken links in markdown and notebook files. Run manually with `pre-commit run test-links --all-files`. | + +If a hook fails, fix the issue and re-stage your changes before committing again. + +## Branches + +### `main` + +The primary integration branch. All changes land here via pull requests. + +### `feature/` and `fix/` + +Development branches for new features and bug fixes, respectively. Create these from `main` and open a pull request when ready. + +- `feature/` — new functionality or enhancements (e.g. `feature/matplotlib-dark-mode-detect`). +- `fix/` — bug fixes or corrections (e.g. `fix/dockerfile-copy-chmod-layers`). + +### `pull-request/` + +These branches are created to enable CI on pull requests from forks. Because this project uses NVIDIA's self-hosted GitHub Actions runners, workflows cannot run directly on fork PRs for security reasons. NVIDIA's [**copy-pr-bot**](https://docs.gha-runners.nvidia.com/cpr/vetters/) automates this process -- when a maintainer determines a fork PR is safe to test, they push a copy of the PR to a `pull-request/` branch on the upstream repo (where `` is the PR number). The CI workflow is configured to trigger on branches matching the `pull-request/[0-9]+` pattern, so pushing to this branch runs the full build and test pipeline. The results are reported back on the original PR because the commit SHAs match. See the [Reviewing PRs From Forks](#reviewing-prs-from-forks) section below for the step-by-step process. + +### `generated` + +A CI-managed branch that stores generated artifacts (e.g. tagged Docker Compose files). The build workflow automatically commits updated Docker Compose files to this branch under `/tutorials//` after each successful build. You should never need to commit to this branch manually. + +### Event branches (`YYYY-MM-`) + +Long-lived branches for conference workshops and training events (e.g. `2025-09-ndc-techtown`, `2026-01-internal-cuda-tile-hackathon`). These capture the exact state of tutorials as delivered at a specific event. + +## Commit Messages + +Commit messages use a **`Category[/Subcategory]: Summary.`** format. The summary is a sentence in imperative mood that starts with a capital letter and ends with a period. + +### Format + +``` +Category[/Subcategory[/...]]: Imperative summary of the change. +``` + +Examples: + +``` +Docker: Fix entrypoint failure when target UID already exists. +Tutorials/Accelerated Python/Kernel Authoring: Add correctness check cell before profiling copy_blocked kernel. +CI: Add nightly schedule trigger to build workflow. +``` + +### Categories + +Use the most specific category path that accurately describes what was changed. The top-level category identifies the broad area of the codebase, and subcategories narrow it down. + +| Category | When to use | +|---|---| +| **`Tutorials/`** | Changes to tutorial content (notebooks, scripts, solutions). Use subcategories to identify the specific module when applicable, e.g. `Tutorials/Accelerated Python/Memory Spaces`, `Tutorials/CUDA Tile/Vector Add`. | +| **`Docker`** | Changes to Dockerfiles, Docker Compose files, entrypoint scripts, or container configuration that affect multiple tutorials or the shared Docker infrastructure. | +| **`Brev`** | Changes specific to the Brev deployment configuration or Brev-specific entrypoint behavior. Use subcategories for specific services, e.g. `Brev/Nsight`, `Brev/Entrypoint`. | +| **`CI`** | Changes to GitHub Actions workflows, CI scripts, or CI configuration. | +| **`Scripts`** | Changes to development and utility scripts (e.g. `brev/dev-build.bash`). | +| **`Tests`** | Changes to test infrastructure, test scripts, or test validation. | +| **`Nsight`** | Changes to Nsight Systems/Compute integration, Nsight Streamer, or profiling configuration. | +| **`Docs`** | Changes to documentation files (READMEs, contributing guides, link fixes). | +| **`Slides`** | Changes to presentation materials. | + +### Summary Guidelines + +- Use **imperative mood**: "Fix bug" not "Fixed bug" or "Fixes bug". +- Start with a **capital letter** and end with a **period**. +- Describe the **what and why**, not the how: "Fix entrypoint failure when target UID already exists." rather than "Add an if-check around useradd." +- If the commit fixes a GitHub issue, append `Fixes #.` to the end of the summary. + +## Pull Requests From Forks + +When opening a pull request from a fork, please check the **"Allow edits from maintainers"** checkbox. This lets maintainers push small fixes (typos, formatting, CI tweaks) directly to your PR branch without requiring a round-trip, which significantly speeds up the review process. You can find this checkbox at the bottom of the "Open a pull request" form on GitHub. See the [GitHub documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) for more details. ## Pre-Commit Hooks @@ -76,36 +189,82 @@ pre-commit run test-links --hook-stage manual --all-files ## License -The preferred license for contributions to this project is the detailed in the -[LICENSE file](LICENSE). +The preferred license for contributions to this project is detailed in the [LICENSE file](LICENSE). + +## Signing Your Commits + +This project requires that all commits and contributions must be **verified** on GitHub. This is necessary to protect against security threats and protect both our codebase and our CI system. + +This means each commit needs two things: + +1. A **`Signed-off-by` trailer** asserting the [Developer Certificate of Origin (DCO)](https://developercertificate.org/). +2. A **cryptographic signature** (GPG or SSH) so GitHub displays the "Verified" badge. + +### Signed-off-by (DCO) + +The `Signed-off-by` trailer certifies that you wrote the contribution or otherwise have the right to submit it under the project's license. Add it by passing `--signoff` (or `-s`) when committing: + +```bash +git commit -s -m "CI: Add nightly schedule trigger to build workflow." +``` + +This appends a line like the following to the commit message: + +``` +Signed-off-by: Your Name +``` + +Your name and email must match your Git identity (`user.name` and `user.email`). -Contributions must include a "signed off by" tag in the commit message for the -contributions asserting the signing of the developers certificate of origin -(https://developercertificate.org/). A GPG-signed commit with the "signed off -by" tag is preferred. +### CryptographicG Commit Signing + +We require that all commits to be cryptographically signed so they display as **"Verified"** on GitHub. The `git-signatures` pre-commit hook and CI both enforce this. You can sign with either a GPG key or an SSH key. + +#### Option A: GPG Signing + +1. [Generate a GPG key](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) and [add it to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account). +2. Tell Git to use your key: + +```bash +gpg --list-secret-keys --keyid-format=long +git config --global user.signingkey +``` + +3. Enable automatic signing so you don't have to pass `-S` every time: + +```bash +git config --global commit.gpgsign true +``` + +#### Option B: SSH Signing + +1. [Add your SSH key to your GitHub account as a **signing** key](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key#telling-git-about-your-ssh-key). +2. Configure Git to use SSH for signing: + +```bash +git config --global gpg.format ssh +git config --global user.signingkey ~/.ssh/id_ed25519.pub +git config --global commit.gpgsign true +``` + +### Recommended Git Configuration + +To sign and sign-off on every commit by default, add both settings: + +```bash +git config --global commit.gpgsign true +git config --global format.signoff true +``` + +With these defaults, a simple `git commit -m "message"` will produce a signed, signed-off commit. ## Styling Please use the guidelines detailed in the [notebook template](docs/notebook_template.ipynb) for contributions. -## Contributing Labs/Modules - -A module should have the following directory structure: - -* The base of the module should contain a README.ipynb file with a brief - introduction to the module and links to the individual labs for each - language translation and programming language available. -* The base of the module should contain a subdirectory for each programming language if applicable. Each - of these directories should contain a directory for each language - translation provided (English, for instance). -* The base of the module should contain an `images` directory that contains - images that will be used in common between multiple notebooks. -* For each programming language and translation there should be a file named - `README.ipynb` containing the actual lab instructions. A single file name - is used in this way to simplify finding the starting point for each new - lab. -* Each lab translation and programming language combination should have a - `solutions` directory containing correct solutions. +## Tutorial Architecture + +For details on the tutorial directory structure, Docker Compose services, notebook conventions (exercise vs. solution notebooks), tests, and deployment infrastructure, see the [Brev Launchable Architecture](docs/brev_launchable_architecture.md) documentation. ## Reviewing PRs From Forks diff --git a/docs/brev_launchable_architecture.md b/docs/brev_launchable_architecture.md index bd8218b4..81825ade 100644 --- a/docs/brev_launchable_architecture.md +++ b/docs/brev_launchable_architecture.md @@ -2,17 +2,91 @@ Brev uses [Docker Compose](https://docs.docker.com/compose/) files to define the services and volumes that define a Launchable. -## Tutorials and Syllabi +## Tutorial Directory Structure -A tutorial is a Docker image plus a collection of notebooks, slides and other content that teach a broad subject. A tutorial is defined by a directory: `tutorials/`. +A tutorial is a Docker image plus a collection of notebooks, slides, and other content that teach a broad subject. Each tutorial is defined by a directory under `tutorials/` with the following layout: -Tutorials may contain syllabi. Syllabi are subset of a tutorial's notebooks for a particular learning objective. Each syllabi uses the underlying tutorial's Docker image. A syllabi is defined by a Jupyter notebook file: `tutorials//notebooks/syllabi/.ipynb`. +``` +tutorials// +├── brev/ +│ ├── docker-compose.yml # Docker Compose service definitions +│ ├── dockerfile # (or docker-recipe.py) Docker image definition +│ ├── requirements.txt # Python dependencies (if applicable) +│ └── test.bash # Entrypoint for tutorial-level tests +├── notebooks/ +│ ├── / # Grouped by topic (e.g. fundamentals, kernels, libraries) +│ │ ├── NN__topic.ipynb # Exercise notebooks (outputs stripped) +│ │ └── solutions/ +│ │ └── NN__topic__SOLUTION.ipynb # Solution notebooks (outputs preserved) +│ └── syllabi/ # Subset notebooks for specific learning objectives +├── test/ # Pytest test modules for this tutorial +└── slides/ # Presentation materials (optional) +``` + +## Notebooks + +### Naming Convention + +Notebook filenames follow the pattern `NN__descriptive_name.ipynb`, where `NN` is a two-digit number and double underscores (`__`) separate the number from the name and between name segments. The number defines the ordering within and across modules; gaps in numbering are expected and make it easy to insert new notebooks later. For example, in the `accelerated-python` tutorial: + +``` +fundamentals/ + 00__what_are_gpus.ipynb + 01__numpy_intro__ndarray_basics.ipynb + 02__numpy_linear_algebra__svd_reconstruction.ipynb + 03__numpy_to_cupy__ndarray_basics.ipynb + ... + 07__cuda_core__devices_streams_and_memory.ipynb +libraries/ + 20__cudf__nyc_parking_violations.ipynb + 21__cudf_pandas__nyc_parking_violations.ipynb + ... + 28__pynvml.ipynb +kernels/ + 40__kernel_authoring__copy.ipynb + 41__kernel_authoring__book_histogram.ipynb + ... +distributed/ + 60__mpi4py.ipynb + 61__dask.ipynb +``` + +Each module starts at a different tens digit (`00`-`09` for fundamentals, `20`-`29` for libraries, `40`-`49` for kernels, `60`-`69` for distributed), so notebooks have a globally unique ordering across the entire tutorial. + +**The notebook number must not appear inside the notebook itself** (not in the title, headings, or body text). For example, notebook `03__numpy_to_cupy__ndarray_basics.ipynb` has the title "NumPy to CuPy - `ndarray` Basics", not "03 - NumPy to CuPy - `ndarray` Basics". This makes renumbering notebooks painless -- only filenames need to change, not content. + +### Exercise Notebooks + +Exercise notebooks are the files students interact with. They contain instructional content, code examples, and exercises with `TODO` markers for the student to fill in. Exercise notebooks have their **outputs stripped** (no cell outputs, no execution counts) so that diffs remain clean and students see a fresh notebook. The pre-commit `notebook-format` hook enforces this. + +### Solution Notebooks + +Solution notebooks live in a `solutions/` subdirectory within each module and have `__SOLUTION` appended to the name (e.g. `03__numpy_to_cupy__ndarray_basics__SOLUTION.ipynb`). They contain completed exercises with **outputs preserved** so students (and CI) can see the expected results. CI tests execute every solution notebook end-to-end to verify they run without errors. + +### Syllabi + +Tutorials may contain syllabi. A syllabus is a subset of a tutorial's notebooks for a particular learning objective. Each syllabus uses the underlying tutorial's Docker image. A syllabus is defined by a Jupyter notebook file: `tutorials//notebooks/syllabi/.ipynb`. + +## Tests + +Each tutorial has a `test/` directory containing [pytest](https://docs.pytest.org/) test modules and a `brev/test.bash` script that serves as the test entrypoint inside Docker. At minimum, tutorials should have a `test_notebooks.py` that discovers and executes all solution notebooks end-to-end. Tutorials may add additional test modules for package validation or other checks as needed. + +The `brev/test.bash` script is the single entrypoint that CI calls. It should support running all test suites when invoked with no arguments and forwarding arguments to pytest for targeted runs: + +```bash +./test.bash # Run all suites +./test.bash 03 # Run notebook tests matching "03" +./test.bash test/test_notebooks.py # Run a specific test module +./test.bash -k "cupy" # Forward raw pytest flags +``` + +Tests are invoked by CI via `brev/test-docker-compose.bash` (see [CONTRIBUTING.md](../CONTRIBUTING.md) for development script documentation). ## Docker Compose Files Each tutorial defines its own Docker Compose file in `tutorials//brev/docker-compose.yml`. -For each syllabi, a Docker Compose file is automatically generated on the [`generated` branch](https://github.com/NVIDIA/accelerated-computing-hub/tree/generated) in `/tutorials//notebooks/syllabi/__docker_compose.yml`. +For each syllabus, a Docker Compose file is automatically generated on the [`generated` branch](https://github.com/NVIDIA/accelerated-computing-hub/tree/generated) in `/tutorials//notebooks/syllabi/__docker_compose.yml`. ## Docker Compose Services @@ -20,12 +94,14 @@ For each syllabi, a Docker Compose file is automatically generated on the [`gene |-----------|--------------|-------------| | `base` | Tutorial | Performs one-time initialization tasks when a Launchable is deployed, such as updating the Git repository to the latest commit and populating the Docker volume. | | `jupyter` | Tutorial | Runs the JupyterLab server and executes notebook content. | -| `nsight` | [NVIDIA NSight Streamer](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/devtools/containers/nsight-streamer-nsys) | Runs the WebRTC server that provides devtools. | +| `nsys` | [NVIDIA Nsight Streamer (nsys)](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/devtools/containers/nsight-streamer-nsys) | Runs the WebRTC server for Nsight Systems. | +| `ncu` | [NVIDIA Nsight Streamer (ncu)](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/devtools/containers/nsight-streamer-ncu) | Runs the WebRTC server for Nsight Compute. | ## Docker Images - Tutorial: A tutorial-specific image built and published by the ACH CI. The image is defined by `tutorials//brev/dockerfile` or `tutorials//brev/docker-recipe.py`. -- [NVIDIA NSight Streamer](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/devtools/containers/nsight-streamer-nsys): A pre-built image that serves NSight GUIs over WebRTC. +- [NVIDIA Nsight Streamer (nsys)](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/devtools/containers/nsight-streamer-nsys): A pre-built image that serves the Nsight Systems GUI over WebRTC. +- [NVIDIA Nsight Streamer (ncu)](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/devtools/containers/nsight-streamer-ncu): A pre-built image that serves the Nsight Compute GUI over WebRTC. ## Docker Volumes @@ -33,8 +109,10 @@ For each syllabi, a Docker Compose file is automatically generated on the [`gene ## Docker Ports -| Service | Port | Protocol | Description | -|-----------|------|----------|------------------------------------| -| `jupyter` | 8888 | HTTP | JupyterLab. | -| `nsight` | 8080 | HTTP | WebRTC UI for NSight Streamer. | -| `nsight` | 3478 | TURN | WebRTC stream for NSight Streamer. | +| Service | Port | Protocol | Description | +|-----------|------|----------|----------------------------------------| +| `jupyter` | 8888 | HTTP | JupyterLab. | +| `nsys` | 8080 | HTTP | WebRTC UI for Nsight Systems Streamer. | +| `nsys` | 3478 | TURN | WebRTC stream for Nsight Systems. | +| `ncu` | 8081 | HTTP | WebRTC UI for Nsight Compute Streamer. | +| `ncu` | 3479 | TURN | WebRTC stream for Nsight Compute. | From b55764b71ab6e82101da4f7576c8b4578d0230e0 Mon Sep 17 00:00:00 2001 From: Bryce Adelstein Lelbach aka wash Date: Wed, 11 Mar 2026 14:20:23 -0400 Subject: [PATCH 2/2] Docs: Add developer setup section and requirements-dev.txt. --- CONTRIBUTING.md | 43 +++++++++++++++++++++++++++++++++++++++ brev/requirements-dev.txt | 7 +++++++ 2 files changed, 50 insertions(+) create mode 100644 brev/requirements-dev.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83e1089b..cf2c286b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,49 @@ Please use the following guidelines when contributing to this project. Before contributing significant changes, please begin a discussion of the desired changes via a GitHub Issue to prevent doing unnecessary or overlapping work. +## Developer Setup + +After cloning the repository, set up your local development environment: + +```bash +# Create and activate a virtual environment +uv venv .venv +source .venv/bin/activate + +# Install developer dependencies +uv pip install -r brev/requirements-dev.txt + +# Install pre-commit hooks +pre-commit install +pre-commit install --hook-type pre-push +``` + +The developer dependencies in `brev/requirements-dev.txt` include: + +| Package | Used by | +|---|---| +| `pre-commit` | Git pre-commit and pre-push hooks. | +| `nbformat` | `brev/test-notebook-format.py` for canonical notebook validation. | +| `nbconvert` | `brev/test-links.bash` for converting notebooks to markdown before link checking. | +| `hpccm` | `brev/dev-build.bash` for generating Dockerfiles from HPCCM recipes (only needed for tutorials that use HPCCM). | + +You will also need the following non-Python tools. On Ubuntu/Debian: + +```bash +# Docker Engine (https://docs.docker.com/engine/install/ubuntu/) +sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +# Git LFS (https://git-lfs.com/) +sudo apt-get install git-lfs +git lfs install + +# Rust toolchain, needed to install lychee (https://rustup.rs/) +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + +# lychee link checker (https://lychee.cli.rs/installation) +cargo install lychee +``` + ## Development Scripts The `brev/` directory contains scripts for building, running, and testing tutorial Docker containers locally, as well as validation and CI helper scripts. diff --git a/brev/requirements-dev.txt b/brev/requirements-dev.txt new file mode 100644 index 00000000..50646080 --- /dev/null +++ b/brev/requirements-dev.txt @@ -0,0 +1,7 @@ +# Developer dependencies for working on Accelerated Computing Hub. +# Install with: uv pip install -r brev/requirements-dev.txt + +pre-commit +nbformat +nbconvert +hpccm