Environment Variable Dependencies
Environment variable dependencies verify that required environment variables exist before your command runs. Root-, command-, and implementation-level checks run against the user's captured host environment. Checks declared inside the selected container runtime configuration run inside the container.
Basic Usage
depends_on: {
env_vars: [
{alternatives: [{name: "API_KEY"}]},
{alternatives: [{name: "DATABASE_URL"}, {name: "DB_URL"}]}
]
}
If the variable isn't set:
✗ Dependencies not satisfied
Command 'deploy' has unmet dependencies:
Missing Environment Variables:
• AWS_ACCESS_KEY_ID - not set in environment
Set the required environment variables and try again.
Alternatives (OR Semantics)
Require one of multiple variables:
depends_on: {
env_vars: [
// Either AWS_ACCESS_KEY_ID OR AWS_PROFILE
{alternatives: [
{name: "AWS_ACCESS_KEY_ID"},
{name: "AWS_PROFILE"}
]}
]
}
The dependency is satisfied if any alternative exists.
Regex Validation
Validate the variable's value matches a pattern:
depends_on: {
env_vars: [
// Must be set AND match semver format
{alternatives: [{
name: "VERSION"
validation: "^[0-9]+\\.[0-9]+\\.[0-9]+$"
}]}
]
}
If the value doesn't match:
✗ Dependencies not satisfied
Command 'release' has unmet dependencies:
Invalid Environment Variables:
• VERSION - value "invalid" does not match pattern "^[0-9]+\.[0-9]+\.[0-9]+$"
Validation Order
Within each dependency-validation phase, environment variables are checked first:
- env_vars ← Checked first!
- tools
- filepaths
- capabilities
- custom_checks
- cmds
For host-level dependencies, this validates the user's actual environment before variables from Invowk™'s env construct are applied. The container-runtime phase uses the selected container's environment instead.
Real-World Examples
AWS Credentials
{
name: "deploy"
description: "Deploy to AWS"
depends_on: {
env_vars: [
// Need either access key or profile
{alternatives: [
{name: "AWS_ACCESS_KEY_ID"},
{name: "AWS_PROFILE"}
]},
// Region is required
{alternatives: [{name: "AWS_REGION"}]}
]
tools: [{alternatives: ["aws"]}]
}
implementations: [{
script: {content: "aws s3 sync ./dist s3://my-bucket"}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
Database Connection
{
name: "db migrate"
description: "Run database migrations"
depends_on: {
env_vars: [
{alternatives: [{
name: "DATABASE_URL"
// Validate it looks like a connection string
validation: "^postgres(ql)?://.*$"
}]}
]
tools: [{alternatives: ["migrate", "goose"]}]
}
implementations: [{
script: {content: "migrate -path ./migrations -database $DATABASE_URL up"}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
API Keys
{
name: "publish"
description: "Publish package to registry"
depends_on: {
env_vars: [
// NPM token for publishing
{alternatives: [{name: "NPM_TOKEN"}]},
]
tools: [{alternatives: ["npm"]}]
}
implementations: [{
script: {content: """
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
npm publish
"""}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
Environment-Specific Config
{
name: "deploy"
description: "Deploy to target environment"
depends_on: {
env_vars: [
// DEPLOY_ENV must be one of: dev, staging, prod
{alternatives: [{
name: "DEPLOY_ENV"
validation: "^(dev|staging|prod)$"
}]}
]
}
implementations: [{
script: {content: """
echo "Deploying to $DEPLOY_ENV..."
./scripts/deploy-$DEPLOY_ENV.sh
"""}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
Version Validation
{
name: "release"
description: "Create a release"
depends_on: {
env_vars: [
// Version must be semantic
{alternatives: [{
name: "VERSION"
validation: "^v?[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9]+)?$"
}]},
// Git tag message
{alternatives: [{name: "RELEASE_NOTES"}]}
]
}
implementations: [{
script: {content: """
git tag -a "$VERSION" -m "$RELEASE_NOTES"
git push origin "$VERSION"
"""}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
Common Validation Patterns
Semantic Version
validation: "^[0-9]+\\.[0-9]+\\.[0-9]+$"
// Matches: 1.0.0, 2.1.3
// Rejects: v1.0.0, 1.0, latest
URL
validation: "^https?://[^\\s]+$"
// Matches: http://localhost, https://example.com/path
// Rejects: ftp://server, not-a-url
Email-like
validation: "^[^@]+@[^@]+\\.[^@]+$"
// Matches: user@example.com
// Rejects: invalid, @example.com
Alphanumeric ID
validation: "^[a-zA-Z0-9_-]+$"
// Matches: my-project_123, ABC
// Rejects: my project, name@here
AWS Region
validation: "^[a-z]{2}-[a-z]+-[0-9]+$"
// Matches: us-east-1, eu-west-2
// Rejects: US-EAST-1, us_east_1
Multiple Requirements
Combine multiple env var checks (AND logic):
depends_on: {
env_vars: [
// Need API_KEY AND API_SECRET AND API_URL
{alternatives: [{name: "API_KEY"}]},
{alternatives: [{name: "API_SECRET"}]},
{alternatives: [{
name: "API_URL"
validation: "^https://.*$"
}]},
]
}
Check Context
Root-, command-, and implementation-level environment dependencies check the user's host environment, not variables set by Invowk:
{
name: "example"
env: {
vars: {
// This is set by Invowk during execution
MY_VAR: "value"
}
}
depends_on: {
env_vars: [
// This checks the USER's environment, BEFORE Invowk sets MY_VAR
// So it will fail if the user hasn't set MY_VAR themselves
{alternatives: [{name: "MY_VAR"}]}
]
}
}
This is intentional: those checks validate what the user configured, not what the command will set. An env_vars dependency inside the selected container runtime configuration is different—it is checked inside the container against the runtime environment.
Best Practices
- Use alternatives for auth methods:
{alternatives: [{name: "TOKEN"}, {name: "API_KEY"}]} - Add validation when format matters: Especially for URLs, versions, and IDs
- Document required vars: Users need to know what to set
- Consider secrets management: Don't log sensitive values
Next Steps
- Custom Checks - Write custom validation scripts
- Overview - Return to dependencies overview