Skip to content

Instantly share code, notes, and snippets.

@andersonbosa
Last active September 11, 2024 20:30
Show Gist options
  • Save andersonbosa/ecff85c26b73b33face247d8b88b2caa to your computer and use it in GitHub Desktop.
Save andersonbosa/ecff85c26b73b33face247d8b88b2caa to your computer and use it in GitHub Desktop.
Set/update multiple CI/CD variables on your Gitlab Pipelines.
#!/usr/bin/env zx
/**
* This script aims to add multiple environment variables to your Gitlab settings.
*
* Useful when setting up a new pipeline.
*
* @author Anderson Bosa < https://github.com/andersonbosa >
*
* @example
*
* zx gitlab_add_multiple_env_variable_from_env_file.mjs <namespace/repository> /path/to/.env
*/
import fs from 'node:fs'
const args = process.argv.slice(3, process.argv.length)
const MIN_REQUIRED_ARGS_TO_RUN = 2
if (args.length < MIN_REQUIRED_ARGS_TO_RUN) {
console.error('USAGE: zx gitlab_add_batch_of_envvars.mjs <gitlab_repository> <path_to_file>')
process.exit(1)
}
const gitlabGroupAndRepo = args[0]
console.log(`${new Date().toISOString()} INFO: Using gitlab repository: '${gitlabGroupAndRepo}'`)
const filePath = args[1]
console.log(`${new Date().toISOString()} INFO: Using file: '${filePath}'`)
async function setOrUpdateVariable (gitlabGroupAndRepo, variable) {
const {
key,
value,
metadata: {
shouldMask
}
} = variable
try {
console.log(`${new Date().toISOString()} INFO: Setting environment variable: ${key}=${value}, shouldMask: ${shouldMask} `)
await $`glab variable set ${key} ${value} --repo ${gitlabGroupAndRepo} --raw ${shouldMask ? '--masked' : ''}`
} catch (error) {
const hasAlreadyBeenSet = error?.stderr.includes('has already been taken')
if (!hasAlreadyBeenSet) {
console.error(`ERROR: While setting environment variable: ${error.message}`)
throw error
}
console.log(`${new Date().toISOString()} INFO: Updating environment variable: ${key}=${value} `)
await $`glab variable update ${key} ${value} --repo ${gitlabGroupAndRepo} --raw ${shouldMask ? '--masked' : ''}`
}
}
async function deleteVariable (gitlabGroupAndRepo, variable) {
const { key } = variable
console.log(`${new Date().toISOString()} INFO: Deleting environment variable: ${key}`)
await $`glab variable delete ${key} --repo ${gitlabGroupAndRepo} `
}
function extractEnvVariables (str) {
return str.split('\n')
.map(line => line.trim())
.filter(line => line && !line.startsWith('#'))
.map(line => {
const shouldMask = line.startsWith('^')
const [key, value] = shouldMask ? line.substring(1).split('=') : line.split('=')
return {
key,
value: value || '',
metadata: {
shouldMask
}
}
})
}
async function main (filePath, gitlabGroupAndRepo) {
let envString
try {
envString = fs.readFileSync(filePath, 'utf8')
} catch (error) {
console.error(`ERROR: While reading file: ${error.message}`)
process.exit(1)
}
const envVariables = extractEnvVariables(envString)
await Promise.all(
envVariables.map(
// async (variable) => deleteVariable(gitlabGroupAndRepo, variable), /* Useful when you want to delete all variables. */
async (variable) => setOrUpdateVariable(gitlabGroupAndRepo, variable),
)
)
console.log(`${new Date().toISOString()} INFO: Listing environment variables to '${gitlabGroupAndRepo}'`)
await $`glab variable list --repo ${gitlabGroupAndRepo}`
console.log(`${new Date().toISOString()} INFO: Script finished successfully.`)
const gitlabHost = await $`glab config get --global host`
const glabCiCdSettingsUrl = `https://${String(gitlabHost).trim()}/${gitlabGroupAndRepo}/-/settings/ci_cd`
console.log(`${new Date().toISOString()} INFO: Checkout to further CI/CD settings: '${glabCiCdSettingsUrl}'`)
process.exit(0)
}
main(filePath, gitlabGroupAndRepo)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment