Invoke-Metadata.ps1

<#PSScriptInfo
 
.VERSION 1.4.0
 
.GUID eb246b19-17da-4392-8c89-7c280f69ad0e
 
.AUTHOR arnold.sikorski@pl.abb.com
 
.COMPANYNAME
 
.COPYRIGHT
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
#>


<#
 
.DESCRIPTION
 Script for generating
 
#>


# Publish-Script -Path -NuGetApiKey
# The trick: if it is not called by Invoke-Build then recall and return.
param (
    [Parameter(Position = 0)]
    $Tasks,
    [Parameter(Mandatory = $false)]
    $OutputPath,

    [Parameter(Mandatory = $false)]
    $ProjectPath
)

if (-not $ProjectPath ) {
    $ProjectPath =  Resolve-Path  (Get-Location).Path
}

if (-not $OutputPath ) {
    $OutputPath = (Join-Path $ProjectPath Output)
}
if (-not $DependenciesPath ) {
    $DependenciesPath = (Join-Path $PSScriptRoot Dependencies)
}

$MetadataPath = Resolve-Path $ProjectPath\*.metadata.json
if (-not (Test-Path $MetadataPath)) 
{
    throw [System.IO.FileNotFoundException] "$MetadataPath not found."
}


$defaultDependencyTags = @("dev")
$defaultPsDependVersion = '0.1.62'

$MetadataTemplate = Get-Content $MetadataPath | Out-String | ConvertFrom-Json

# NOTE: Inline invocation of Invoke-Build, before let's install all dependencies
if ([System.IO.Path]::GetFileName($MyInvocation.ScriptName) -ne 'Invoke-Build.ps1') {

    $defaultPsDependConfiguration = @{
        PSDependOptions = @{
            AddToPath = $true
        }
    
        InvokeBuild     = @{
            Version        = '4.1.0'
            Tags           = 'dev', 'prod'
            DependencyType = 'PSGalleryModule'
        }
        EPS             = @{
            Version        = '0.5.0'
            Tags           = 'dev'
            DependencyType = 'PSGalleryModule'
        }
        Pester          = @{
            Version        = '4.1.0'
            Tags           = 'dev'
            DependencyType = 'PSGalleryModule'
        }
        BuildHelpers    = @{
            Version        = '1.0.0'
            Tags           = 'dev', 'prod'
            DependencyType = 'PSGalleryModule'
        }
    }
    
    if (-not(Get-InstalledModule PSDepend -RequiredVersion $defaultPsDependVersion -ErrorAction SilentlyContinue)) {
        Install-Module PSDepend -RequiredVersion $defaultPsDependVersion -Force -Scope CurrentUser
    }
    # -ProjectPath (Get-Location).Path
    
    Import-Module PSDepend -RequiredVersion $defaultPsDependVersion
    Invoke-PSDepend -InputObject $defaultPsDependConfiguration  -Install -Import -Force -Target $DependenciesPath -Tags $defaultDependencyTags -ErrorAction SilentlyContinue
    Invoke-Build $Tasks $MyInvocation.MyCommand.Path @PSBoundParameters  -Result result
    if ($Result.Error) {exit 1} else {exit 0}

}

# NOTE: Defoult tasks chain
Task default UpdateConfiguration, Metadata, Csproj, Changelog

# NOTE: Update configuration
Task UpdateConfiguration {
    Set-Content $ProjectPath\GitVersion.yml @"
branches:
    master:`
      mode: ContinuousDeployment
      tag: stable
      increment: None
      prevent-increment-of-merged-branch-version: true
      track-merge-target: false
    release:
      mode: ContinuousDeployment
      tag: release
      increment: None
      prevent-increment-of-merged-branch-version: true
      track-merge-target: false
    (pull|pull\-requests|pr)[/-]:
      mode: ContinuousDeployment
      tag: pr
      increment: None
      prevent-increment-of-merged-branch-version: false
      tag-number-pattern: '[/-](?<number>\d+)[-/]'
      track-merge-target: false
    hotfix(es)?[/-]:
      mode: ContinuousDeployment
      tag: hotfix
      increment: None
      prevent-increment-of-merged-branch-version: false
      track-merge-target: false
    support[/-]:
      mode: ContinuousDeployment
      tag: support
      increment: None
      prevent-increment-of-merged-branch-version: true
      track-merge-target: false
    develop:
      mode: ContinuousDeployment
      tag: develop
      increment: None
      prevent-increment-of-merged-branch-version: false
      track-merge-target: true
"@


}
# NOTE: Generate metadata
Task Metadata {
    Set-Location $ProjectPath
    $CurrentTime = Get-Date -Format "MM-dd-yyyy-hh-mm-ss"

    $GitVersionVars = ConvertFrom-Json ( GitVersion.exe | Out-String)
    $Script:Metadata = [PSCustomObject]@{
        Name      = $MetadataTemplate.Name
        Version   = if ($GitVersionVars.FullSemVer) {$GitVersionVars.FullSemVer} else {"none"};
        Build     = [PSCustomObject] @{
            Time              = $CurrentTime
            BuildId           = if ($env:BUILD_BUILDID) {$env:BUILD_BUILDID} else {"none"};
            DefinitionName    = if ($env:BUILD_DEFINITIONNAME) {$env:BUILD_DEFINITIONNAME} else {"none"};
            BuildNumber       = if ($env:BUILD_BUILDNUMBER) {$env:BUILD_BUILDNUMBER} else {"none"};
            DefinitionVersion = if ($env:BUILD_DEFINITIONVERSION) {$env:BUILD_DEFINITIONVERSION} else {"none"};
            QueuedBy          = if ($env:BUILD_QUEUEDBY) {$env:BUILD_QUEUEDBY} else {"none"};
            RepositoryUri     = if ($env:BUILD_REPOSITORY_URI) {$env:BUILD_REPOSITORY_URI} else {"none"};
            TeamProject       = if ($env:SYSTEM_TEAMPROJECT) {$env:SYSTEM_TEAMPROJECT} else {"none"};
            BuildReason       = if ($env:RELEASE_ENVIRONMENTNAME) {$env:RELEASE_ENVIRONMENTNAME} else {"none"};
            AgentName         = if ($env:AGENT_NAME) {$env:AGENT_NAME} else {"none"};
        }
        SemVer    = $GitVersionVars
        Resources = $MetadataTemplate.Resources
    }

    $MetadataAsJson = $Metadata | ConvertTo-Json -depth 100 
    $MetadataFileName = Split-Path $MetadataPath -leaf
    $MetadataOutputFile = (Join-Path $OutputPath  $MetadataFileName) 
    Write-Verbose ("MetadataAsJson: {0}" -f $MetadataAsJson) -Verbose

    $MetadataAsJson | Out-File $MetadataOutputFile -Force
    Write-Verbose ("Metadata saved to: [{0}]" -f $MetadataOutputFile) -Verbose

    Write-Host "##vso[task.setvariable variable=MetadataOutputFile;]$MetadataOutputFile"
}
# NOTE: Generate changelog file
Task Changelog {
    Set-Location $ProjectPath
    $ChangelogFile = (Join-Path $OutputPath CHANGELOG.md)
    exec {
        conventional-changelog -p angular -i $ChangelogFile -s -r 0
    }
    Write-Build Green "ChangelogFile: $ChangelogFile"
    Write-Host "##vso[task.setvariable variable=ChangelogFile;]$ChangelogFile"

}
# NOTE: Set version and update all csproj files
Task Csproj {
    # Update Version element in each csproj
    Set-Location $ProjectPath
    Get-ChildItem -Recurse -Filter *.csproj -File |
        ForEach-Object {
        [xml]$CsProjectName = Get-Content $_.FullName
        $Version = $CsProjectName.SelectSingleNode('//Version[last()]')
        if ($Version) {
            $Version.InnerText = $metadata.Version
            $CsProjectName.Save($_.FullName)
        }
    }
}