Manifest Validator API
Relevant source files
The following files were used as context for generating this wiki page:
The Manifest Validator API is a critical component of the numan-plugins CI/CD pipeline, responsible for ensuring the integrity, consistency, and provenance of plugin build definitions. It validates the central manifest.json file, which serves as the source of truth for all plugins built and hosted by the repository. The API enforces strict schema requirements, ensures that build targets are correctly mapped, and optionally verifies that human-facing Git tags resolve to immutable source commit SHAs.
This validator acts as a CI gate that must pass before any publishing builds are executed. By verifying the active[] entries in the manifest, the API ensures that only valid, well-described, and version-compatible plugins are processed by the build matrix.
Sources: REVIEW.md:7-10, scripts/validate_manifest.py:1-4, manifest.json:1-5
Core Validation Logic
The primary function of the validator is to parse the manifest.json file and verify that every plugin entry contains the necessary metadata for a successful build and registry intake.
Data Structure Requirements
Each entry in the active list of the manifest must satisfy a specific schema of required fields. This ensures that downstream scripts, such as gen_spec.py, have all the information needed to generate a numan-registry package spec.
| Field | Type | Description |
|---|---|---|
repo | String | The GitHub repository in owner/name format. |
name | String | The unique name of the plugin. |
owner | String | The owner of the plugin. |
plugin_bin | String | The name of the resulting plugin binary. |
tag | String | Human-facing Git tag for provenance. |
source_commit | String | 40-character lowercase hex SHA-1 commit hash. |
version | String | The plugin version string. |
nu_version | String | Nushell compatibility range. |
verified_with | List[String] | Specific Nushell versions tested with the plugin. |
description | String | A brief description of the plugin's purpose. |
tags | List[String] | Keywords for registry searching. |
Sources: scripts/validate_manifest.py:12-25, manifest.json:13-28
Validation Workflow
The following diagram illustrates the logical flow of the validate_manifest.py execution during a CI run.
The diagram shows the sequence from loading the manifest to the optional upstream verification step.
Sources: scripts/validate_manifest.py:53-125
Target Matrix Resolution
The validator calculates the final build targets for each plugin by reconciling the default_targets defined at the manifest root with any exclude_targets specified within an individual plugin entry.
Logic for Target Calculation
- Defaults: The validator retrieves the list of
default_targets(e.g.,x86_64-unknown-linux-gnu,x86_64-apple-darwin). - Exclusions: It checks the plugin's
exclude_targetslist. - Consistency Check: It ensures that any excluded targets are actually present in the default list; otherwise, it raises a
ValueError. - Final Set: It returns the remaining targets. If a plugin excludes all default targets, validation fails.
Sources: scripts/validate_manifest.py:44-70, manifest.json:6-12
Upstream Provenance Verification
A key security feature of the Manifest Validator is the --verify-upstream flag. When enabled, the script performs a network lookup using git ls-remote to ensure that the human-readable tag in the manifest exactly matches the immutable source_commit.
Resolve Tag Implementation
The API uses the following logic to resolve tags:
def resolve_tag(repo: str, tag: str) -> str:
url = f"https://github.com/%7Brepo%7D.git%22
for ref in (f"refs/tags/{tag}^{{}}", f"refs/tags/{tag}"):
result = subprocess.run(
["git", "ls-remote", url, ref],
# ... capture output and check return code
)
if result.stdout.strip():
return result.stdout.split()[0]
raise ValueError(f"upstream tag not found: {repo}@{tag}")
This ensures that "tag sliding" or mutable tags cannot be used to introduce unverified code into the build pipeline.
Sources: scripts/validate_manifest.py:102-125
Error Handling and Constraints
The validator is designed to "fail closed," meaning any deviation from the expected format or state results in a non-zero exit code.
- Duplicate Names: The validator maintains a set of seen names and raises a
ValueErrorif a duplicate plugin name is encountered in theactive[]list. - SHA-1 Integrity: The
source_commitmust strictly match a 40-character lowercase hex regex:^[0-9a-f]{40}$. - Timeout Safety: External Git calls are protected by a
COMMAND_TIMEOUT_SECONDSof 30 seconds to prevent hanging CI runners. - Documentation Coverage: As a safety module, the validator script itself is monitored for 100% docstring coverage for its functions and classes.
Sources: scripts/validate_manifest.py:10, 80-92, scripts/test_docstring_coverage.py:11-23
Conclusion
The Manifest Validator API provides the essential verification layer for the numan-plugins repository. By enforcing a strict schema on manifest.json and validating upstream Git references, it ensures that every binary artifact produced is traceable to a specific, immutable source commit, maintaining the project's trust boundary.