Create Release on GitLab with PowerShell - powershell

I try to create a powershell script which can help us to create a release on our private gitlab server.
I found this tutorial
How to create releases in GitLab?
I'm not able to figure out how I can replace the curl command with the powershell invoke-webrequest command.
I already tried multiple concepts for this. In our case we have some code files and create the package in the same repository. The package is included in the gitignore file. (That's fine for us)
Now I tried to do this
$body = #{'form'='file=#/our awesome app.app'}
Invoke-RestMethod -Headers #{ 'PRIVATE-TOKEN'='<mytoeken>' } -Uri https://scm.domain.net/api/v4/projects/19/uploads -Body $Body
Result:
Invoke-RestMethod : {"error":"file is invalid"}
Does anyone have a script for creating a gitlab release page with download and changelog with powershell.
I also tried release it but I'm not able to configure it for gitlab.
https://www.npmjs.com/package/release-it#gitlab-releases

Below is a collection of some PowerShell snippets I have written or used for this purpose. Maybe this can help some people. Can you not create the $Body in the script also - it looks like it fails create the content from the file?
# Provides code snippets for Windows Powershell to use Gitlabs API to do various tasks
# for example [ Issue management, Release creation etc.]
# https://docs.gitlab.com/ee/api/
# Variables
# modify with you own content
$glUrl = "http://<your-gitlab-url>"
$p = "3" # Project ID
$tag = "1.3" # Modify this to create/delete release ...
$token = "<EDIT_ME>" # Your access token (http://<your-gitlab-url>/profile/personal_access_tokens)
$projectsUrl = "$glUrl/api/v4/projects" # i.e. http://<your-gitlab-url>/api/v4/projects
$pUrl = "$projectsUrl/$p" # i.e. http://<your-gitlab-url>/api/v4/projects/3
$releaseUrl = "$pUrl/releases" # i.e. http://<your-gitlab-url>/api/v4/projects/3/releases
$artifactsUrl = "$pUrl/jobs/artifacts/$tag/download?job=build-standard" # i.e. Build artifacts created for $tag and the relevant job ("build-standard"; can be modified)
# Project List
$r = Invoke-RestMethod -Headers #{ 'PRIVATE-TOKEN'="$token" } -Uri $projectsUrl
$r | Sort-Object -Property id | Format-Table -Property id, name
# Issues List
$r = Invoke-RestMethod -Headers #{ 'PRIVATE-TOKEN'="$token" } -Uri $pUrl/issues
$r | Sort-Object -Property id | Format-Table -Property id, state, title
# New Issue
Invoke-RestMethod -Method Post -Headers #{ 'PRIVATE-TOKEN'="$token" } -Uri "$pUrl/issues?title=Hello from PS&labels=test"
# Comment on the Issue
Invoke-RestMethod -Method Post -Headers #{ 'PRIVATE-TOKEN'="$token" } -Uri "$pUrl/issues/3/notes?body=Hello PowerShell"
function Register-NewIssue {
param(
[string]$title,
[string]$desc = '',
[string]$uri = '$projectUrl/issues'
)
$title = [System.Web.HttpUtility]::UrlEncode($title)
$desc = [System.Web.HttpUtility]::UrlEncode($desc)
$u = "$uri`?title=$title&description=$desc"
$r = Invoke-RestMethod -Method Post -Headers #{ 'PRIVATE-TOKEN'= "$token" } -Uri $u
$r | Format-List -Property iid, state, title, description
}
# Get list of Releases
Invoke-RestMethod -Method Get -Headers #{ 'PRIVATE-TOKEN'="$token" } -Uri $releaseUrl
# Create a Release
$JSON = #"
{
"name": "New release",
"tag_name": $tag,
"ref": "master",
"description": "FromPS",
"assets":{
"links":[
{
"name":"Executables",
"url":"$artifactsUrl"
}
]
}
}
"#
Invoke-RestMethod -Method Post -Headers #{ 'PRIVATE-TOKEN'="$token"; 'Content-Type'='application/json' } -Body $JSON -Uri "$releaseUrl"
Read-Host -Prompt "Press Enter to continue"
# Adds only a link to this Release manually
$JSONLINK = #'
{"name":"awesome-exec",
"url":"$artifactsUrl"
}
'#
Invoke-RestMethod -Method Post -Headers #{ 'PRIVATE-TOKEN'= "$token"; 'Content-Type'='application/json' } -Body $JSONLINK -Uri "$releaseUrl/$tag/assets/links"
# Delete a Release
Invoke-RestMethod -Method Delete -Headers #{ 'PRIVATE-TOKEN'= "$token" } -Uri "$releaseUrl/$tag"

Related

Running query in Pipeline in Azure-DevOps

I want to add an Azure-DevOps query to a pipeline,
Is there an option to put a query in a yaml file?
If yes, how?
Thanks in advance.
I suppose that you could run a rest api for query via powershell script or something like that in a pipeline task to do it.
GET https://dev.azure.com/{organization}/{project}/_apis/wit/queries/{query}?api-version=7.0
Powershell Script
# Define organization base url, PAT and API version variables
$orgUrl = "https://dev.azure.com/{org}/{project}"
$pat = "{pat}"
$queryString = "api-version=7.0"
# Create header with PAT
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)"))
$header = #{authorization = "Basic $token"}
# Get the list of all projects in the organization
$projectsUrl = "$orgUrl/_apis/wit/queries/{query}?$queryString"
$result = Invoke-RestMethod -Uri $projectsUrl -Method Get -ContentType "application/json" -Headers $header | ConvertTo-Json | ConvertFrom-Json
write-host $result
If you are going to echo the specific element from the query result, you could modify the $result line with below
$result = Invoke-RestMethod -Uri $projectsUrl -Method Get -ContentType "application/json" -Headers $header | ConvertTo-Json | ConvertFrom-Json | Select-Object -ExpandProperty {your element}
write-host $result
You could also create a query with rest api, and with the similar powershell script to put into pipeline.
POST https://dev.azure.com/{organization}/{project}/_apis/wit/queries/{query}?api-version=7.0

Unable to ingest JSON data into Azure Event Hub

I wrote the below Powershell script to get the JSON data from an API endpoint (https://data.melbourne.vic.gov.au/resource/vh2v-4nfs) and then write this data in JSON format to Azure Event hub. I am able to successfully get the data from the endpoint however the data is not getting ingested into Azure Event Hub.
Can anyone please let me know what's wrong with the below code:
$url = "https://data.melbourne.vic.gov.au/resource/vh2v-4nfs"
$apptoken = "k7lQcUCVFoROv7rQh9fSSXMkZ"
# Set header to accept JSON
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Accept","application/json")
$headers.Add("X-App-Token",$apptoken)
$results = Invoke-RestMethod -Uri $url -Method get -Headers $headers
$results
$method = "POST"
$URI = "https://YOURNS.servicebus.windows.net/eh-streetparking/messages"
$signature = "SharedAccessSignature sr=YOURNS.servicebus.windows.net%2feh-streetparking&sig=K6bfL1VjW9FUcL0B5xaI%3d&se=16722&skn=eh-sap-streetparking"
#$authInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$signature"))
# API headers
$headers = #{
"Authorization"=$signature;
# "Content-Type"="application/json;type=entry;charset=utf-8";
"Content-Type"="application/json";
}
# execute the Azure REST API
foreach ( $result in $results)
{
Invoke-RestMethod -Uri $URI -Method $method -Headers $headers -Body $result
}
The value you have presented as the return result from your Invoke-RestMethod is actually a deserialized PowerShell object, not JSON. It appears to be having its quotes removed at some point too.
PSObject ($results) looks like this: $x = #{account_id="12345"; username="12345"; is_locked="False"; employee_id="12345"; first_name="John"; middle_initial="Roger"; last_name="Doe"; full_name="John Roger Doe"}
You can do this to access individual values:
$x.full_name
Finally, follow this syntax to send POST request:
$Cred = Get-Credential
$Url = "https://server.contoso.com:8089/services/search/jobs/export"
$Body = #{
search = "search index=_internal | reverse | table index,host,source,sourcetype,_raw"
output_mode = "csv"
earliest_time = "-2d#d"
latest_time = "-1d#d"
}
Invoke-RestMethod -Method 'Post' -Uri $url -Credential $Cred -Body $body -OutFile output.csv

Scheduling a Azure DevOps release using Powershell

I am able to trigger a Azure DevOps release using Rest API call. But when i tried to do it by adding the scheduling it is not working. The code i used is given below:
$PATtoken= 'PAT'
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PATtoken)"))
$header=#{authorization= "Basic $token" }
$defurl = "https://vsrm.dev.azure.com/Orgnization/Project/_apis/release/definitions/13?api-version=5.1"
$definition = Invoke-RestMethod -Uri $defurl -Method Get -Headers $header
$triggers = '
[{
"schedule": {
"timeZoneId": "India Standard Time",
"startHours": 20,
"startMinutes": 40,
"daysToRelease": 31
}
}]'
$definition | Add-Member -NotePropertyName "triggers" -NotePropertyValue (Convertfrom-Json $triggers) -Force
$json = #($definition) | ConvertTo-Json -Depth 99
$updatedef = Invoke-RestMethod -Uri $defurl -Method Put -Body $json -ContentType "application/json" -Headers $header
Write-Host ($updatedef.triggers | ConvertTo-Json -Depth 99)
But unfortunately the scheduling or triggering is not happening.
You can do it in this way:
...
$definition = Invoke-RestMethod -Uri $defurl -Method Get -Headers $header
$hash = #(
#{ triggerType="schedule";
schedule = #{"daysToRelease"="31";"timeZoneId"="India Standard Time";"startHours"="20";"startMinutes"="40"}
}
)
$definition.triggers = $hash
$json = $definition | ConvertTo-Json -Depth 99
Invoke-RestMethod -Uri $defurl -Method Put -Body $json -ContnetType application/json -Headers $header
You should not add schedule into triggers to configure the release pipeline schedule execute.
You can use Postman as test. See below pic:
Even I have configure the schedule script in request body, the response body still has no content in the trigger.
To set the schedule, you need apply above schedule script to schedules which is nested under environment. Also, you could using Fiddler to capture the records to confirm this by configuring the schedule release from UI.

How to check if a previous release has been completed before deploying a new release

As part of our release pipeline we have a task (the last task) to merge the release branch back to master.
I was wondering whether there is a way to check that this task or the previous release has completed before allowing the new release to be queued. Can a gate be used for this?
Ideally, the release manager would then be able to decide whether they want to continue with the release or to cancel.
You can't use the Invoke Rest API gate with an Azure DevOps API url because for checking the last release status you need to check the environment (stage) status, and for this, you need to the release id (so you can't know what it will be and put it in the rest API gate URL).
But, you can use PowerShell to check the last release and if it is not succeeded just fail the stage.
Add a PowerShell task in your release to check the last release:
$headers = #{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" }
# Replace {org} with your organization
# Replace {project} with your project
# Replace {defId} with your release definition id
$url = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases?definitionId={defId}&api-version=5.1"
$releases = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType 'application/json'
$releaseUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases/$($releases.value[1].id)?api-version=5.1"
$releaseInfo = Invoke-RestMethod -Method Get -Uri $releaseUrl -Headers $headers -ContentType 'application/json'
$releaseEvnriomentId = $releaseInfo.environments.Where({ $_.name -eq 'THE STAGE NAME WHERE YOU DO MERGE' }).id
$envUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/Release/releases/$($releases.value[1].id)/environments/$($releaseEvnriomentId)?api-version=5.1-preview.1"
$environment = Invoke-RestMethod -Method Get -Uri $envUrl -Headers $headers -ContentType 'application/json'
$envStatus = $environment.status
if($envStatus -ne "succeeded")
{
Write-Error "Previous release not succeeded!"
}
else
{
Write-Host "Previous release succeeded :)"
}
In the agent job options you need to allow scripts to access the OAuth token:
Azure functions also support PowerShell so you do it also with Azure functions gate:
1) Create a new Azure Function with VS Code like explained here.
2) In your run.ps1 file replace the code to this code:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
$defnitionId = $Request.Query.DefinitionId
# Generate PAT and put it in the {YOUR PAT}
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,"{YOUR PAT}")))
$headers = #{Authorization=("Basic {0}" -f $base64AuthInfo)}
# Replace {org} with your organization
# Replace {project} with your project
$url = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases?definitionId=$($defnitionId)&api-version=5.1"
$releases = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType 'application/json'
Write-Debug $releases
$releaseUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases/$($releases.value[1].id)?api-version=5.1"
$releaseInfo = Invoke-RestMethod -Method Get -Uri $releaseUrl -Headers $headers -ContentType 'application/json'
Write-Debug $releaseInfo
$releaseEvnriomentId = $releaseInfo.environments.Where({ $_.name -eq 'THE STAGE NAME WHERE YOU DO MERGE' }).id
$envUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/Release/releases/$($releases.value[1].id)/environments/$($releaseEvnriomentId)?api-version=5.1-preview.1"
$environment = Invoke-RestMethod -Method Get -Uri $envUrl -Headers $headers -ContentType 'application/json'
Write-Debug $environment
$envStatus = $environment.status
Write-Debug $envStatus
if($envStatus -ne "succeeded")
{
$status = [HttpStatusCode]::BadRequest
$body = "failed"
}
else
{
$status = [HttpStatusCode]::OK
$body = "success"
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = $status
Body = $body
})
3) Publish the function to Azure.
4) Create an Invoke Azure Function gate in your release:
Another option, take the above code, convert him to C# or another language ans use Rest API, deploy to it web server and use the Invoke Rest API gate.

How can I cancel & delete a waiting build in the queue using PowerShell

Due to long running builds various next in line builds take longer time to execute.
Is there a way I can cancel and delete waiting build in queue and give way for latest triggered build using PowerShell or REST API's?
The following code snippet goes over all TFS builds,Gets the Builds which in Progress and not started, and then, cancel them.
$tfsUrl = "http://{server}:{port}/{organization}/{collection}/{project}" # TFS Base URL
$BuildDefsUrl = "$tfsUrl/_apis/build/definitions?api-version=2.0" # TFS build definitions URL
$BuildsUrl = "$tfsUrl/_apis/build/builds" #TFS Builds URL
$Builds = (Invoke-RestMethod -Uri ($BuildDefsUrl) -Method GET -UseDefaultCredentials).value | Select id,name # get all builds
#for filtering use : | Where-Object {$_.name -like "*Your Pattern*"}
foreach($Build in $Builds)
{
$command = "$($BuildsUrl)?api-version=3.2-preview.3&resultFilter=inprogress&definitions=$($Build.id)&queryOrder=finishTimeDescending"
$Ids = (((Invoke-RestMethod -Method Get -Uri $command -UseDefaultCredentials).value) | where status -like "*notStarted*").id # get waiting builds id's
foreach($id in $Ids)
{
$uri = "$($BuildsUrl)/$($id)?api-version=2.0" # TFS URI
$body = '{"status":4}' # body
$result = Invoke-RestMethod -Method Patch -Uri $uri -UseDefaultCredentials -ContentType 'application/json' -Body $body -Verbose #cancel build
}
}
The above example is pretty old. The code snippet below working for Azure Devops-
$PATToken = "PAT_GOES_HERE"
$AuthHeader= #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PATToken)")) }
$azureDevops = "https://dev.azure.com/{organization}/{project}"
$BuildsUrl = "$azureDevops/_apis/build/builds"
$filterBuilds = "$($BuildsUrl)?statusFilter=notStarted&api-version=6.0"
(Invoke-RestMethod -Method Get -Uri $filterBuilds -Headers $AuthHeader).value | % {
$uri = "$($BuildsUrl)/$($_.id)?api-version=6.0" # Azure Devops URI
$body = '{"status":4}' # body
$result = Invoke-RestMethod -Method Patch -Uri $uri -Headers $AuthHeader -ContentType 'application/json' -Body $body -Verbose #cancel build
Write-Output "$($_.definition.name) cancaled"
}