From 42e945ad952a20b0569982209acaa540d6948772 Mon Sep 17 00:00:00 2001 From: markekraus Date: Sat, 4 Mar 2017 19:03:48 -0600 Subject: [PATCH] Merge from dev --- .gitattributes | 1 - PSMSGraph/Public/Get-AADGroupMember.ps1 | 5 +- RELEASE.md | 47 ++++ Tests/Help.Tests.ps1 | 28 +- Tests/New-GraphApplication.Unit.Tests.ps1 | 61 ++++ .../New-GraphOauthAccessToken.Unit.Tests.ps1 | 83 ++++++ Tests/PSScriptAnalyzer.Tests.ps1 | 34 +++ Tests/Project.Tests.ps1 | 22 +- appveyor.yml | 12 - build.ps1 | 6 +- psake.ps1 | 261 +++++++++++++++--- 11 files changed, 468 insertions(+), 92 deletions(-) delete mode 100644 .gitattributes create mode 100644 RELEASE.md create mode 100644 Tests/New-GraphApplication.Unit.Tests.ps1 create mode 100644 Tests/New-GraphOauthAccessToken.Unit.Tests.ps1 create mode 100644 Tests/PSScriptAnalyzer.Tests.ps1 diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 9e6dcef..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.psd1 merge=ours diff --git a/PSMSGraph/Public/Get-AADGroupMember.ps1 b/PSMSGraph/Public/Get-AADGroupMember.ps1 index 5b35395..402a6c8 100644 --- a/PSMSGraph/Public/Get-AADGroupMember.ps1 +++ b/PSMSGraph/Public/Get-AADGroupMember.ps1 @@ -40,6 +40,7 @@ function Get-AADGroupMember { [CmdletBinding(SupportsShouldProcess = $true, HelpUri = 'http://psmsgraph.readthedocs.io/en/latest/functions/Get-AADGroupMember')] [OutputType('MSGraphAPI.DirectoryObject.User')] + [Alias('Get-AADGroupMembers')] param ( [Parameter(Mandatory = $true, @@ -101,6 +102,4 @@ function Get-AADGroupMember { while ($SkipToken) } } -} - -New-Alias -Name Get-AADGroupMembers -Value Get-AADGroupMember -Description "Alias for Get-AADGroupMember" \ No newline at end of file +} \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..5d3686c --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,47 @@ +# Version 1.0.24.17 (2017-03-05) +## Functions +### All +* Added HelpUri and .LINK's to Comment based Help + +### OAuth functions +* Standardized on "Oauth" in the function and file names (was a mix of "OAuth" and "Oath") + +### Get-AADGroupMember +* Made function singular instead of plural (was Get-AADGroupMembers) +* Added Get-AADGroupMembers alias +* Fixed all the millions of problems this rename caused + +## Build Tools +### psake.ps1 +* Restructured psake.ps1 + - Init > UnitTests > Build > Test > BuildDocs > Deploy > Post Deploy +* Added AST based Function and Alias module manifest population +* Added NestedModule Population +* Added Release notes and change log auto processing and documentation +* PostDeploy is now local build friendly + +## Tests +### PSScriptAnalyzer.tests.Ps1 +* Moved out of Project.Tests.ps1 +* Re-wroded the tests so they display better in AppVeyor test logs +* Removed .psd1 from the tests because it dose not appear to support suppression and certain test will falsely fail due to the text in RealseNotes + +### Project.Tests.ps1 +* Moved the PSScriptAnalyzer tests to PSScriptAnalyzer.tests.Ps1 +* Added Unit tag to "General project validation" so it test before and after build + +### New-GraphApplication.Unit.Tests.ps1 +* Added Unit test for New-GraphApplication + +### New-GraphOauthAccessToken.Unit.Tests.ps1 +* Added Unit test for New-GraphOauthAccessToken + +## Project +### RELEASE.md +* Added this to server as the current release notes +* Integrates automatically with ChangeLog.md through build pipeline +* Gets copied to ```docs/``` + +### ChangeLog.md +* Added to ```docs/``` +* Automatically managed by build process diff --git a/Tests/Help.Tests.ps1 b/Tests/Help.Tests.ps1 index 8e2d324..8e06aac 100644 --- a/Tests/Help.Tests.ps1 +++ b/Tests/Help.Tests.ps1 @@ -5,24 +5,28 @@ $moduleName = Split-Path $moduleRoot -Leaf Import-Module (Join-Path $moduleRoot "$moduleName.psd1") -force Describe "Help tests for $moduleName" -Tags Build { - + $functions = Get-Command -Module $moduleName -CommandType Function - $help = $functions | %{Get-Help $_.name} - foreach($node in $help) - { - Context $node.name { - - it "has a description" { - $node.description | Should Not BeNullOrEmpty + foreach($Function in $Functions){ + $help = Get-Help $Function.name + Context $help.name { + it "Has a HelpUri" { + $Function.HelpUri | Should Not BeNullOrEmpty + } + It "Has related Links" { + $help.relatedLinks.navigationLink.uri.count | Should BeGreaterThan 0 + } + it "Has a description" { + $help.description | Should Not BeNullOrEmpty } - it "has an example" { - $node.examples | Should Not BeNullOrEmpty + it "Has an example" { + $help.examples | Should Not BeNullOrEmpty } - foreach($parameter in $node.parameters.parameter) + foreach($parameter in $help.parameters.parameter) { if($parameter -notmatch 'whatif|confirm') { - it "parameter $($parameter.name) has a description" { + it "Has a Parameter description for '$($parameter.name)'" { $parameter.Description.text | Should Not BeNullOrEmpty } } diff --git a/Tests/New-GraphApplication.Unit.Tests.ps1 b/Tests/New-GraphApplication.Unit.Tests.ps1 new file mode 100644 index 0000000..da63f1d --- /dev/null +++ b/Tests/New-GraphApplication.Unit.Tests.ps1 @@ -0,0 +1,61 @@ +<# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.135 + Created on: 2/27/2017 4:42 AM + Created by: Mark Kraus + Organization: + Filename: + =========================================================================== + .DESCRIPTION + Unit Tests for New-GraphApplication +#> + +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") +$moduleName = Split-Path $moduleRoot -Leaf +Import-Module (Join-Path $moduleRoot "$moduleName.psd1") -force + +$Command = 'New-GraphApplication' + +$TypeName = 'MSGraphAPI.Application' +$ClientID = '12345' +$ClientSecret = '54321' +$SecClientSecret = $ClientSecret | ConvertTo-SecureString -AsPlainText -Force +$ClientCredential = [system.Management.Automation.PSCredential]::new($ClientID, $SecClientSecret) + +$Params = @{ + Name = 'Unit Test Application' + Description = 'This is a test of the emergency broadcast system' + ClientCredential = $ClientCredential + GUID = 'e2ad918e-dc87-4c23-803c-e67e43e0f217' + RedirectUri = 'https://localhost' + Tenant = 'adatum.onmicrosoft.com' +} +$RequiredParams = @( + 'Tenant' + 'Name' + 'ClientCredential' + 'RedirectUri' +) +Describe $Command -Tags Unit { + It 'Does not have errors when passed required parameters' { + $LocalParams = $Params.psobject.Copy() + { & $Command @LocalParams -ErrorAction Stop } | Should not throw + } + Foreach ($RequiredParam in $RequiredParams) { + It "Requires the $RequiredParam parameter" { + ((Get-Command $Command).Parameters[$RequiredParam].Attributes | + Where-Object { $_ -is [parameter] }).Mandatory | + Should be $true + } + } + It "Emits a $TypeName Object" { + (Get-Command $Command).OutputType.Name.where({ $_ -eq $TypeName }) | Should be $TypeName + } + It "Creates a $TypeName Object" { + $LocalParams = $Params.psobject.Copy() + $Object = & $Command @LocalParams -ErrorAction SilentlyContinue | Select-Object -First 1 + $Object.psobject.typenames.where({ $_ -eq $TypeName }) | Should be $TypeName + } +} \ No newline at end of file diff --git a/Tests/New-GraphOauthAccessToken.Unit.Tests.ps1 b/Tests/New-GraphOauthAccessToken.Unit.Tests.ps1 new file mode 100644 index 0000000..4be6b62 --- /dev/null +++ b/Tests/New-GraphOauthAccessToken.Unit.Tests.ps1 @@ -0,0 +1,83 @@ +<# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.135 + Created on: 2/27/2017 4:42 AM + Created by: Mark Kraus + Organization: + Filename: + =========================================================================== + .DESCRIPTION + Unit Tests for New-GraphOauthAccessToken +#> + +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") +$moduleName = Split-Path $moduleRoot -Leaf +Import-Module (Join-Path $moduleRoot "$moduleName.psd1") -force + +$Command = 'New-GraphOauthAccessToken' + +$TypeName = 'MSGraphAPI.Oauth.AccessToken' +$ClientID = '12345' +$ClientSecret = '54321' +$SecClientSecret = $ClientSecret | ConvertTo-SecureString -AsPlainText -Force +$ClientCredential = [system.Management.Automation.PSCredential]::new($ClientID, $SecClientSecret) +$Params = @{ + Name = 'Unit Test Application' + Description = 'This is a test of the emergency broadcast system' + ClientCredential = $ClientCredential + GUID = 'e2ad918e-dc87-4c23-803c-e67e43e0f217' + RedirectUri = 'https://localhost' + Tenant = 'adatum.onmicrosoft.com' +} +$App = New-GraphApplication @Params + +$AToken = '67890' +$SecAtoken = $Atoken | ConvertTo-SecureString -AsPlainText -Force +$AccessTokenCredential = [system.Management.Automation.PSCredential]::new('access_token', $SecAtoken) +$Rtoken = '09876' +$SecRtoken = $Rtoken | ConvertTo-SecureString -AsPlainText -Force +$RefreshTokenCredential = [system.Management.Automation.PSCredential]::new('refresh_token', $SecRtoken) + +$Params = @{ + 'Application' = $App + 'AccessTokenCredential' = $AccessTokenCredential + 'RefreshTokenCredential' = $RefreshTokenCredential + 'RequestedDate' = Get-Date + 'Response' = [pscustomobject]@{TestResponse = 'Test'} + 'ResponseHeaders' = [pscustomobject]@{ TestHeaders = 'Test' } + 'LastRequestDate' = get-date + 'GUID' = '1c6e3c87-8f77-435c-911d-3e97588918d0' + 'Session' = [Microsoft.PowerShell.Commands.WebRequestSession]::new() +} +$RequiredParams = @( + 'Application' + 'AccessTokenCredential' + 'RefreshTokenCredential' + 'RequestedDate' + 'Response' + 'ResponseHeaders' + 'LastRequestDate' +) +Describe $Command -Tags Unit { + It 'Does not have errors when passed required parameters' { + $LocalParams = $Params.psobject.Copy() + { & $Command @LocalParams -ErrorAction Stop } | Should not throw + } + Foreach ($RequiredParam in $RequiredParams) { + It "Requires the $RequiredParam parameter" { + ((Get-Command $Command).Parameters[$RequiredParam].Attributes | + Where-Object { $_ -is [parameter] }).Mandatory | + Should be $true + } + } + It "Emits a $TypeName Object" { + (Get-Command $Command).OutputType.Name.where({ $_ -eq $TypeName }) | Should be $TypeName + } + It "Creates a $TypeName Object" { + $LocalParams = $Params.psobject.Copy() + $Object = & $Command @LocalParams -ErrorAction SilentlyContinue | Select-Object -First 1 + $Object.psobject.typenames.where({ $_ -eq $TypeName }) | Should be $TypeName + } +} \ No newline at end of file diff --git a/Tests/PSScriptAnalyzer.Tests.ps1 b/Tests/PSScriptAnalyzer.Tests.ps1 new file mode 100644 index 0000000..dba52a9 --- /dev/null +++ b/Tests/PSScriptAnalyzer.Tests.ps1 @@ -0,0 +1,34 @@ +<# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.135 + Created on: 2/28/2017 11:49 AM + Editied on: 3/4/2017 + Created by: Mark Kraus + Organization: + Filename: PSScriptAnalyzer.tests.Ps1 + =========================================================================== + .DESCRIPTION + Runs PSScriptAnalyzer tests for every rule against every file in the module +#> +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") +$moduleName = Split-Path $moduleRoot -Leaf + +Describe "PSScriptAnalyzer Tests" -Tags Build { + + $Rules = Get-ScriptAnalyzerRule + $scripts = Get-ChildItem $moduleRoot -Include *.ps1, *.psm1 -Recurse | Where-Object fullname -notmatch 'classes' + + foreach ($Script in $scripts) { + $RelPath = $Script.FullName.Replace($moduleRoot, '') -replace '^\\', '' + Context "$RelPath" { + foreach ($rule in $rules) { + It "Passes $rule" { + + (Invoke-ScriptAnalyzer -Path $script.FullName -IncludeRule $rule.RuleName).Count | Should Be 0 + } + } + } + } +} \ No newline at end of file diff --git a/Tests/Project.Tests.ps1 b/Tests/Project.Tests.ps1 index 1216e20..484d247 100644 --- a/Tests/Project.Tests.ps1 +++ b/Tests/Project.Tests.ps1 @@ -2,27 +2,7 @@ $projectRoot = Resolve-Path "$PSScriptRoot\.." $moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") $moduleName = Split-Path $moduleRoot -Leaf - -Describe "Testing all Script against default PSScriptAnalyzer rule-set" { - - $Rules = Get-ScriptAnalyzerRule - $scripts = Get-ChildItem $moduleRoot -Include *.ps1, *.psm1, *.psd1 -Recurse | where fullname -notmatch 'classes' - - foreach ($Script in $scripts) { - Context "Testing Script '$($script.FullName)'" { - - foreach ($rule in $rules) { - It "passes the PSScriptAnalyzer Rule [$rule]" { - - (Invoke-ScriptAnalyzer -Path $script.FullName -IncludeRule $rule.RuleName).Count | Should Be 0 - } - } - } - } -} - - -Describe "General project validation: $moduleName" -Tags Build { +Describe "General project validation: $moduleName" -Tags Build, Unit { It "Module '$moduleName' can import cleanly" { { Import-Module (Join-Path $moduleRoot "$moduleName.psm1") -force } | Should Not Throw diff --git a/appveyor.yml b/appveyor.yml index fbfd153..4085b52 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,15 +19,3 @@ build: false #Kick off the CI/CD pipeline test_script: - ps: . .\build.ps1 - -on_success: - - git config --global credential.helper store - - ps: Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:access_token):x-oauth-basic@github.com`n" - - git config --global user.email "appveyor-psmsgraph-github@markekraus.com" - - git config --global user.name "markekraus" - - git config --global core.autocrlf true - - git checkout master - - git add -A - - git commit -m "appveyor post-build commit[ci skip]" - - git status - - git push \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index 1ba6271..98036d4 100644 --- a/build.ps1 +++ b/build.ps1 @@ -3,11 +3,11 @@ param ($Task = 'Default') # Grab nuget bits, install modules, set build variables, start build. Get-PackageProvider -Name NuGet -ForceBootstrap | Out-Null -Install-Module Psake, PSDeploy, BuildHelpers, platyPS -force +Install-Module Psake, PSDeploy, BuildHelpers, platyPS, PSScriptAnalyzer -force Install-Module Pester -Force -SkipPublisherCheck -Import-Module Psake, BuildHelpers, platyPS +Import-Module Psake, BuildHelpers, platyPS, PSScriptAnalyzer Set-BuildEnvironment Invoke-psake -buildFile .\psake.ps1 -taskList $Task -nologo -exit ( [int]( -not $psake.build_success ) ) \ No newline at end of file +exit ([int](-not $psake.build_success)) \ No newline at end of file diff --git a/psake.ps1 b/psake.ps1 index bf87676..2fd0f5b 100644 --- a/psake.ps1 +++ b/psake.ps1 @@ -6,19 +6,28 @@ Properties { if (-not $ProjectRoot) { $ProjectRoot = $PSScriptRoot } - - $Timestamp = Get-date -uformat "%Y%m%d-%H%M%S" + $ModuleFolder = Split-Path -Path $ENV:BHPSModuleManifest -Parent $PSVersion = $PSVersionTable.PSVersion.Major $TestFile = "TestResults_PS$PSVersion`_$TimeStamp.xml" $lines = '----------------------------------------------------------------------' - $Verbose = @{ } if ($ENV:BHCommitMessage -match "!verbose") { $Verbose = @{ Verbose = $True } } + $CurrentVersion = [version](Get-Metadata -Path $env:BHPSModuleManifest) + $StepVersion = [version] (Step-Version $CurrentVersion) + $GalleryVersion = Get-NextPSGalleryVersion -Name $env:BHProjectName + $BuildVersion = $StepVersion + If ($GalleryVersion -gt $StepVersion) { + $BuildVersion = $GalleryVersion + } + $BuildVersion = [version]::New($BuildVersion.Major, $BuildVersion.Minor, $BuildVersion.Build, $env:BHBuildNumber) + $BuildDate = Get-Date -uFormat '%Y-%m-%d' + $ReleaseNotes = "$ProjectRoot\RELEASE.md" + $ChangeLog = "$ProjectRoot\docs\ChangeLog.md" } -Task Default -Depends Deploy +Task Default -Depends PostDeploy Task Init { $lines @@ -26,25 +35,124 @@ Task Init { "Build System Details:" Get-Item ENV:BH* | Format-List "`n" + "Current Version: $CurrentVersion`n" + "Build Version: $BuildVersion`n" } Task UnitTests -Depends Init { $lines - 'Running quick unit tests to fail early if there is an error' - $TestResults = Invoke-Pester -Path $ProjectRoot\Tests\*unit* -PassThru -Tag Build - + "Running Pre-build unit tests`n" + $Timestamp = Get-date -uformat "%Y%m%d-%H%M%S" + $TestFile = "TestResults_PS$PSVersion`_$TimeStamp.xml" + $Parameters = @{ + Script = "$ProjectRoot\Tests" + PassThru = $true + Tag = 'Unit' + OutputFormat = 'NUnitXml' + OutputFile = "$ProjectRoot\$TestFile" + } + $TestResults =Invoke-Pester @Parameters if ($TestResults.FailedCount -gt 0) { Write-Error "Failed '$($TestResults.FailedCount)' tests, build failed" } "`n" + If ($ENV:BHBuildSystem -eq 'AppVeyor') { + "Uploading $ProjectRoot\$TestFile to AppVeyor" + "JobID: $env:APPVEYOR_JOB_ID" + (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path "$ProjectRoot\$TestFile")) + } + Remove-Item "$ProjectRoot\$TestFile" -Force -ErrorAction SilentlyContinue } -Task Test -Depends UnitTests { +Task Build -Depends UnitTests { + $lines + + "Populating AliasesToExport and FunctionsToExport" + # Load the module, read the exported functions and aliases, update the psd1 + $FunctionFiles = Get-ChildItem "$ModuleFolder\Public\*.ps1" | + Where-Object{ $_.name -notmatch 'Tests' } + $ExportFunctions = @() + $ExportAliases = @() + foreach ($FunctionFile in $FunctionFiles) { + $AST = [System.Management.Automation.Language.Parser]::ParseFile($FunctionFile.FullName, [ref]$null, [ref]$null) + $Functions = $AST.FindAll({ + $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] + }, $true) + if ($Functions.Name) { + $ExportFunctions += $Functions.Name + } + $Aliases = $AST.FindAll({ + $args[0] -is [System.Management.Automation.Language.AttributeAst] -and + $args[0].parent -is [System.Management.Automation.Language.ParamBlockAst] -and + $args[0].TypeName.FullName -eq 'alias' + }, $true) + if ($Aliases.PositionalArguments.value) { + $ExportAliases += $Aliases.PositionalArguments.value + } + } + Set-ModuleFunctions -Name $env:BHPSModuleManifest -FunctionsToExport $ExportFunctions + Update-Metadata -Path $env:BHPSModuleManifest -PropertyName AliasesToExport -Value $ExportAliases + + "Populating NestedModules" + # Scan the Public and Private folders and add all Files to NestedModules + # I prefer to populate this instead of dot sourcing from the .psm1 + $Parameters = @{ + Path = @( + "$ModuleFolder\Public\*.ps1" + "$ModuleFolder\Private\*.ps1" + ) + ErrorAction = 'SilentlyContinue' + } + $ExportModules = Get-ChildItem @Parameters | + Where-Object { $_.Name -notmatch '\.tests{0,1}\.ps1' } | + ForEach-Object { $_.fullname.replace("$ModuleFolder\", "") } + Update-Metadata -Path $env:BHPSModuleManifest -PropertyName NestedModules -Value $ExportModules + + # Bump the module version + Update-Metadata -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -Value $BuildVersion + + # Update release notes with Version info and set the PSD1 release notes + $parameters = @{ + Path = $ReleaseNotes + ErrorAction = 'SilentlyContinue' + } + $ReleaseText = (Get-Content @parameters | Where-Object {$_ -notmatch '^# Version '}) -join "`r`n" + if (-not $ReleaseText) { + "Skipping realse notes`n" + "Consider adding a RELEASE.md to your project.`n" + return + } + $Header = "# Version {0} ({1})`r`n" -f $BuildVersion, $BuildDate + $ReleaseText = $Header + $ReleaseText + $ReleaseText | Set-Content $ReleaseNotes + Update-Metadata -Path $env:BHPSModuleManifest -PropertyName ReleaseNotes -Value $ReleaseText + + # Update the ChangeLog with the current release notes + $releaseparameters = @{ + Path = $ReleaseNotes + ErrorAction = 'SilentlyContinue' + } + $changeparameters = @{ + Path = $ChangeLog + ErrorAction = 'SilentlyContinue' + } + (Get-Content @releaseparameters),"`r`n`r`n", (Get-Content @changeparameters) | Set-Content $ChangeLog +} + +Task Test -Depends Build { $lines "`n`tSTATUS: Testing with PowerShell $PSVersion" # Gather test results. Store them in a variable and file - $TestResults = Invoke-Pester -Path $ProjectRoot\Tests -PassThru -OutputFormat NUnitXml -OutputFile "$ProjectRoot\$TestFile" -Tag Build + $Timestamp = Get-date -uformat "%Y%m%d-%H%M%S" + $TestFile = "TestResults_PS$PSVersion`_$TimeStamp.xml" + $parameters = @{ + Script = "$ProjectRoot\Tests" + PassThru = $true + OutputFormat = 'NUnitXml' + OutputFile = "$ProjectRoot\$TestFile" + } + $TestResults = Invoke-Pester @parameters # In Appveyor? Upload our tests! #Abstract this into a function? If ($ENV:BHBuildSystem -eq 'AppVeyor') { @@ -63,45 +171,44 @@ Task Test -Depends UnitTests { "`n" } -Task Build -Depends Test { +Task BuildDocs -depends Test { $lines - $functions = Get-ChildItem "$PSScriptRoot\$env:BHProjectName\Public\*.ps1" | - Where-Object{ $_.name -notmatch 'Tests' } | - Select-Object -ExpandProperty basename - - # Load the module, read the exported functions, update the psd1 FunctionsToExport - Set-ModuleFunctions -Name $env:BHPSModuleManifest -FunctionsToExport $functions - - # Bump the module version - $version = [version] (Step-Version (Get-Metadata -Path $env:BHPSModuleManifest)) - $galleryVersion = Get-NextPSGalleryVersion -Name $env:BHProjectName - if ($version -lt $galleryVersion) { - $version = $galleryVersion - } - $version = [version]::New($version.Major, $version.Minor, $version.Build, $env:BHBuildNumber) - Write-Host "Using version: $version" - - Update-Metadata -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -Value $version -} - -Task BuildDocs -depends Build { - $lines - - $moduleRoot = Split-Path (Resolve-Path "$ProjectRoot\*\*.psd1") - $moduleName = Split-Path $moduleRoot -Leaf - $psd1 = Join-Path $moduleRoot "$moduleName.psd1" - Write-Host "Loading Module from $psd1" + "Loading Module from $ENV:BHPSModuleManifest" Remove-Module $ENV:BHProjectName -Force -ea SilentlyContinue - Import-Module $psd1 -force -Global + # platyPS + AppVeyor requires the module to be loaded in Global scope + Import-Module $ENV:BHPSModuleManifest -force -Global + + #Build YAMLText starting with the header $YMLtext = (Get-Content "$ProjectRoot\header-mkdocs.yml") -join "`n" - $YMLText = "$YMLtext`n - Functions:`n" + $YMLtext = "$YMLtext`n" + $parameters = @{ + Path = $ReleaseNotes + ErrorAction = 'SilentlyContinue' + } + $ReleaseText = (Get-Content @parameters) -join "`n" + if ($ReleaseText) { + $ReleaseText | Set-Content "$ProjectRoot\docs\RELEASE.md" + $YMLText = "$YMLtext - Realse Notes: RELEASE.md`n" + } + if ((Test-Path -Path $ChangeLog)) { + $YMLText = "$YMLtext - Change Log: ChangeLog.md`n" + } + $YMLText = "$YMLtext - Functions:`n" + # Drain the swamp + $parameters = @{ + Recurse = $true + Force = $true + Path = "$ProjectRoot\docs\functions" + ErrorAction = 'SilentlyContinue' + } + $null = Remove-Item @parameters $Params = @{ Path = "$ProjectRoot\docs\functions" type = 'directory' ErrorAction = 'SilentlyContinue' } - New-Item @Params + $null = New-Item @Params $Params = @{ Module = $ENV:BHProjectName Force = $true @@ -112,7 +219,7 @@ Task BuildDocs -depends Build { $Function = $_.Name -replace '\.md', '' $Part = " - {0}: functions/{1}" -f $Function, $_.Name $YMLText = "{0}{1}`n" -f $YMLText, $Part - Write-Host $Part + $Part } $YMLtext | Set-Content -Path "$ProjectRoot\mkdocs.yml" } @@ -140,3 +247,77 @@ Task Deploy -Depends BuildDocs { "`t* Your commit message includes !deploy (Current: $ENV:BHCommitMessage)" } } + +Task PostDeploy -depends Deploy { + $lines + if ($ENV:APPVEYOR_REPO_PROVIDER -notlike 'github') { + "Repo provider '$ENV:APPVEYOR_REPO_PROVIDER'. Skipping PostDeploy" + return + } + If ($ENV:BHBuildSystem -eq 'AppVeyor') { + "git config --global credential.helper store" + cmd /c "git config --global credential.helper store 2>&1" + + Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:access_token):x-oauth-basic@github.com`n" + + "git config --global user.email" + cmd /c "git config --global user.email ""$($ENV:BHProjectName)-$($ENV:BHBranchName)-$($ENV:BHBuildSystem)@markekraus.com"" 2>&1" + + "git config --global user.name" + cmd /c "git config --global user.name ""AppVeyor"" 2>&1" + + "git config --global core.autocrlf true" + cmd /c "git config --global core.autocrlf true 2>&1" + } + + "git checkout $ENV:BHBranchName" + cmd /c "git checkout $ENV:BHBranchName 2>&1" + + "git add -A" + cmd /c "git add -A 2>&1" + + "git commit -m" + cmd /c "git commit -m ""AppVeyor post-build commit[ci skip]"" 2>&1" + + "git status" + cmd /c "git status 2>&1" + + "git push origin $ENV:BHBranchName" + cmd /c "git push origin $ENV:BHBranchName 2>&1" + # if this is a !deploy on master, create GitHub release + if ( + $ENV:BHBuildSystem -ne 'Unknown' -and + $ENV:BHBranchName -eq "master" -and + $ENV:BHCommitMessage -match '!deploy' + ) { + "Publishing Release 'v$BuildVersion' to Github" + $parameters = @{ + Path = $ReleaseNotes + ErrorAction = 'SilentlyContinue' + } + $ReleaseText = (Get-Content @parameters) -join "`r`n" + if (-not $ReleaseText) { + $ReleaseText = "Release version $BuildVersion ($BuildDate)" + } + $Body = @{ + "tag_name" = "v$BuildVersion" + "target_commitish"= "master" + "name" = "v$BuildVersion" + "body"= $ReleaseText + "draft" = $false + "prerelease"= $false + } | ConvertTo-Json + $releaseParams = @{ + Uri = "https://api.github.com/repos/{0}/releases" -f $ENV:APPVEYOR_REPO_NAME + Method = 'POST' + Headers = @{ + Authorization = 'Basic ' + [Convert]::ToBase64String( + [Text.Encoding]::ASCII.GetBytes($env:access_token + ":x-oauth-basic")); + } + ContentType = 'application/json' + Body = $Body + } + $Response = Invoke-RestMethod @releaseParams + $Response | Format-List * + } +} \ No newline at end of file