Getting Started Guide
Relevant source files
The following files were used as context for generating this wiki page:
This guide provides a technical overview and instructions for using the numan-plugins repository to build, package, and release binary artifacts for numan plugins. The project serves as a CI build and sign pipeline feeder, addressing the gap for Nushell plugins that only ship source code by providing signed, hash-pinned binary artifacts.
Sources: README.md:1-15
Architecture Overview
The system operates on a trust boundary where this repository builds and hosts binaries but never holds signing keys. Signing is deferred to the numan-registry. The workflow involves cross-compiling plugins from immutable upstream commits, packaging them into target-specific archives (.tar.gz for Unix, .zip for Windows), and publishing them as GitHub release assets.
High-Level Build Flow
The following diagram illustrates the lifecycle of a plugin from manifest addition to registry intake.
The flow ensures that every binary is traceable to an immutable upstream source and verified before being made public.
Sources: README.md:21-50, REVIEW.md:32-50
Configuration and Manifests
The manifest.json file is the central configuration for the build pipeline. It defines which plugins are "active," their upstream sources, and their target compatibility.
Manifest Structure
Each entry in the active[] list requires specific fields to ensure provenance and build accuracy.
| Field | Type | Description |
|---|---|---|
repo | String | Upstream GitHub repository (owner/name). |
name | String | Unique plugin identifier in the registry. |
tag | String | Human-facing upstream tag. |
source_commit | String | Immutable 40-character SHA-1 commit hash. |
plugin_bin | String | The name of the resulting binary. |
nu_version | String | SemVer range for Nushell compatibility. |
exclude_targets | Array | Optional list of Rust targets to skip. |
Sources: manifest.json:10-30, scripts/validate_manifest.py:17-30
Build Matrix
The pipeline supports a specific set of runners and targets defined in the manifest:
- Linux:
x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu(cross-compiled) - macOS:
x86_64-apple-darwin,aarch64-apple-darwin - Windows:
x86_64-pc-windows-msvc
Sources: manifest.json:152-158, README.md:52-56
Core Build Scripts
The build process is managed by a suite of Python scripts that handle validation, packaging, and release management.
1. Validation (validate_manifest.py)
Ensures the manifest is schema-compliant and that human-facing tags resolve to the pinned source_commit.
- Key Function:
verify_upstream(entries)resolves the remote tag viagit ls-remoteand compares it to the manifest commit.
Sources: scripts/validate_manifest.py:114-124
2. Packaging (package_plugin.py)
Normalizes built binaries into archives. It uses a fixed MTIME (1980-01-01) to ensure deterministic builds where the same source produces the same sha256 hash.
- Archive Types:
.tar.gzfor Unix (usingtarfileandgzip),.zipfor Windows (usingzipfile).
Sources: scripts/package_plugin.py:27-30, scripts/package_plugin.py:40-66
3. Release Transactions (release_transaction.py)
Handles the atomic publication of assets to GitHub. It utilizes a "claim-then-finalize" pattern to prevent half-published releases.
The script includes a cleanup command to delete owned drafts and tags if the transaction fails before finalization.
Sources: scripts/release_transaction.py:58-96, scripts/release_transaction.py:157-190
Release Safety Invariants
To maintain the integrity of the plugin registry, several invariants are enforced during the build and review process:
- Immutability: Release tags and assets are immutable. The
ensure_release_absent.pyscript fails the build if a tag or release already exists for the version. - Manual Trigger: The
build-pluginsworkflow must be manually dispatched with anonly=package list; automated pushes or PRs only perform validation. - Provenance: Generated
spec-*.jsonfiles must preservesource.revas the immutable upstream commit. - No Private Keys: Signing keys and PEM files are strictly prohibited in this repository.
Sources: REVIEW.md:32-48, scripts/ensure_release_absent.py:20-56, README.md:65-72
Summary
Starting a new plugin build requires adding a valid entry to manifest.json, ensuring the source_commit matches the desired tag, and triggering the manual CI workflow. The system's reliance on deterministic packaging and strict release transactions ensures that the numan-registry receives consistent and secure binary artifacts for end-users.
Sources: README.md:58-80, REVIEW.md:52-60