Private/New-PesterYamlFile.ps1

function New-PesterYamlFile {
  <#
  .SYNOPSIS
    Creates a YAML file for an Azure DevOps Pester testing pipeline.
 
  .DESCRIPTION
    This function automates the creation of a YAML file suitable for configuring a Pester testing
    pipeline within Azure DevOps. The generated YAML includes trigger, path, and task definitions,
    and it handles the installation of the Pester module if required.
 
  .PARAMETER Path
    Required. Specifies the absolute path where the YAML file will be created.
 
  .PARAMETER Name
    Required. The name of the module, used within the YAML file's configuration.
 
  .PARAMETER DevOpsPath
    Required. The relative path to the module folder within the DevOps repository.
 
  .EXAMPLE
    New-PesterYamlFile -Path C:\MyProject\CI -Name MyModule -RelativePath Modules
    This creates a file named "MyModule_Pester_Pipeline.yaml" in the "C:\MyProject\CI" directory.
 
  .NOTES
    Author: owen.heaume
    Version: 1.0.0 - Initial release
              1.0.1 - Change 'DevopsPath' to 'RelativePath'
  #>



  Param(
    [Parameter(Mandatory)]
    [string] $Path,

    [Parameter(Mandatory)]
    [string] $Name,

    [Parameter(Mandatory)]
    [string] $RelativePath
  )

  # Construct the full file path
  try {
    $yamlFilePath = Join-Path -Path "$Path\$name" -ChildPath "$($Name)_Pester_Pipeline.yaml" -ea Stop
  } catch {
    throw "Error joining path: $_"
  }

  # Here-string for YAML content (indentation is essential)
  $yamlContent = @"
trigger:
  branches:
    include:
      - main
  paths:
    include:
      - '$($RelativePath.replace('\', '/'))/$Name/$name/private/*'
      - '$($RelativePath.replace('\', '/'))/$Name/$name/public/*'
 
pool:
  vmImage: 'windows-latest'
 
steps:
- powershell: |
    # Path to the Pester configuration file
    `$pesterConfigFile = '`$(System.DefaultWorkingDirectory)/$($RelativePath.replace('\', '/'))/$Name/test.ps1'
 
    # Check if configuration file exists
    if (Test-Path `$pesterConfigFile) {
      # Install Pester (if necessary)
      if (-not (Get-Module -ListAvailable -Name Pester)) {
      Install-Module -Name Pester -Force -Scope CurrentUser
      }
 
      # Run Pester tests
      `$testResults = Invoke-Pester -Path `$pesterConfigFile -output detailed
 
      # Fail build if any tests fail
      if (`$testResults.FailedCount -gt 0) {
      Write-Host "Tests failed! Failing the build."
      exit 1
      } else {
      Write-Host "All Pester tests passed!"
      }
    } else {
      Write-Host "Pester configuration file not found."
    }
  displayName: 'Run Pester Tests'
 
- task: PublishCodeCoverageResults@1
  displayName: 'Publish Code Coverage Results'
  inputs:
    codeCoverageTool: 'JaCoCo'
    summaryFileLocation: '`$(System.DefaultWorkingDirectory)/$($RelativePath.replace('\', '/'))/$Name/coverage.xml'
    pathToSources: '`$(System.DefaultWorkingDirectory)/$($RelativePath.replace('\', '/'))/$Name/$Name/Public;`$(System.DefaultWorkingDirectory)/$($RelativePath.replace('\', '/'))/$Name/$Name/Private'
"@


  # Create the YAML file
  try {
    Write-Host "Creating YAML file: $yamlFilePath" -ForegroundColor DarkCyan
    if (Test-Path $yamlFilePath) {
      Write-Host 'YAML file already exists' -ForegroundColor DarkYellow
    } else {
      $yamlContent | Out-File -FilePath $yamlFilePath -ea Stop
      Write-Host 'YAML file created successfully' -ForegroundColor DarkGreen
    }
  } catch {
    throw "Error writing YAML file: $_"
  }
}