Binstaller Configuration Schema
This directory contains the TypeSpec definition for binstaller's configuration format and tools to generate JSON Schema and Go types.
Binstaller uses YAML configuration files (typically .config/binstaller.yml) to define how to download, verify, and install binaries from GitHub releases.
Quick Start
Here's a minimal configuration:
schema: v1
repo: owner/project
asset:
template: "${NAME}_${VERSION}_${OS}_${ARCH}.tar.gz"
Complete Example
schema: v1
name: mytool
repo: myorg/mytool
default_version: latest
default_bin_dir: ${HOME}/.local/bin
# Define how to construct download URLs
asset:
template: "${NAME}_${VERSION}_${OS}_${ARCH}${EXT}"
default_extension: .tar.gz
# Multiple binaries in the archive
binaries:
- name: mytool
path: mytool
- name: mytool-helper
path: bin/mytool-helper
# Platform-specific rules (applied cumulatively)
rules:
# Windows uses .zip files
- when:
os: windows
ext: .zip
# macOS uses different naming
- when:
os: darwin
os: macOS # Changes ${OS} to "macOS"
# macOS also uses .zip
- when:
os: darwin
ext: .zip
# M1 Macs need signed binaries
- when:
os: darwin
arch: arm64
template: "${NAME}_${VERSION}_${OS}_${ARCH}_signed${EXT}"
# Security features
checksums:
algorithm: sha256
template: "${NAME}_${VERSION}_checksums.txt"
# Archive extraction
unpack:
strip_components: 1
# Platform restrictions
supported_platforms:
- os: linux
arch: amd64
- os: linux
arch: arm64
- os: darwin
arch: amd64
- os: darwin
arch: arm64
- os: windows
arch: amd64
Key Concepts
Template Placeholders
The asset template uses these placeholders:
${NAME} - Binary name (from name field or repository name)
${VERSION} - Version to install (without 'v' prefix)
${OS} - Operating system (e.g., 'linux', 'darwin', 'windows')
${ARCH} - Architecture (e.g., 'amd64', 'arm64', '386')
${EXT} - File extension (from default_extension or rules)
Rules System
Rules are evaluated sequentially and all matching rules are applied:
- Each rule's
when condition is checked
- If all conditions match, the rule's overrides are applied
- Later rules can override values from earlier rules
Example flow for darwin/arm64:
rules:
- when: { os: darwin }
os: macOS # ${OS} becomes "macOS"
- when: { os: darwin }
ext: .zip # ${EXT} becomes ".zip"
- when: { os: darwin, arch: arm64 }
template: "special_${OS}_${ARCH}${EXT}" # Uses "macOS" and ".zip" from above
Security Features
Checksums
- Download checksum files from releases
- Or embed pre-verified checksums using
binst embed-checksums
Common Patterns
asset:
template: "${NAME}_${VERSION}_${OS}_${ARCH}.tar.gz"
rules:
- when: { os: windows }
ext: .zip
Direct Binary Download (No Archive)
asset:
template: "${NAME}_${VERSION}_${OS}_${ARCH}${EXT}"
default_extension: ""
binaries:
- name: mytool
path: ${ASSET_FILENAME} # The downloaded file IS the binary
rules:
- when: { os: windows }
ext: .exe
Multiple Architectures with Emulation
asset:
template: "${NAME}_${VERSION}_${OS}_${ARCH}.tar.gz"
arch_emulation:
rosetta2: true # Use x86_64 on Apple Silicon when available
Custom OS/Arch Names
Some projects use non-standard naming:
asset:
template: "${NAME}-${OS}-${ARCH}"
rules:
- when: { os: darwin }
os: macos
- when: { arch: amd64 }
arch: x64
- when: { arch: 386 }
arch: x86
Schema Development
The schema is defined using TypeSpec:
# Install dependencies
cd schema
npm install
# Generate JSON Schema and Go types
make gen
# Or individually:
make gen-schema # Generate JSON Schema
make gen-go # Generate Go types
The generation pipeline:
- TypeSpec → JSON Schema (via TypeSpec compiler)
- JSON Schema → Go structs (via customized quicktype)
Files
main.tsp - TypeSpec definition of the configuration schema (source)
InstallSpec.json - Generated JSON Schema with all definitions inline
InstallSpec.yaml - YAML version of the JSON Schema for easier reading
../pkg/spec/generated.go - Generated Go structs
tspconfig.yaml - TypeSpec compiler configuration
package.json - NPM scripts for schema generation
gen-go-with-fork.sh - Script to use forked quicktype with unevaluatedProperties support
output/ - TypeSpec compiler output directory (gitignored)
Validation and Testing
Configuration Validation
Use binst check to validate your configuration and verify assets:
# Check the default config file
binst check
# Check with a specific version
binst check --version v1.2.3
# Check without verifying GitHub assets (faster)
binst check --check-assets=false
# Ignore specific file patterns
binst check --ignore "\.deb$" --ignore ".*-musl.*"
Testing Generated Installers
Test your installer script with dry-run mode:
# Generate and test installer without actually installing
binst gen | sh -s -- -n
# Test with a specific version
binst gen | sh -s -- -n v1.2.3
# Test installation to a custom directory
binst gen | sh -s -- -n -b /tmp/test-install
Schema Validation
For direct schema validation:
# Using any JSON Schema validator
npx ajv validate -s schema/InstallSpec.json -d .config/binstaller.yml
IDE Support
Many IDEs support JSON Schema validation for YAML files. The binst init command automatically adds this directive:
# yaml-language-server: $schema=https://raw.githubusercontent.com/binary-install/binstaller/main/schema/InstallSpec.json
schema: v1
repo: owner/repo
# ... rest of config
Tips and Best Practices
Workflow Tips
-
Start with init: Use binst init to generate a base configuration from existing sources:
# From GitHub releases
binst init --source=github --repo=junegunn/fzf
# From GoReleaser config
binst init --source=goreleaser --repo=owner/repo
# From Aqua registry
binst init --source=aqua --repo=junegunn/fzf
-
Validate early and often: Use binst check after each configuration change:
binst check # Validates config and checks assets exist
-
Test incrementally: Use dry-run mode to test without installing:
binst gen | sh -s -- -n # Test the installer script
Configuration Tips
- Start simple: Begin with minimal configuration and add complexity as needed
- Use rules sparingly: Only add rules for actual platform differences
- Document your choices: Add comments explaining non-obvious configurations
Security Tips
-
Always use checksums: Configure checksums for security:
checksums:
algorithm: sha256
template: "${NAME}_${VERSION}_checksums.txt"
-
Embed checksums for releases: For published releases, embed checksums:
# Download checksum file from GitHub
binst embed-checksums --version v1.0.0 --mode download
# Or calculate directly (requires GITHUB_TOKEN)
export GITHUB_TOKEN=$(gh auth token)
binst embed-checksums --version v1.0.0 --mode calculate
Advanced Usage
-
Generate version-specific installers: For CI/CD or specific deployments:
binst gen --target-version v1.2.3 -o install-v1.2.3.sh
-
Use runner mode: For temporary execution without installation:
binst gen --type=runner -o run.sh
./run.sh --help # All arguments pass directly to the binary
# Control runner behavior with environment variables:
BINSTALLER_TARGET_TAG=v1.2.3 ./run.sh --help # Use specific version
BINSTALLER_SHOW_HELP=1 ./run.sh # Show script help