Skip to content

Commit ddb4ff0

Browse files
Lucas-c-BManbearpiet
authored andcommitted
feat: Added function New-PipelineRun
Added a new function called New-PipelineRun, which can start a pipelin run in an Azure DevOps Project programmatically docs: Added comment based help to New-PipelineRun Added comment based help to New-PipelineRun fix: Add missing ValidateScript Add missing ValidateScript fix: should process input fix: param validator collectionUri fix: fixed service connection parameter set feat: Add function Get-PipelineRun Add function Get-PipelineRun that gets all or specific runs from the specified pipeline fix: formatting formatting feat: added classification nodes endpoint feat: Add PipelineFolderPath parameter to be able to place a pipeline in a folder in azure devops to the module: New-AzDoPipeline Add PipelineFolderPath parameter to be able to place a pipeline in a folder in azure devops to the module: New-AzDoPipeline feat: add public cmdlet to create pull requests individually or in bulk (supports pipeline) fix: 💩 Fixing breaking change for Get-AzAccessToken Fixing Get-AzAccessToken, but this needs the Invoke-RestMethod function needs refactoring feat: add support for content type header fix: Add support for files beginning with a dot refactor: Enhance Get-PipelineRun function to use splatting and return structured output refactor: Improve New-PipelineRun function output structure
1 parent 4100a2b commit ddb4ff0

File tree

14 files changed

+1071
-7
lines changed

14 files changed

+1071
-7
lines changed

AzureDevOpsPowerShell/Private/Invoke-AzDoRestMethod.ps1

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ function Invoke-AzDoRestMethod {
3333

3434
[Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
3535
[PSCustomObject[]]
36-
$Body
36+
$Body,
37+
38+
[Parameter()]
39+
[ValidateSet('application/json', 'application/json-patch+json')]
40+
[string]
41+
$ContentType = 'application/json'
3742
)
3843

3944
begin {
@@ -73,7 +78,7 @@ function Invoke-AzDoRestMethod {
7378
$params = @{
7479
Method = $Method
7580
Headers = $script:header
76-
ContentType = 'application/json'
81+
ContentType = $ContentType
7782
}
7883

7984
if ($QueryParameters) {

AzureDevOpsPowerShell/Private/New-AzDoAuthHeader.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ function New-AzDoAuthHeader {
1717
$PSCmdlet.ThrowTerminatingError($PSItem)
1818
}
1919
Write-Verbose "Getting Access Token"
20-
$script:header = @{Authorization = 'Bearer ' + (Get-AzAccessToken -Resource 499b84ac-1321-427f-aa17-267ca6975798).token
20+
$script:header = @{
21+
Authorization = 'Bearer ' + ((Get-AzAccessToken -Resource 499b84ac-1321-427f-aa17-267ca6975798 -AsSecureString).token | ConvertFrom-SecureString -AsPlainText)
2122
}
2223
} catch {
2324
throw 'Please login to Azure PowerShell first'

AzureDevOpsPowerShell/Private/Validate-CollectionUri.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function Validate-CollectionUri {
77
$CollectionUri
88
)
99

10-
if ($CollectionUri -notmatch '^https:\/\/dev\.azure\.com\/\w+$') {
10+
if ($CollectionUri -notmatch '^https:\/\/dev\.azure\.com\/\w+') {
1111
Write-AzdoError "CollectionUri must be a valid Azure DevOps collection URI starting with 'https://dev.azure.com/'"
1212
} else {
1313
$true
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
function New-AzDoPullRequest {
2+
<#
3+
.SYNOPSIS
4+
Creates a pull request in Azure DevOps.
5+
.DESCRIPTION
6+
Creates a pull request in Azure DevOps.
7+
.EXAMPLE
8+
$params = @{
9+
CollectionUri = "https://dev.azure.com/contoso"
10+
RepoName = "Repo1"
11+
ProjectName = "Project 1"
12+
Title = "New Pull Request"
13+
Description = "This is a new pull request"
14+
SourceRefName = "refs/heads/feature1"
15+
TargetRefName = "refs/heads/main"
16+
}
17+
New-AzDoPullRequest @params
18+
19+
This example creates a new Azure DevOps Pull Request with splatting parameters
20+
.EXAMPLE
21+
$params = @{
22+
CollectionUri = "https://dev.azure.com/contoso"
23+
RepoName = "Repo1"
24+
ProjectName = "Project 1"
25+
Title = "New Pull Request"
26+
Description = "This is a new pull request"
27+
SourceRefName = "refs/heads/feature1"
28+
TargetRefName = "refs/heads/main"
29+
}
30+
$params | New-AzDoPullRequest
31+
32+
This example creates a new Azure DevOps Pull Request with pipeline parameters
33+
.OUTPUTS
34+
[PSCustomObject]@{
35+
CollectionUri = $CollectionUri
36+
ProjectName = $ProjectName
37+
RepoName = $RepoName
38+
PullRequestId = $res.pullRequestId
39+
PullRequestURL = $res.url
40+
}
41+
.NOTES
42+
#>
43+
44+
[CmdletBinding(SupportsShouldProcess)]
45+
param (
46+
# Collection Uri of the organization
47+
[Parameter(Mandatory)]
48+
[ValidateScript({ Validate-CollectionUri -CollectionUri $_ })]
49+
[string]
50+
$CollectionUri,
51+
52+
# Id of the repository
53+
[Parameter(Mandatory)]
54+
[string]
55+
$RepoName,
56+
57+
# Name of the project where the new repository has to be created
58+
[Parameter(Mandatory)]
59+
[string]
60+
$ProjectName,
61+
62+
# Title of the pull request
63+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
64+
[string[]]
65+
$Title,
66+
67+
# Description of the pull request
68+
[Parameter(ValueFromPipelineByPropertyName)]
69+
[string[]]
70+
$Description = 'Describe the changes made in this pull request',
71+
72+
# Source ref name
73+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
74+
[string[]]
75+
$SourceRefName,
76+
77+
# Target ref name
78+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
79+
[string[]]
80+
$TargetRefName
81+
)
82+
83+
begin {
84+
Write-Verbose "Starting function: New-AzDoPullRequest"
85+
$CollectionUri = $CollectionUri.TrimEnd('/')
86+
$result = New-Object System.Collections.Generic.List[System.Object]
87+
}
88+
89+
process {
90+
foreach ($pr in $Title) {
91+
$prTitle = $pr
92+
$prDescription = $Description[$Title.IndexOf($pr)]
93+
$prSourceRefName = $SourceRefName[$Title.IndexOf($pr)]
94+
$prTargetRefName = $TargetRefName[$Title.IndexOf($pr)]
95+
96+
# If the ref name is not in the format refs/heads/branch, then add it
97+
if ($prSourceRefName -notlike "refs/*") {
98+
$prSourceRefName = "refs/heads/$prSourceRefName"
99+
}
100+
if ($prTargetRefName -notlike "refs/*") {
101+
$prTargetRefName = "refs/heads/$prTargetRefName"
102+
}
103+
104+
$params = @{
105+
uri = "$CollectionUri/$ProjectName/_apis/git/repositories/$RepoName/pullrequests"
106+
version = '7.2-preview.2'
107+
method = 'POST'
108+
body = @{
109+
sourceRefName = $prSourceRefName
110+
targetRefName = $prTargetRefName
111+
title = $prTitle
112+
description = $prDescription
113+
}
114+
}
115+
116+
if ($PSCmdlet.ShouldProcess($CollectionUri, "Create pull request named: $($PSStyle.Bold)$prTitle$($PSStyle.Reset)")) {
117+
try {
118+
$result += Invoke-AzDoRestMethod @params
119+
} catch {
120+
if ($_ -match 'TF401179') {
121+
Write-Warning "Pull request between those branches already exists, trying to get it"
122+
$getParams = @{
123+
uri = "$CollectionUri/$ProjectName/_apis/git/repositories/$RepoName/pullrequests"
124+
version = '7.1-preview.1'
125+
method = 'GET'
126+
}
127+
$result += (Invoke-AzDoRestMethod @getParams).value | Where-Object { $_.sourceRefName -eq $prSourceRefName -and $_.targetRefName -eq $prTargetRefName }
128+
} else {
129+
Write-AzDoError -message $_
130+
}
131+
}
132+
} else {
133+
Write-Verbose "Calling Invoke-AzDoRestMethod with $($params| ConvertTo-Json -Depth 10)"
134+
}
135+
}
136+
}
137+
138+
end {
139+
if ($result) {
140+
$result | ForEach-Object {
141+
[PSCustomObject]@{
142+
CollectionUri = $CollectionUri
143+
ProjectName = $ProjectName
144+
RepoName = $RepoName
145+
PullRequestTitle = $_.title
146+
PullRequestId = $_.pullRequestId
147+
PullRequestURL = $_.url
148+
PullRequestWebUrl = "$CollectionUri/$ProjectName/_git/$RepoName/pullrequest/$($_.pullRequestId)"
149+
PullRequestStatus = $_.status
150+
}
151+
}
152+
}
153+
}
154+
}

AzureDevOpsPowerShell/Public/Api/Git/Pushes/Add-FilesToRepo.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function Add-FilesToRepo {
4949
process {
5050

5151
$changes = @()
52-
$files = Get-ChildItem -Path $Path -Recurse -File
52+
$files = Get-ChildItem -Path $Path -Recurse -File -Force | Where-Object {$_.FullName -notmatch ".git"}
5353
foreach ($file in $files) {
5454

5555
if (($file.Extension -in '.png', '.svg, .jpg', '.jpeg')) {

AzureDevOpsPowerShell/Public/Api/Pipelines/Pipelines/New-AzDoPipeline.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ function New-AzDoPipeline {
4848
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
4949
$RepoName,
5050

51+
# Folder to put Azure Devops Pipeline in
52+
[Parameter(ValueFromPipelineByPropertyName)]
53+
$PipelineFolderPath = $null,
54+
5155
# Path of the YAML-sourcecode in the Repository
5256
[Parameter(ValueFromPipelineByPropertyName)]
5357
[string]
@@ -70,7 +74,7 @@ function New-AzDoPipeline {
7074

7175
$body = @{
7276
name = $PipelineName
73-
folder = $null
77+
folder = $PipelineFolderPath
7478
configuration = @{
7579
type = "yaml"
7680
path = $Path
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
function Get-PipelineRun {
2+
<#
3+
.SYNOPSIS
4+
Retrieves pipeline run information from Azure DevOps for a specified pipeline within a project.
5+
.DESCRIPTION
6+
The `Get-PipelineRun` function fetches details about one or more pipeline runs from an Azure DevOps project.
7+
It requires the collection URI, project name, and pipeline ID. Optionally, specific run IDs can be provided
8+
to filter the results. The function uses the `Invoke-AzDoRestMethod` cmdlet to make the REST API call to
9+
Azure DevOps and returns the run details.
10+
.EXAMPLE
11+
$getPipelineRunSplat = @{
12+
CollectionUri = "https://dev.azure.com/YourOrg"
13+
ProjectName = "YourProject"
14+
PipelineId = 123
15+
}
16+
17+
Get-PipelineRun @getPipelineRunSplat
18+
Retrieves all runs for the specified pipeline in the given project.
19+
.EXAMPLE
20+
$getPipelineRunSplat = @{
21+
CollectionUri = "https://dev.azure.com/YourOrg"
22+
ProjectName = "YourProject"
23+
PipelineId = 123
24+
RunId = 456
25+
}
26+
27+
Get-PipelineRun @getPipelineRunSplat
28+
29+
Retrieves the details of the specified run (with ID 456) for the given pipeline.
30+
.OUTPUTS
31+
System.Management.Automation.PSCustomObject
32+
33+
Returns an array of pipeline run objects. If specific run IDs are provided, only the matching runs are returned.
34+
.NOTES
35+
#>
36+
[CmdletBinding(SupportsShouldProcess)]
37+
param (
38+
# Collection Uri of the organization
39+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
40+
[ValidateScript({ Validate-CollectionUri -CollectionUri $_ })]
41+
[string]
42+
$CollectionUri,
43+
44+
# The name of the project containing the pipeline
45+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
46+
[string]
47+
$ProjectName,
48+
49+
# The ID of the pipeline to retrieve the run for
50+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
51+
[int]$PipelineId,
52+
53+
# The ID of the run to retrieve. If not provided, all runs for the pipeline are returned.
54+
[Parameter(ValueFromPipelineByPropertyName)]
55+
[int[]]$RunId
56+
)
57+
58+
process {
59+
$params = @{
60+
Uri = "$CollectionUri/$ProjectName/_apis/pipelines/$PipelineId/runs"
61+
Version = "6.0"
62+
Method = 'GET'
63+
}
64+
65+
if ($PSCmdlet.ShouldProcess("Pipeline Id: $PipelineId", "Get run")) {
66+
$response = Invoke-AzDoRestMethod @params
67+
$runs = $response.value
68+
69+
if (-not $RunId) {
70+
$runs | ForEach-Object {
71+
[PSCustomObject]@{
72+
PipelineId = $_.pipeline.id
73+
RunId = $_.id
74+
RunName = $_.name
75+
Result = $_.result
76+
State = $_.state
77+
CreatedAt = $_.createdDate
78+
FinishedAt = $_.finishedDate
79+
ProjectName = $ProjectName
80+
CollectionUri = $CollectionUri
81+
URL = $_.url
82+
}
83+
}
84+
return
85+
}
86+
87+
@($runs | Where-Object { $_.id -in $RunId } | ForEach-Object {
88+
[PSCustomObject]@{
89+
PipelineId = $_.pipeline.id
90+
RunId = $_.id
91+
RunName = $_.name
92+
Result = $_.result
93+
State = $_.state
94+
CreatedAt = $_.createdDate
95+
FinishedAt = $_.finishedDate
96+
ProjectName = $ProjectName
97+
CollectionUri = $CollectionUri
98+
URL = $_.url
99+
}
100+
}
101+
)
102+
} else {
103+
Write-Verbose "Calling Invoke-AzDoRestMethod with $($params| ConvertTo-Json -Depth 10)"
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)