Plugin Packaging utility
Relevant source files
The following files were used as context for generating this wiki page:
The Plugin Packaging utility is a specialized suite of scripts designed to normalize built Nushell plugin binaries into signed, hash-pinned artifacts. Its primary purpose is to close the gap for plugins that only ship as source code by providing prebuilt, cross-compiled binaries for various architectures including Linux, macOS, and Windows.
This utility ensures byte-stability across rebuilds by using fixed timestamps and file modes. This stability allows for reliable sha256 hash pinning, which is a requirement for the official numan-registry. The utility handles the full lifecycle from binary normalization to generating the machine-readable specifications required for registry intake.
Sources: README.md:9-20, scripts/package_plugin.py:1-15
Packaging Architecture and Normalization
The core logic of the packaging utility focuses on deterministic output. By fixing metadata such as modification times (mtime) and file permissions (mode), the utility ensures that rebuilding the same source on the same target results in an identical binary archive.
Deterministic Archive Creation
The utility supports two archive formats based on the target operating system:
- .tar.gz: Used for Unix-based targets (Linux and macOS).
- .zip: Used for Windows targets.
To achieve stability, the utility uses a fixed epoch (1980-01-01 UTC) for all file entries and sets a standard Unix execution mode of 0o755.
The diagram shows the decision flow and normalization steps required to produce byte-stable archives.
Sources: scripts/package_plugin.py:27-65, scripts/test_package_plugin.py:32-52
Configuration Constants
| Variable | Value | Description |
|---|---|---|
FIXED_MTIME | 315532800 | Unix timestamp for 1980-01-01 00:00:00 UTC. |
UNIX_MODE | 0o755 | Standard executable permissions for Unix targets. |
ZIP_CREATE_SYSTEM | 3 | Identifies the system as Unix for stable ZIP central directory headers. |
Sources: scripts/package_plugin.py:27-30
Build Manifest and Validation
The manifest.json file serves as the source of truth for the build matrix. It defines which plugins are active, their upstream source commits, and their target compatibility.
Manifest Structure
The manifest includes a list of default_targets and an active array of plugin objects. Each plugin entry must contain immutable pins to upstream repositories and specific Nu version compatibility.
{
"repo": "cptpiepmatz/nu-plugin-highlight",
"name": "nu_plugin_highlight",
"tag": "v1.4.15+0.113.1",
"source_commit": "c5454221668342bf1770f3793a13d3bd8bcbfea0",
"version": "1.4.15",
"nu_version": ">=0.113.0 <0.114.0"
}
Sources: manifest.json:8-30
Validation Logic
The validate_manifest.py script ensures the integrity of the build pipeline by:
- Schema Verification: Checking for required fields such as
repo,source_commit, andplugin_bin. - Commit Pinning: Validating that
source_commitis a 40-character lowercase hex string. - Upstream Matching: Resolving the human-facing
tagviagit ls-remoteto ensure it matches the immutablesource_commit.
Sources: scripts/validate_manifest.py:15-30, scripts/validate_manifest.py:127-140
Specification Generation
Once archives are packaged, the gen_spec.py utility aggregates the results into a kind: binary specification file. This file is the primary interface for the numan-registry.
Spec Data Flow
The generator consumes a TSV-formatted list of packaged assets (emitted by package_plugin.py) and merges them with metadata from the manifest.
The diagram illustrates how packaging results are combined with static metadata to produce the final registry specification.
Sources: scripts/gen_spec.py:1-25, scripts/gen_spec.py:53-78
Registry Specification Fields
The generated spec includes essential provenance and artifact details:
- Source Block: Contains the
gitURL, immutablerev(commit), andcargo_name. - Artifact Block: Maps Rust target triples to download URLs and their internal
executable_path. - Metadata: Includes
nu_versioncompatibility and tags for registry searching.
Sources: scripts/gen_spec.py:126-150
Conclusion
The Plugin Packaging utility provides a deterministic, automated bridge between upstream Rust source code and the numan ecosystem's requirement for signed binary artifacts. By enforcing immutable commit pins and byte-stable archive generation, the utility maintains a strict trust boundary while simplifying plugin installation for end-users.