SkillAgentSearch skills...

Glenv

Sync .env files to GitLab CI/CD variables — bulk import, export, and manage environment variables via CLI

Install / Use

/learn @ohmylock/Glenv
About this skill

Quality Score

0/100

Category

Operations

Supported Platforms

Universal

README

<p align="right"> <a href="README.ru.md">🇷🇺 Читать на русском</a> </p> <p align="center"> <img src="https://img.shields.io/badge/go-1.25+-00ADD8?style=flat&logo=go" alt="Go version 1.25 or higher"> <a href="https://github.com/ohmylock/glenv/actions/workflows/ci.yml"><img src="https://github.com/ohmylock/glenv/actions/workflows/ci.yml/badge.svg" alt="CI Build Status"></a> <a href="https://github.com/ohmylock/glenv/releases"><img src="https://img.shields.io/github/v/release/ohmylock/glenv?include_prereleases" alt="Latest Release Version"></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a> <a href="https://goreportcard.com/report/github.com/ohmylock/glenv"><img src="https://goreportcard.com/badge/github.com/ohmylock/glenv" alt="Go Report Card Score"></a> </p> <h1 align="center">glenv</h1> <p align="center"> <b>Sync .env files to GitLab CI/CD variables — bulk import, export, and manage environment variables via API</b><br> <i>Fast, concurrent CLI tool for GitLab secrets management and dotenv synchronization</i> </p> <p align="center"> <a href="#quick-start">Quick Start</a> • <a href="#features">Features</a> • <a href="#installation">Installation</a> • <a href="#usage">Usage</a> • <a href="#configuration">Configuration</a> • <a href="#faq">FAQ</a> </p>

What is glenv?

glenv is a command-line tool that synchronizes .env files with GitLab CI/CD variables. It solves the problem of managing GitLab environment variables at scale — bulk import, export, diff, and sync hundreds of variables in seconds using the GitLab API.

Instead of clicking through the GitLab web UI or writing fragile bash scripts, glenv provides:

  • Bulk operations — import/export entire .env files with one command
  • Smart classification — auto-detects masked, protected, and file-type variables
  • Safe workflow — preview changes with diff before applying
  • Concurrent sync — parallel API calls with built-in rate limiting
  • Multi-environment — manage production, staging, and custom environments from config

Why glenv over alternatives?

| Problem | glenv Solution | |---------|----------------| | GitLab UI is slow for many variables | Bulk sync hundreds of variables in seconds | | Bash scripts are fragile and sequential | Concurrent workers with retry and rate limiting | | No preview before changes | Diff command shows create/update/delete before sync | | Manual variable classification | Auto-detects masked/protected/file from key patterns | | Different configs per environment | Single YAML config for all environments |

glenv is written in Go — single static binary, no runtime dependencies, works on Linux, macOS, and Windows.

Features

  • Concurrent sync — configurable worker pool with token bucket rate limiter
  • Smart classification — auto-detects masked, protected, and file-type variables from key patterns
  • Rate limit safe — respects GitLab API limits, handles 429 with Retry-After, exponential backoff
  • Diff before sync — preview changes before applying (create/update/delete)
  • Dry-run mode — see what would happen without making any API calls
  • Multi-environment — sync production, staging, or any custom environment from config
  • Export — download current GitLab variables to .env file format
  • .env parser — supports multiline values, quoted strings, comments, placeholder detection
  • Zero config — works with just a token and project ID, config file is optional
  • Self-hosted support — works with any GitLab instance, configurable rate limits

Quick Start

# Install
go install github.com/ohmylock/glenv/cmd/glenv@latest

# Set credentials (or use config file)
export GITLAB_TOKEN="glpat-xxxxxxxxxxxx"
export GITLAB_PROJECT_ID="12345678"

# Sync .env file to GitLab
glenv sync -f .env.production -e production

# Preview changes first (recommended)
glenv diff -f .env.production -e production

Installation

Homebrew (macOS/Linux)

brew install ohmylock/tools/glenv

Download binary

Download the appropriate binary for your platform from releases:

| Platform | Architecture | File | |----------|--------------|------| | macOS | Apple Silicon | glenv_*_darwin_arm64.tar.gz | | macOS | Intel | glenv_*_darwin_amd64.tar.gz | | Linux | x86_64 | glenv_*_linux_amd64.tar.gz | | Linux | ARM64 | glenv_*_linux_arm64.tar.gz | | Windows | x86_64 | glenv_*_windows_amd64.zip |

Go install

go install github.com/ohmylock/glenv/cmd/glenv@latest

Build from source

git clone https://github.com/ohmylock/glenv.git
cd glenv
make build
# binary: bin/glenv

Usage

Sync Variables

The primary command. Reads a .env file and syncs variables to GitLab:

# Sync single file to specific environment
glenv sync -f .env.production -e production

# Sync with dry-run (preview only)
glenv sync -f .env.staging -e staging --dry-run

# Sync all environments defined in config
glenv sync --all

# Override rate limits for self-hosted GitLab
glenv sync -f .env -e production --workers 10 --rate-limit 50

Diff (Preview Changes)

Compare local .env file with current GitLab variables:

glenv diff -f .env.production -e production

Output:

+ DB_HOST=postgres.internal
~ API_KEY: *** → ***
- OLD_VAR
= LOG_LEVEL

List Variables

# List all variables
glenv list

# Filter by environment
glenv list -e production

Export Variables

Download GitLab variables to a local .env file:

glenv export -e production -o .env.production.backup

Note: File-type variables (certificates, PEM keys) are excluded from the output and replaced with a comment # KEY (file type, skipped). Use glenv list to see their presence.

Delete Variables

# Delete specific variable
glenv delete -e production OLD_SECRET

# Delete multiple variables
glenv delete -e staging KEY1 KEY2 KEY3 --force

Configuration

glenv works with zero config (just env vars), but a config file unlocks multi-environment workflows.

Config file locations (checked in order):

  1. --config flag path
  2. .glenv.yml in current directory
  3. ~/.glenv.yml
# GitLab connection
gitlab:
  url: https://gitlab.com                     # self-hosted: https://gitlab.company.com
  token: ${GITLAB_TOKEN}                      # env var expansion supported
  project_id: "12345678"

# Rate limiting (safe defaults for gitlab.com)
rate_limit:
  requests_per_second: 10                     # max API requests/sec (gitlab.com allows ~33)
  max_concurrent: 5                           # parallel workers
  retry_max: 3                                # retries on failure
  retry_initial_backoff: 1s                   # backoff before first retry

# Environments
environments:
  production:
    file: deploy/gitlab-envs/.env.production
  staging:
    file: deploy/gitlab-envs/.env.staging

# Custom classification rules (extend built-in defaults)
classify:
  masked_patterns:                            # keys containing these → masked
    - "_TOKEN"
    - "SECRET"
    - "PASSWORD"
    - "API_KEY"
    - "DSN"
  masked_exclude:                             # exceptions (NOT masked)
    - "MAX_TOKENS"
    - "TIMEOUT"
    - "PORT"
  file_patterns:                              # keys containing these → file type
    - "PRIVATE_KEY"
    - "_CERT"
    - "_PEM"
  file_exclude:                               # exceptions (NOT file type)
    - "_PATH"
    - "_DIR"
    - "_URL"

Environment Variables

| Variable | Description | |----------|-------------| | GITLAB_TOKEN | GitLab Personal Access Token (scope: api) | | GITLAB_PROJECT_ID | Project ID or URL-encoded path | | GITLAB_URL | GitLab instance URL (default: https://gitlab.com) | | NO_COLOR | Disable colored output when set to any non-empty value (standard convention) |

Environment variables take precedence over config file values. CLI flags take precedence over everything.

How It Works

Sync Workflow

  1. Parse — reads .env file, handles multiline values, skips placeholders
  2. Classify — auto-detects masked/protected/file properties from key patterns and values
  3. Fetch — gets current variables from GitLab (paginated, concurrent-safe)
  4. Diff — calculates creates, updates, deletes, and unchanged
  5. Apply — distributes changes across worker pool with rate limiting
  6. Report — color-coded summary with timing and API call stats

Variable Classification

glenv auto-detects variable properties:

| Property | Condition | |----------|-----------| | masked | Key matches secret pattern (_TOKEN, SECRET, PASSWORD, PRIVATE_KEY, etc.) AND value is >= 8 characters AND value is single-line AND value contains only [a-zA-Z0-9_:@-.+~=/] characters | | protected | Environment is production AND key matches secret pattern | | file type | (Key matches file pattern (PRIVATE_KEY, _CERT, _PEM) AND value contains newlines) OR value contains PEM headers (-----BEGIN) |

Variables with placeholder values (your_, CHANGE_ME, REPLACE_WITH_) are skipped. Variables with interpolation (${VAR}) are skipped.

Rate Limiting

glenv uses a token bucket rate limiter to stay within GitLab API limits:

| GitLab Instance | Limit | Default Config | |----------------|-------|----------------| | gitlab.com | 2,000 req/min (~33/sec) | 10 req/sec, 5 workers | | Self-hosted | Configurable | Adjust via config |

On 429 responses:

  1. Parse Retry-After header
  2. Wait the specified duration
  3. Retry with exponential backoff + jitter
  4. Max 3 retries per operation

.env File Format

Supported syntax:

# Comments are skipped
KEY=value
QUOTED="value with spaces"
SINGLE_QUOTED='value'

# Multiline values
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY---
View on GitHub
GitHub Stars7
CategoryOperations
Updated18d ago
Forks0

Languages

Go

Security Score

90/100

Audited on Mar 14, 2026

No findings