How to Create and Update Gitlab CI/CD Variables Using PowerShell

How to Create and Update Gitlab CI/CD Variables Using PowerShell

How to Use PowerShell Invoke-WebRequest to Set Gitlab CI/CD Variables

Context

I needed to create multiple CI/CD variables in Gitlab on my Windows machine. I chose to be lazy and skip the Clickops, so I automated everything instead using PowerShell 🤪️️️️️️

Prerequisite

  1. Create a personal access token with api scope to invoke the Gitlab REST API.

  2. Retrieve your project id in Settings > General

  3. Store them into your PowerShell terminal as an environment variables.

$env:gitlab_token='REPLACE_VALUE_WITH_API_TOKEN'
$env:project_id='REPLACE_VALUE_WITH_PROJECT_ID'

TLDR;

  • You can refer to the complete script in this project repository if you want to jump right into action

Step-by-Step Walkthrough

  1. First up, defining the Gitlab token and project ID as variables in the PowerShell script
# User token and project id
$GITLAB_API_TOKEN="$env:gitlab_token"
$PROJECT_ID="$env:project_id"

# To toggle between create / update
$ACTION="create" 
#$ACTION="update"
  1. Then we define the Gitlab endpoints required. In this case, we are using the Project-level CI/CD variables API, along with the headers that will be used in the API calls.
# Gitlab endpoints
$GITLAB_BASE_URI = 'https://gitlab.com'
$GITLAB_BASE_API = "$GITLAB_BASE_URI/api/v4"

# Target API for Project-level CI/CD variables
$GITLAB_URI="$GITLAB_BASE_API/projects/$PROJECT_ID/variables"

# Headers
$Headers = @{
    "Authorization" = "Bearer $GITLAB_API_TOKEN"
}
  1. Next, we will define an array of hashtable that will contain the key-value pair for the CI/CD variables.

    • Each hashtable contains the form data for 1 CI/CD variable

    • You can define multiple hashtable inside the array

    • The protected, masked and raw keys are to determine whether the variable needs to be protected, masked and treated as a literal string respectively.

# Key-value pairs should be customized here to your needs
$VariableForm = @(
    @{
        "variable_type" = "env_var"
        "key" = "sample_key1"
        "value" = "dummy"
        "protected" = $false
        "masked" = $false
        "raw" = $true
        "environment_scope" = "*"
        "description" = "Sample key 1 created"
    },
    @{
        "variable_type" = "env_var"
        "key" = "sample_key2"
        "value" = "dummydummy"
        "protected" = $false
        "masked" = $false
        "raw" = $true
        "environment_scope" = "*"
        "description" = "Sample key 2 created"
    }
)
  1. To invoke the REST API, we will be using Invoke-WebRequest command.

  2. I have written the CreateVariablesForProject function to call the create variable API.

function CreateVariablesForProject([string] $gitlab_url, [hashtable] $headers, [object[]] $form) {

    $form | ForEach-Object {
        $current_form = $_
        $Result = Invoke-WebRequest -Uri $gitlab_url -Method Post -Headers $headers -Form $current_form
        Write-Output $Result
    }

}
  1. I have also written the UpdateVariablesForProject function to call the update variable API.

    The only difference is PUT method and the API URL needs to append the value of variable_key.

function UpdateVariablesForProject([string] $gitlab_url, [hashtable] $headers, [object[]] $form) {
    $form | ForEach-Object {
        $current_form = $_
        $variable_key = $current_form.key
        $gitlab_update_url = "$gitlab_url/$variable_key"
        $Result = Invoke-WebRequest -Uri $gitlab_update_url -Method Put -Headers $headers -Form $current_form
        Write-Output $Result
    } 
}
  1. Finally, we will invoke the function to trigger the actual creation of the CI/CD variables in the target project repository.
Write-Output "[info] Create CI/CD variables for Target Project"
CreateVariablesForProject $GITLAB_URI $Headers $VariableForm

if ( "$ACTION" -eq "create") {

    Write-Output "[info] Create CI/CD variables for Target Project"
    CreateVariablesForProject $GITLAB_URI $Headers $VariableForm

} elseif ("$ACTION" -eq "update") {
    Write-Output "[info] Update CI/CD variables for Target Project"
    UpdateVariablesForProject $GITLAB_URI $Headers $VariableForm

}

Conclusion

I decided to embrace my inner laziness and avoid the dreaded Clickops by automating everything with PowerShell instead of the usual shell-script. It's a bit unconventional, but hey, it should save us all some time when creating and updating CI/CD variables on GitLab from a Windows machine. Cheers! 🤪️️️️️️

Did you find this article valuable?

Support Nuggets of Wisdom by becoming a sponsor. Any amount is appreciated!