Module/DevOps/Update-BCSDevPipelineFiles.ps1

<#
.SYNOPSIS
  Update Azure Pipeline files from Template Project
 
.DESCRIPTION
  Update current.yml and build-settings.json from the project template repository and copy the files to your local project folder.
 
.PARAMETER PipelineFilesFolder
  Local folder where to your AL project
  
.PARAMETER Project
  DevOps project where the template repository exists, default is BrightCom Solutions
  
.PARAMETER TemplateRepository
  Name of the template project repository, default is BCS AL Project Template
  
.PARAMETER PipelineFilesSubFolder
  Path to local pipeline files, default is .azureDevOps
 
.PARAMETER PipelineFileName
  Name of the pipeline yaml file, default is current.yml
 
.PARAMETER PipelineBuildSettingsFileName
  Name of the pipeline build-settings file, default is build-settings.json
 
.PARAMETER ContainerName
  Name of the container that is created when the pipeline runs.
 
.PARAMETER DeployToTenant
  Tenant for where artifacts is to be deployed by the pipeline, must be a QA tenant.
 
.EXAMPLE
  Update-BCSDevPipelineFiles -PipelineFilesFolder C:\Projects\myAlProject -ContainerName myAlProject -DeployToTenant desenioqa
.NOTES
    Author: Mathias Stjernfelt
    Website: http://www.brightcom.se
#>


function Update-BCSDevPipelineFiles {
  Param (
    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)]
    [string]$PipelineFilesFolder,

    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)]
    [string]$Project = 'BrightCom Solutions',

    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)]
    [string]$TemplateRepository = 'BCS AL Project Template',
    
    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)]
    [string]$PipelineFilesSubFolder = '.azureDevOps',

    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)]
    [string]$PipelineFileName = 'Current.yml',
    
    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)]
    [string]$PipelineBuildSettingsFileName = 'Build-Settings.json',

    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)]
    [string]$ContainerName,

    [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)]
    [string]$DeployToTenant
  )

  try {
    $BaseURI = 'https://dev.azure.com/BrightComSolutions/';

    $TemplateRepositoryURI = ('{0}/{1}/_git/{2}' -f $BaseURI, $Project, $TemplateRepository);
    $Workfolder = ('{0}\{1}\{2}' -f $env:TEMP, $Project, $Repository);
    
    if (Test-Path -Path $Workfolder) {
      Remove-Item -Path $Workfolder -Recurse -Force;
    }

    $TemplateRepositoryURI = [uri]::EscapeUriString($TemplateRepositoryURI) 

    $RepositoryCloneFolder = ('{0}{1}' -f $Workfolder, '.Repo');

    git clone $TemplateRepositoryURI $RepositoryCloneFolder;

    $CurrentFilePath = ("{0}\{1}\{2}" -f $RepositoryCloneFolder, $PipelineFilesSubFolder, $PipelineFileName);
    $BuildSettingsFilePath = ("{0}\{1}\{2}" -f $RepositoryCloneFolder, $PipelineFilesSubFolder, $PipelineBuildSettingsFileName);

    Copy-Item -Path $CurrentFilePath -Destination $PipelineFilesFolder -Force 
    Copy-Item -Path $BuildSettingsFilePath -Destination $PipelineFilesFolder -Force

    $BuildSettingJson = Get-Content $BuildSettingsFilePath | ConvertFrom-Json
    # $BuildSettingJson = Get-Content C:\Temp\test\Build-Settings.json | ConvertFrom-Json
    
    $BuildSettingJson.name = $ContainerName;
    $BuildSettingJson.versions[0].ImageName = 'BC17';
    $BuildSettingJson.deployments[0].DeployToTenants = $DeployToTenant

    $BuildSettingJson | ConvertTo-Json | Format-Json | set-content "$PipelineFilesFolder\$PipelineBuildSettingsFileName"
  }
  catch {
    throw "An error occured: $_.Exception";
  }
}

function Format-Json {
  <#
  .SYNOPSIS
      Prettifies JSON output.
  .DESCRIPTION
      Reformats a JSON string so the output looks better than what ConvertTo-Json outputs.
  .PARAMETER Json
      Required: [string] The JSON text to prettify.
  .PARAMETER Minify
      Optional: Returns the json string compressed.
  .PARAMETER Indentation
      Optional: The number of spaces (1..1024) to use for indentation. Defaults to 4.
  .PARAMETER AsArray
      Optional: If set, the output will be in the form of a string array, otherwise a single string is output.
  .EXAMPLE
      $json | ConvertTo-Json | Format-Json -Indentation 2
  #>

  [CmdletBinding(DefaultParameterSetName = 'Prettify')]
  Param(
    [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
    [string]$Json,

    [Parameter(ParameterSetName = 'Minify')]
    [switch]$Minify,

    [Parameter(ParameterSetName = 'Prettify')]
    [ValidateRange(1, 1024)]
    [int]$Indentation = 4,

    [Parameter(ParameterSetName = 'Prettify')]
    [switch]$AsArray
  )

  if ($PSCmdlet.ParameterSetName -eq 'Minify') {
    return ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100 -Compress
  }

  # If the input JSON text has been created with ConvertTo-Json -Compress
  # then we first need to reconvert it without compression
  if ($Json -notmatch '\r?\n') {
    $Json = ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100
  }

  $indent = 0
  $regexUnlessQuoted = '(?=([^"]*"[^"]*")*[^"]*$)'

  $result = $Json -split '\r?\n' |
  ForEach-Object {
    # If the line contains a ] or } character,
    # we need to decrement the indentation level unless it is inside quotes.
    if ($_ -match "[}\]]$regexUnlessQuoted") {
      $indent = [Math]::Max($indent - $Indentation, 0)
    }

    # Replace all colon-space combinations by ": " unless it is inside quotes.
    $line = (' ' * $indent) + ($_.TrimStart() -replace ":\s+$regexUnlessQuoted", ': ')

    # If the line contains a [ or { character,
    # we need to increment the indentation level unless it is inside quotes.
    if ($_ -match "[\{\[]$regexUnlessQuoted") {
      $indent += $Indentation
    }

    $line
  }

  if ($AsArray) { return $result }
  return $result -Join [Environment]::NewLine
}

Export-ModuleMember -Function Update-BCSDevPipelineFiles