Apicurio CLI
A powerful Rust-based command-line tool for managing schema artifacts from Apicurio Registry. The apicurio CLI provides dependency management for Protobuf, Avro, JSON Schema, and other schema artifacts with lockfile-based reproducible builds.
Installation
From Source
From Cargo
Features
- 🔒 Lockfile-based dependency management - Reproducible builds with exact version locking
- 📦 Multiple artifact types - Support for Protobuf, Avro, JSON Schema, OpenAPI, GraphQL, and more
- 🔐 Flexible authentication - Basic, token, and bearer authentication support
- 🌐 Multi-registry support - Work with multiple Apicurio Registry instances
- 📋 Semver resolution - Smart semantic version resolution with range support
- 🚀 Publishing capabilities - Publish artifacts back to registries
- 🔍 Status monitoring - Check for outdated dependencies
- ✅ Integrity verification - SHA256 checksums for artifact validation
Installation
From Source
From Cargo
Quick Start
-
Initialize a new project:
-
Add a dependency:
-
Pull dependencies:
-
Check status:
Configuration
Repository Configuration (apicurioconfig.yaml)
The main configuration file that defines registries, dependencies, and publishing configuration:
# Optional: path to external registries file
externalRegistriesFile: ${APICURIO_REGISTRIES_PATH:-}
# Registry definitions
registries:
- name: production
url: https://registry.example.com
auth:
type: bearer
tokenEnv: APICURIO_TOKEN
- name: staging
url: https://staging-registry.example.com
auth:
type: basic
username: admin
passwordEnv: STAGING_PASSWORD
# Dependencies to fetch
dependencies:
- name: user-service-protos
groupId: com.example.services
artifactId: user-service
version: ^1.2.0
registry: production
outputPath: protos/user-service.proto
- name: payment-schemas
groupId: com.example.schemas
artifactId: payment-events
version: ~2.1.0
registry: production
outputPath: schemas/payment.avsc
### Smart Dependency Resolution
Dependencies support smart resolution of `groupId` and `artifactId` from the `name` field:
```yaml
dependencies:
# Smart resolution from group/artifact format
- name: com.example/user-service # → groupId: com.example, artifactId: user-service
version: ^1.0.0
registry: production
outputPath: protos/user-service.proto
# Smart resolution with simple name
- name: payment-events # → groupId: default, artifactId: payment-events
version: ~2.1.0
registry: production
outputPath: schemas/payment.avsc
# Complex artifact names work too
- name: nprod/sp.frame.Frame # → groupId: nprod, artifactId: sp.frame.Frame
version: 4.3.1
registry: nprod-apicurio
outputPath: protos/sp/frame/frame.proto
# Explicit override of smart resolution
- name: custom-name # Name is just an alias
groupId: com.special.group # Explicit groupId overrides smart resolution
artifactId: actual-artifact # Explicit artifactId overrides smart resolution
version: ^1.0.0
registry: production
outputPath: protos/special.proto
Smart Resolution Rules:
- If
namecontains/:groupId= part before/,artifactId= part after/ - If
nameis simple:groupId="default",artifactId= entire name - Explicit
groupId/artifactIdfields override smart resolution - This matches the behavior of publishing configuration
Artifacts to publish
publishes:
- name: com.example/my-service inputPath: protos/my-service.proto version: 1.0.0 registry: production type: protobuf description: "My service API definition" labels: team: backend service: my-service
### Global Registries (`~/.config/apicurio/registries.yaml`)
Global registry definitions shared across projects:
```yaml
registries:
- name: company-registry
url: https://registry.company.com
auth:
type: bearer
tokenEnv: COMPANY_REGISTRY_TOKEN
Lock File (apicuriolock.yaml)
Auto-generated file containing exact resolved versions and checksums:
lockedDependencies:
- name: user-service-protos
registry: production
resolvedVersion: 1.2.3
downloadUrl: https://registry.example.com/apis/registry/v3/groups/com.example.services/artifacts/user-service/versions/1.2.3/content
sha256: a1b2c3d4e5f6...
outputPath: protos/user-service.proto
groupId: com.example.services
artifactId: user-service
versionSpec: ^1.2.0
lockfileVersion: 1
configHash: abc123...
generatedAt: "1735387200000000000"
Commands
Core Commands
| Command | Description |
|---|---|
init |
Initialize a new project with config and lock files |
pull |
Fetch dependencies according to lock file (or resolve if no lock exists) |
update |
Re-resolve semver ranges and update lock file |
lock |
Update lock file based on current config without downloading |
Dependency Management
| Command | Description |
|---|---|
add <identifier> |
Add a new dependency (interactive if identifier incomplete) |
remove <identifier> |
Remove a dependency by identifier |
list |
List all configured dependencies and registries |
status |
Check for outdated dependencies |
Registry Management
| Command | Description |
|---|---|
registry add <name> <url> |
Add a registry to global config |
registry list |
List all configured registries |
registry remove <name> |
Remove a registry from global config |
Publishing & Verification
| Command | Description |
|---|---|
publish [name] |
Publish artifacts to registries |
verify |
Verify downloaded files against lock file checksums |
doctor |
Validate configuration and connectivity |
Utilities
| Command | Description |
|---|---|
completions <shell> |
Generate shell completion scripts |
Examples
Basic Workflow
# Initialize a new project
# Add a Protobuf dependency
# Pull dependencies
# Check for updates
# Update to latest matching versions
Working with Multiple Registries
# Add registries
# Add dependencies from different registries
Publishing Artifacts
# Configure a publish target in apicurioconfig.yaml
# Publish the artifact
Environment Variables
# Set authentication tokens
# Override registries file location
# Pull dependencies
Authentication
None (Anonymous)
auth:
type: none
Basic Authentication
auth:
type: basic
username: admin
passwordEnv: REGISTRY_PASSWORD
Token Authentication
auth:
type: token
tokenEnv: REGISTRY_TOKEN
Bearer Authentication
auth:
type: bearer
tokenEnv: REGISTRY_BEARER_TOKEN
Artifact Types
The CLI supports various artifact types with automatic content-type detection:
- Protobuf (
.proto) -application/x-protobuf - Avro (
.avsc) -application/json - JSON Schema (
.json) -application/json - OpenAPI (
.yaml,.json) -application/json - GraphQL (
.graphql,.gql) -application/graphql - XML/WSDL (
.xml) -application/xml
Semver Support
Version specifications support standard semantic versioning:
1.2.3- Exact version^1.2.0- Compatible releases (>=1.2.0, <2.0.0)~1.2.0- Reasonably close (>=1.2.0, <1.3.0)>=1.1.0, <1.4.0- Range specification
Development Setup
Prerequisites
- Rust 1.70+ with Cargo
- Access to an Apicurio Registry instance (for testing)
Building from Source
Running Tests
# Run unit tests
# Run with logging
RUST_LOG=debug
# Run specific test
# Using cargo-make for comprehensive testing
Development Environment
-
Start a local Apicurio Registry:
-
Build and test:
-
Run integration tests:
# Ensure local registry is running on localhost:8080
Code Structure
src/
├── main.rs # CLI entry point
├── commands/ # Command implementations
│ ├── mod.rs # Command routing
│ ├── init.rs # Project initialization
│ ├── pull.rs # Dependency fetching
│ ├── add.rs # Dependency addition
│ └── ...
├── config.rs # Configuration management
├── lockfile.rs # Lock file operations
├── registry.rs # Registry client
├── dependency.rs # Dependency resolution
└── identifier.rs # Identifier parsing
Configuration Reference
Repository Config Schema
# Optional external registries file
externalRegistriesFile: string
# Registry definitions
registries:
- name: string # Required: unique registry name
url: string # Required: registry base URL
auth: # Optional: authentication config
type: none|basic|token|bearer # Required if auth present
username: string # Required for basic auth
passwordEnv: string # Required for basic auth
tokenEnv: string # Required for token/bearer auth
# Dependencies to fetch
dependencies:
- name: string # Required: local alias (can use group/artifact format)
groupId: string # Optional: artifact group (resolved from name if not provided)
artifactId: string # Optional: artifact ID (resolved from name if not provided)
version: string # Required: semver specification
registry: string # Required: registry name reference
outputPath: string # Required: local file path
# Smart Resolution Examples:
# name: "com.example/user-service" → groupId: "com.example", artifactId: "user-service"
# name: "user-service" → groupId: "default", artifactId: "user-service"
# name: "nprod/sp.frame.Frame" → groupId: "nprod", artifactId: "sp.frame.Frame"
# Reference resolution configuration
referenceResolution:
enabled: true # Enable automatic reference resolution
outputPattern: string # Pattern for transitive dependency paths
maxDepth: 5 # Maximum reference resolution depth
outputOverrides: # Explicit path mappings
"groupId/artifactId": "path/pattern"
"registry:groupId/artifactId": "path/pattern"
# Dependencies with per-dependency reference control
dependencies:
- name: string # Required: dependency identifier
groupId: string # Optional: defaults from name
artifactId: string # Optional: defaults from name
version: string # Required: semver specification
registry: string # Required: registry name
outputPath: string # Required: local file path
resolveReferences: boolean # Optional: override global reference resolution
# Publishing configuration
publishes:
- name: string # Required: publish identifier
inputPath: string # Required: source file path
version: string # Required: exact version
registry: string # Required: target registry
type: protobuf|avro|... # Optional: auto-detected from extension
groupId: string # Optional: defaults from name
artifactId: string # Optional: defaults from name
ifExists: FAIL|CREATE_VERSION|FIND_OR_CREATE_VERSION
description: string # Optional: artifact description
labels: # Optional: key-value labels
key: value
references: # Optional: artifact references
- name: string # Reference identifier
version: string # Exact version (no ranges)
nameAlias: string # Optional: import alias
Troubleshooting
Common Issues
1. Authentication failures:
# Check environment variables
# Verify registry connectivity
2. Lock file conflicts:
# Regenerate lock file
3. Version resolution failures:
# Check available versions
# Update to latest compatible versions
4. Network connectivity:
# Test registry connectivity
Debug Mode
# Enable debug logging
RUST_LOG=debug
# Trace network requests
RUST_LOG=reqwest=trace
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make changes and add tests
- Run tests:
cargo test - Format code:
cargo fmt - Run linter:
cargo clippy - Submit a pull request
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.