Skip to main content
Version: 0.2.0

Environment Variables

Set environment variables directly in your invowkfile. These are available to your scripts during execution.

Basic Usage

{
name: "build"
env: {
vars: {
NODE_ENV: "production"
API_URL: "https://api.example.com"
DEBUG: "false"
}
}
implementations: [{
script: """
echo "Building for $NODE_ENV"
echo "Date: $BUILD_DATE"
"""
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}

Variable Syntax

Variables are key-value string pairs:

vars: {
// Simple values
NAME: "value"

// Numbers (still strings in shell)
PORT: "3000"
TIMEOUT: "30"

// Boolean-like (strings "true"/"false")
DEBUG: "true"
VERBOSE: "false"

// Paths
CONFIG_PATH: "/etc/myapp/config.yaml"
OUTPUT_DIR: "./dist"

// URLs
API_URL: "https://api.example.com"
}

All values are strings. The shell interprets them as needed.

Referencing Other Variables

Reference system environment variables:

vars: {
// Use system variable
HOME_CONFIG: "${HOME}/.config/myapp"

// With default value
LOG_LEVEL: "${LOG_LEVEL:-info}"

// Combine variables
FULL_PATH: "${HOME}/projects/${PROJECT_NAME}"
}

Note: References are expanded at runtime, not definition time.

Scope Levels

Root Level

Available to all commands:

env: {
vars: {
PROJECT_NAME: "myproject"
VERSION: "1.0.0"
}
}

cmds: [
{
name: "build"
// Gets PROJECT_NAME and VERSION
implementations: [...]
},
{
name: "deploy"
// Also gets PROJECT_NAME and VERSION
implementations: [...]
}
]

Command Level

Available to specific command:

{
name: "build"
env: {
vars: {
BUILD_MODE: "release"
}
}
implementations: [...]
}

Implementation Level

Available to specific implementation:

{
name: "build"
implementations: [
{
script: "npm run build"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
env: {
vars: {
NODE_ENV: "production"
}
}
},
{
script: "go build ./..."
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
env: {
vars: {
CGO_ENABLED: "0"
}
}
}
]
}

Platform Level

Per-platform variables:

// Platform-specific env requires separate implementations
implementations: [
{
script: "echo $PLATFORM_CONFIG"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}]
env: {
vars: {
PLATFORM_CONFIG: "/etc/myapp"
PLATFORM_NAME: "Linux"
}
}
},
{
script: "echo $PLATFORM_CONFIG"
runtimes: [{name: "native"}]
platforms: [{name: "macos"}]
env: {
vars: {
PLATFORM_CONFIG: "/usr/local/etc/myapp"
PLATFORM_NAME: "macOS"
}
}
},
{
script: "echo %PLATFORM_CONFIG%"
runtimes: [{name: "native"}]
platforms: [{name: "windows"}]
env: {
vars: {
PLATFORM_CONFIG: "%APPDATA%myapp"
PLATFORM_NAME: "Windows"
}
}
}
]

Combined with Files

Variables override values from env files:

env: {
files: [".env"] // Loaded first
vars: {
// These override .env values
OVERRIDE: "from-invowkfile"
}
}

CLI Override

Override at runtime:

# Single variable
invowk cmd build --ivk-env-var NODE_ENV=development

# Multiple variables
invowk cmd build --ivk-env-var NODE_ENV=dev --ivk-env-var DEBUG=true --ivk-env-var PORT=8080

CLI variables have the highest priority.

Real-World Examples

Build Configuration

{
name: "build"
env: {
vars: {
NODE_ENV: "production"
BUILD_TARGET: "es2020"
SOURCEMAP: "false"
}
}
implementations: [{
script: "npm run build"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

API Configuration

{
name: "start"
env: {
vars: {
API_HOST: "0.0.0.0"
API_PORT: "3000"
API_PREFIX: "/api/v1"
CORS_ORIGIN: "*"
}
}
implementations: [{
script: "go run ./cmd/server"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Dynamic Values

{
name: "release"
env: {
vars: {
// Git-based version
GIT_SHA: "$(git rev-parse --short HEAD)"
GIT_BRANCH: "$(git branch --show-current)"

// Timestamp
BUILD_TIME: "$(date -u +%Y-%m-%dT%H:%M:%SZ)"

// Combine values
BUILD_ID: "${GIT_BRANCH}-${GIT_SHA}"
}
}
implementations: [{
script: """
echo "Building $BUILD_ID at $BUILD_TIME"
go build -ldflags="-X main.version=$BUILD_ID" ./...
"""
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}

Database Configuration

{
name: "db migrate"
env: {
vars: {
DB_HOST: "${DB_HOST:-localhost}"
DB_PORT: "${DB_PORT:-5432}"
DB_NAME: "${DB_NAME:-myapp}"
DB_USER: "${DB_USER:-postgres}"
// Construct URL from parts
DATABASE_URL: "postgres://${DB_USER}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
}
}
implementations: [{
script: "migrate -database $DATABASE_URL up"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}

Container Environment

Variables are passed into containers:

{
name: "build"
env: {
vars: {
GOOS: "linux"
GOARCH: "amd64"
CGO_ENABLED: "0"
}
}
implementations: [{
script: "go build -o /workspace/bin/app ./..."
runtimes: [{name: "container", image: "golang:1.26"}]
platforms: [{name: "linux"}]
}]
}

Best Practices

  1. Use defaults: ${VAR:-default} for optional config
  2. Keep secrets out: Don't hardcode secrets; use env files or external secrets
  3. Document variables: Add comments explaining each variable
  4. Use consistent naming: UPPER_SNAKE_CASE convention
  5. Scope appropriately: Root for shared, command for specific

Next Steps