| name | finpilot-examples |
| description | Index of runnable example scripts and the activation pattern. Covers existing .example files and how to activate them. Use when adding new build scripts or explaining the activation pattern to contributors. |
finpilot Example Scripts
When to Use
- You need to add a third-party repository or desktop swap
- You want to understand the
.example → .sh activation pattern
- You are creating a new build script and want a starting point
- You need to document a new pattern for contributors
When NOT to Use
- You are modifying existing active
.sh scripts directly — edit them, don't activate an example
- You are adding a simple package — use
build/10-build.sh directly, no example needed
Core Process
- Find the relevant example in
build/ directory
- Copy and rename from
.example to .sh
- Add its explicit
RUN block after 10-build.sh in Containerfile
- Customize for your specific use case
- Validate with
shellcheck and just build
- Commit (via PR to
main)
The Activation Pattern
All example scripts in build/ follow the pattern:
- Inactive: Named
NN-descriptive-name.sh.example
- Activate the file: Rename to
NN-descriptive-name.sh
- Activate execution: Add an explicit
RUN block after 10-build.sh in Containerfile
The template does not automatically discover numbered scripts. See build/README.md for the standard mounted RUN block; replace its script path with the activated example.
Existing Example Scripts
build/40-nvidia.sh.example
What it does:
- Pulls pre-built NVIDIA akmods from
ghcr.io/ublue-os/akmods-nvidia-open
- Installs NVIDIA driver (open kernel modules, CUDA, libnvidia-container)
- Configures CDI (Container Device Interface) GPU passthrough for Podman
- Writes bootc kernel args: nouveau blacklist +
nvidia-drm.modeset=1
- Enables Mutter
kms-modifiers for Wayland support on NVIDIA
How to activate:
mv build/40-nvidia.sh.example build/40-nvidia.sh
just build
All NVIDIA logic is self-contained in the script. It provisions NVIDIA support directly into the base image when both the script is renamed to .sh and its Containerfile RUN block is added. Deactivate by removing that RUN block and renaming the file back to .example.
Expected validation:
pr-validation.yml → shellcheck
build-image.yml → full build test
- Must test on actual NVIDIA hardware — Wayland/modeset issues are not caught in CI
build/20-onepassword.sh.example
What it does:
- Adds the 1Password repository
- Installs
1password
- Removes the repo file after install (isolated install pattern)
How to activate:
cp build/20-onepassword.sh.example build/20-onepassword.sh
Expected validation:
pr-validation.yml → shellcheck
build-image.yml → full build test
build/30-cosmic-desktop.sh.example
What it does:
- Removes the GNOME desktop environment
- Installs the COSMIC desktop environment from COPR
- Sets the default graphical target
How to activate:
cp build/30-cosmic-desktop.sh.example build/30-cosmic-desktop.sh
Expected validation:
pr-validation.yml → shellcheck
build-image.yml → full build test (significant change, test thoroughly)
Creating New Example Scripts
When adding a new pattern that others might reuse, create an .example file:
- Name it with the correct prefix:
20- for third-party repos, 30- for desktop swaps
- Include comments explaining what it does and how to customize
- Follow conventions:
set -euo pipefail, dnf5, copr_install_isolated for COPRs
- Add the new example to this skill so agents discover it
Template for New Examples
#!/usr/bin/env bash
set -euo pipefail
Validation by Example Type
| Example | Shellcheck | Build Test | Additional Validation |
|---|
Third-party repo (20-*.sh) | Yes | Yes | Verify repo URL accessible |
Desktop swap (30-*.sh) | Yes | Yes | Test in VM (just run-vm-qcow2) |
COPR install (20-*.sh) | Yes | Yes | Verify COPR exists and packages install |
NVIDIA GPU (40-nvidia.sh) | Yes | Yes | Test on NVIDIA hardware; verify nvidia-smi after boot |
Link to Package Decision Tree
For deciding whether to use an example script or add directly to build/10-build.sh, use finpilot-packages.
Quick guide:
- Simple system packages →
build/10-build.sh
- Third-party repo or complex install →
build/20-*.sh (activate an example or create new)
- Desktop environment swap →
build/30-*.sh (activate an example or create new)
Common Rationalizations
| Rationalization | Reality |
|---|
| "I'll just add my script directly — no need for an example." | If the pattern is reusable, an example helps future contributors. If it's one-off, add to 10-build.sh. |
"I'll leave it as .example and never rename it." | .example files are inactive. Rename one to .sh and add its explicit Containerfile RUN block. |
| "I renamed the example, so it will run." | The template runs only scripts explicitly named in Containerfile. Add the matching RUN block. |
Red Flags
.example file modified but not renamed to .sh
- Renamed
.sh file without a matching Containerfile RUN block
- New
.sh file without set -euo pipefail
- Script using
dnf or yum instead of dnf5
- COPR repo not disabled after install
- Third-party repo file not removed after install
- Missing shellcheck validation before committing
Verification