MetalDeploy includes powerful environment file generation capabilities that automatically create .env files from GitHub secrets and variables. This enables secure management of environment configurations without storing them in your repository.
- ✅ Multiple Format Support - ENV format (KEY=VALUE), JSON, YAML, and auto-detection
- ✅ Flexible File Structures - Single
.envfile, flat.env.*files, or nested.envs/{environment}/organization - ✅ Priority System - Environment-specific secrets override base secrets automatically
- ✅ All-in-One Secret Support - Store multiple variables in single secrets
- ✅ Strict Filtering - Only processes keys starting with
ENV_or the literalENVto ensure security - ✅ Secure Handling - Files created with
0o600permissions, no secret logging - ✅ Secrets & Variables - Supports both GitHub Secrets (encrypted) and GitHub Variables (plaintext)
- Discovery: The action scans environment variables starting with
ENV_or a literalENV. - Bucketing:
- Literal
ENV: Treated as a non-prefixed global blob. Its contents go directly into the.envfile without prefixes. ENV_COMPONENT_...: Treated as part of a specific component (e.g.,ENV_APP_...goes to.env.app).ENV_ENVIRONMENT_...: Identifies prefixes matching common environments (PROD,STAGING,DEV,TEST) plus your currentenvironmentinput.
- Literal
- Strict Filtering: MetalDeploy only processes secrets that start with
ENV_or the literalENV. Other secrets (likeSTRIPE_KEYorGITHUB_TOKEN) are ignored for security unless specifically prefixed.
The priority system ensures that specific overrides always take precedence:
- Base Variables (Lowest) Individual secrets or raw blocks are loaded first.
- Explicit Workflow
env:Variables (Medium) Variables you map directly in your workflow'senv:block win over the blob. - Environment Overrides (Highest)
Secrets matching your
environmentinput (e.g.ENV_PROD_...) win last.
Here is exactly how the env: block looks alongside the with: block in a GitHub Action:
- name: Deploy to Staging
uses: ./
env:
# MANUAL OVERRIDES GO HERE
ENV_APP_PORT: 9090 # This wins over any other PORT setting
with:
env_files_generate: 'true'
environment: 'staging'
remote_host: ${{ secrets.REMOTE_HOST }}
# ... other inputs ...For the simplest setup, pass all secrets in one go:
- uses: ./ with: env_files_generate: 'true'
Security Check: Only secrets you have named with the ENV_ prefix in your repository settings will be processed. All other private secrets remain untouched.