Skip to content

Instantly share code, notes, and snippets.

@brospars
Last active September 12, 2025 09:53
Show Gist options
  • Select an option

  • Save brospars/af91dfdc257fc7f0cb7621529f803999 to your computer and use it in GitHub Desktop.

Select an option

Save brospars/af91dfdc257fc7f0cb7621529f803999 to your computer and use it in GitHub Desktop.
Bash Script: Bulk create and sync .env variables to GitLab CI/CD

This Bash script automates the process of creating and syncing environment variables from a .env file to GitLab CI/CD variables. It’s designed to work with self-hosted GitLab instances (e.g., gitlab.example.com) and handles both creating new variables and updating existing ones seamlessly.

Usage:

chmod +x add_gitlab_ci_vars.sh
./add_gitlab_ci_vars.sh "https://gitlab.com/your-group/your-project" "your-private-token"
#!/bin/bash
# Check if .env file exists
if [ ! -f ".env" ]; then
echo "Error: .env file not found."
exit 1
fi
# Check if PROJECT_URL and PRIVATE_TOKEN are provided
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <PROJECT_URL> <PRIVATE_TOKEN>"
echo "Example: $0 https://gitlab.com/your-group/your-project your-private-token"
exit 1
fi
PROJECT_URL="$1"
PRIVATE_TOKEN="$2"
# Extract the domain (e.g., gitlab.example.com)
DOMAIN=$(echo "$PROJECT_URL" | sed -E 's|^https://([^/]+).*|\1|')
# Extract the project path (e.g., your-group/your-project)
PROJECT_PATH=$(echo "$PROJECT_URL" | sed 's|^https://[^/]*/||')
# URL encode the project path
ENCODED_PROJECT_PATH=$(printf '%s' "$PROJECT_PATH" | jq -sRr @uri)
# Construct the GitLab API URL for variables
API_URL="https://${DOMAIN}/api/v4/projects/${ENCODED_PROJECT_PATH}/variables"
# Read .env file line by line
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip comments and empty lines
[[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
# Extract key and value
key=$(echo "$line" | cut -d '=' -f 1)
value=$(echo "$line" | cut -d '=' -f 2-)
# Skip if key or value is empty
[[ -z "$key" || -z "$value" ]] && continue
# Try to create the variable (POST)
response=$(curl --silent --write-out "\n%{http_code}" --request POST \
--header "PRIVATE-TOKEN: $PRIVATE_TOKEN" \
--form "key=$key" \
--form "value=$value" \
--form "protected=false" \
--form "masked=false" \
"$API_URL")
# Extract HTTP status code
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')
# Check if successful
if [ "$http_code" -eq 200 ] || [ "$http_code" -eq 201 ]; then
echo "Successfully created variable: $key"
# If it fails try updating the variable (PUT)
else
# Update existing variable (PUT) using the key
response=$(curl --silent --write-out "\n%{http_code}" --request PUT \
--header "PRIVATE-TOKEN: $PRIVATE_TOKEN" \
--form "value=$value" \
"$API_URL/$key")
# Extract HTTP status code
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')
# Check if successful
if [ "$http_code" -eq 200 ] || [ "$http_code" -eq 201 ]; then
echo "Successfully updated variable: $key"
else
echo "Failed to update/create variable: $key"
echo "Response: $body"
fi
fi
done < ".env"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment