func_Milestones.ps1

# ---------------------------------------------------------------------
# Group milestones API
# https://docs.gitlab.com/ee/api/group_milestones.html

# get a list of group milestones
function Get-GitlabGroupMilestones( [Parameter(Mandatory=$true)] [string] $group
                                  , [Parameter(Mandatory=$false)][string] $title
                                  , [Parameter(Mandatory=$false)][string] $search
                                  , [Parameter(Mandatory=$false)][switch] $active
                                  , [Parameter(Mandatory=$false)][switch] $closed
                                  )
{
  [string] $GAPI_MILESTONES = "$CI_API_V4_URL/groups/$group/milestones?per_page=100"

  if (![string]::IsNullOrWhiteSpace($title)) {
    $GAPI_MILESTONES += "&title=$title"
  }

  if (![string]::IsNullOrWhiteSpace($search)) {
    $search = [uri]::EscapeDataString($search)  # URL-encoded
    $GAPI_MILESTONES += "&search=$search"
  }

  if ($active) {
    $GAPI_MILESTONES += "&state=active"
  }
  elseif ($closed) {
    $GAPI_MILESTONES += "&state=closed"
  }

  return @(Invoke-RestMethod -headers $GLPT -uri $GAPI_MILESTONES -method GET)
}

# get a single group milestone
function Get-GitlabGroupMilestone( [Parameter(Mandatory=$true)] [string] $group
                                 , [Parameter(Mandatory=$true)]    [int] $id
                                 )
{
  [string] $GAPI_MILESTONES_ID = "$CI_API_V4_URL/groups/$group/milestones/$id"
  return (Invoke-RestMethod -headers $GLPT -uri $GAPI_MILESTONES_ID -method GET)
}

# modify an existing group milestone
function Set-GitlabGroupMilestone( [Parameter(Mandatory=$true)] [string] $group
                                 , [Parameter(Mandatory=$true)]    [int] $id
                                 , [Parameter(Mandatory=$false)][string] $title
                                 , [Parameter(Mandatory=$false)][string] $description
                                 , [Parameter(Mandatory=$false)][string] $start_date
                                 , [Parameter(Mandatory=$false)][string] $due_date
                                 , [Parameter(Mandatory=$false)][switch] $close
                                 , [Parameter(Mandatory=$false)][switch] $reopen
                                 )
{
  $body_json = @{}

  if ($PSBoundParameters.ContainsKey('title')) {
    $body_json += @{ "title" = "$title" }
  }

  if ($PSBoundParameters.ContainsKey('description')) {
    $body_json += @{ "description" = "$description" }
  }

  if ($PSBoundParameters.ContainsKey('start_date')) {
    $body_json += @{ "start_date" = "$start_date" }
  }

  if ($PSBoundParameters.ContainsKey('due_date')) {
    $body_json += @{ "due_date" = "$due_date" }
  }

  if ($close) {
    $body_json += @{ "state_event" = "close" }
  }
  elseif ($reopen) {
    $body_json += @{ "state_event" = "activate" }
  }

  if (!$body_json.Count) { return $null }
  [string] $body = $body_json | ConvertTo-Json -depth 10

  [string] $GAPI_MILESTONES_ID = "$CI_API_V4_URL/groups/$group/milestones/$id"
  return (Invoke-RestMethod -headers $GLPT -uri $GAPI_MILESTONES_ID -method PUT -ContentType 'application/json' -body $body)
}

# create a new group milestone
function New-GitlabGroupMilestone( [Parameter(Mandatory=$true)] [string] $group
                                 , [Parameter(Mandatory=$true)] [string] $title
                                 , [Parameter(Mandatory=$false)][string] $description
                                 , [Parameter(Mandatory=$false)][string] $start_date
                                 , [Parameter(Mandatory=$false)][string] $due_date
                                 )
{
  $body_json = @{ "title" = "$title" }

  if ($PSBoundParameters.ContainsKey('description')) {
    $body_json += @{ "description" = "$description" }
  }

  if ($PSBoundParameters.ContainsKey('start_date')) {
    $body_json += @{ "start_date" = "$start_date" }
  }

  if ($PSBoundParameters.ContainsKey('due_date')) {
    $body_json += @{ "due_date" = "$due_date" }
  }

  [string] $body = $body_json | ConvertTo-Json -depth 10

  [string] $GAPI_MILESTONES = "$CI_API_V4_URL/groups/$group/milestones"
  return (Invoke-RestMethod -headers $GLPT -uri $GAPI_MILESTONES -method POST -ContentType 'application/json' -body $body)
}

# delete a group milestone
function Remove-GitlabGroupMilestone( [Parameter(Mandatory=$true)] [string] $group
                                    , [Parameter(Mandatory=$true)]    [int] $id
                                    )
{
  [string] $GAPI_MILESTONES_ID = "$CI_API_V4_URL/groups/$group/milestones/$id"
  return (Invoke-RestMethod -headers $GLPT -uri $GAPI_MILESTONES_ID -method DELETE)
}


# ---------------------------------------------------------------------
# Project milestones API
# https://docs.gitlab.com/ee/api/milestones.html
function Get-GitlabMilestoneID( [Parameter(Mandatory=$true)] [string] $project
                              , [Parameter(Mandatory=$false)][string] $title
                              )
{
  if ([string]::IsNullOrWhiteSpace($title)) {
    return 0
  }

  # query project
  [string] $GAPI_MILESTONES = "$CI_API_V4_URL/projects/$project/milestones?title=$title"
  $milestone = Invoke-RestMethod -headers $GLPT -uri $GAPI_MILESTONES -method GET
  if ($milestone) { return $milestone[0].id }

  # query groups in reverse order
  [string] $group = $project
  do {
    # remove last subgroup entry
    $group = $group -replace '%2F[^%]+$'

    $GAPI_MILESTONES = "$CI_API_V4_URL/groups/$group/milestones?title=$title"
    $milestone = Invoke-RestMethod -headers $GLPT -uri $GAPI_MILESTONES -method GET

    if ($milestone) { return $milestone[0].id }
  } while ($group -cmatch '%2F')  # stop after top level group

  return 0
}