Sync .env files with GitHub Actions, GitLab CI/CD, HashiCorp Vault and Jenkins credentials. Review a plan before anything changes. Secret values are never printed.
curl -sSfL https://raw.githubusercontent.com/bakhod1r/env4ci/main/install.sh | shNo Go needed. Also: brew install bakhod1r/tap/env4ci · scoop install env4ci · uses: bakhod1r/env4ci@v1 · go install
Built for people who've pasted a secret into the wrong field before.
diff shows every change as new, changed, unverifiable or remote only. push asks before it writes.
Plans and logs show keys and kinds only. GitHub secrets are encrypted on your machine with a libsodium sealed box.
Glob rules decide secret or variable. Keys that match no rule become secrets, so a value is never exposed by accident.
Keys that exist only on the remote are left alone unless you pass --prune.
Tokens come from GITHUB_TOKEN and GITLAB_TOKEN. The config file rejects unknown fields.
SSH keys log in to their server and registry tokens log in to ghcr.io or Docker Hub before anything is stored. If a check fails, nothing is written.
Reads the repo from git remote and maps the current branch to its environment. A branch with no mapping is refused.
pull writes mode 0600, never overwrites a file, and adds it to .gitignore.
Put shared values at repository level and per-environment values in each environment. The environment value wins when both have the same key.
env4ci push github \ -f .env.shared GitHub repo secrets/vars GitLab scope "*"
env4ci push github \ -f .env.dev -e dev GitHub environment "dev" GitLab scope "dev"
env4ci push github \ -f .env.prod -e production GitHub environment "production" GitLab scope "production"
Run env4ci init to create it. Rules are checked top to bottom and the first match wins.
# env4ci.yaml
source: .env.production
default: secret
rules:
- { pattern: "*SECRET*", type: secret }
- { pattern: "*TOKEN*", type: secret }
- { pattern: "APP_*", type: variable }
- { pattern: "LOG_*", type: variable }
targets:
github: { repo: owner/name, environment: production }
gitlab: { project: group/project, protected: true }
Provider commands take github, gitlab, vault or jenkins; default comes from env4ci.yaml or git remote.
| init | Create env4ci.yaml (wizard on a terminal) |
| gen | Auth file + one gitignored env file per environment |
| scan | List variables the CI files use |
| verify | Log in with SSH keys and registry tokens |
| diff <p> | Plan only. Never writes anything. |
| push <p> | Verify, confirm, apply the plan |
| pull <p> | Write readable remote values to a .env file |
| check <p> | Exit 2 if CI uses keys the provider lacks |
| rotate KEY | New value or --generate, verify, back up, push one key |
| leaks | Exit 2 if tracked files contain secret values |
| hook | Pre-commit hook running leaks --staged |
| makefile | Add make env-* targets |
| update | Replace the binary with the latest release |
| completion | Tab completion for bash, zsh, fish |
| help [cmd] | One command's usage and flags; also man env4ci |