Add CI and update readme (#8)
This commit is contained in:
Родитель
68947c452c
Коммит
06df7beb08
|
@ -0,0 +1,154 @@
|
|||
# Azure DevOps
|
||||
# CI pipeline for PSRule.Rules.CAF
|
||||
|
||||
variables:
|
||||
version: '0.1.0'
|
||||
buildConfiguration: 'Release'
|
||||
disable.coverage.autogenerate: 'true'
|
||||
|
||||
# Use build number format, i.e. 0.1.0-B1811001
|
||||
name: $(version)-B$(date:yyMM)$(rev:rrr)
|
||||
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- 'master'
|
||||
tags:
|
||||
include:
|
||||
- 'v0.*'
|
||||
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- 'master'
|
||||
|
||||
stages:
|
||||
|
||||
# Build pipeline
|
||||
- stage: Build
|
||||
displayName: Build
|
||||
jobs:
|
||||
- job:
|
||||
strategy:
|
||||
matrix:
|
||||
Linux:
|
||||
displayName: 'Linux'
|
||||
imageName: 'ubuntu-latest'
|
||||
MacOS:
|
||||
displayName: 'MacOS'
|
||||
imageName: 'macOS-latest'
|
||||
Windows:
|
||||
displayName: 'Windows'
|
||||
imageName: 'vs2017-win2016'
|
||||
publish: 'true'
|
||||
analysis: 'true'
|
||||
coverage: 'true'
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
displayName: 'PowerShell'
|
||||
steps:
|
||||
|
||||
# Install pipeline dependencies
|
||||
- powershell: ./.azure-pipelines/pipeline-deps.ps1
|
||||
displayName: 'Install dependencies'
|
||||
|
||||
# Build module
|
||||
- powershell: Invoke-Build -Configuration $(buildConfiguration) -Build $(Build.BuildNumber)
|
||||
displayName: 'Build module'
|
||||
|
||||
# Pester test results
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Pester results'
|
||||
inputs:
|
||||
testRunTitle: 'Pester on $(imageName)'
|
||||
testRunner: NUnit
|
||||
testResultsFiles: 'reports/pester-unit.xml'
|
||||
mergeTestResults: true
|
||||
platform: $(imageName)
|
||||
configuration: $(buildConfiguration)
|
||||
publishRunAttachments: true
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# PSRule results
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish PSRule results'
|
||||
inputs:
|
||||
testRunTitle: 'PSRule on $(imageName)'
|
||||
testRunner: NUnit
|
||||
testResultsFiles: 'reports/ps-rule*.xml'
|
||||
mergeTestResults: true
|
||||
platform: $(imageName)
|
||||
configuration: $(buildConfiguration)
|
||||
publishRunAttachments: true
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# Generate Code Coverage report
|
||||
- task: Palmmedia.reportgenerator.reportgenerator-build-release-task.reportgenerator@4
|
||||
displayName: 'Code coverage report generator'
|
||||
inputs:
|
||||
reports: 'reports\pester-coverage.xml'
|
||||
targetdir: 'reports\coverage'
|
||||
sourcedirs: 'src\PSRule.Rules.CAF'
|
||||
reporttypes: 'HtmlInline_AzurePipelines;Cobertura;Badges'
|
||||
tag: $(Build.BuildNumber)
|
||||
condition: eq(variables['coverage'], 'true')
|
||||
|
||||
# Publish Code Coverage report
|
||||
- task: PublishCodeCoverageResults@1
|
||||
displayName: 'Publish Pester code coverage'
|
||||
inputs:
|
||||
codeCoverageTool: 'Cobertura'
|
||||
summaryFileLocation: 'reports/coverage/Cobertura.xml'
|
||||
reportDirectory: 'reports/coverage'
|
||||
condition: eq(variables['coverage'], 'true')
|
||||
|
||||
# Generate artifacts
|
||||
- task: PublishPipelineArtifact@0
|
||||
displayName: 'Publish module'
|
||||
inputs:
|
||||
artifactName: PSRule.Rules.CAF
|
||||
targetPath: out/modules/PSRule.Rules.CAF
|
||||
condition: and(succeeded(), eq(variables['publish'], 'true'))
|
||||
|
||||
# Release pipeline
|
||||
# - stage: Release
|
||||
# displayName: Release
|
||||
# dependsOn: Build
|
||||
# condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v0.'))
|
||||
# jobs:
|
||||
# - job:
|
||||
# displayName: Live
|
||||
# pool:
|
||||
# vmImage: 'ubuntu-16.04'
|
||||
# variables:
|
||||
# isPreRelease: $[contains(variables['Build.SourceBranchName'], '-B')]
|
||||
# steps:
|
||||
|
||||
# # Download module from build
|
||||
# - task: DownloadPipelineArtifact@1
|
||||
# displayName: 'Download module'
|
||||
# inputs:
|
||||
# artifactName: PSRule.Rules.CAF
|
||||
# downloadPath: $(Build.SourcesDirectory)/out/modules/PSRule.Rules.CAF
|
||||
|
||||
# # Install pipeline dependencies
|
||||
# - powershell: ./.azure-pipelines/pipeline-deps.ps1
|
||||
# displayName: 'Install dependencies'
|
||||
|
||||
# # Install pipeline dependencies and build module
|
||||
# - powershell: Invoke-Build Release -ApiKey $(apiKey)
|
||||
# displayName: 'Publish module'
|
||||
|
||||
# # Update GitHub release
|
||||
# - task: GitHubRelease@0
|
||||
# displayName: 'GitHub release'
|
||||
# inputs:
|
||||
# gitHubConnection: 'AzureDevOps-PSRule.Rules.CAF'
|
||||
# repositoryName: '$(Build.Repository.Name)'
|
||||
# action: edit
|
||||
# tag: '$(Build.SourceBranchName)'
|
||||
# releaseNotesSource: input
|
||||
# releaseNotes: 'See [change log](https://github.com/Microsoft/PSRule.Rules.CAF/blob/master/CHANGELOG.md)'
|
||||
# assetUploadMode: replace
|
||||
# addChangeLog: false
|
||||
# isPreRelease: $(isPreRelease)
|
|
@ -0,0 +1,54 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
# Synopsis: Check for recommended community files
|
||||
Rule 'OpenSource.Community' -Type 'System.IO.DirectoryInfo' {
|
||||
$requiredFiles = @(
|
||||
'CHANGELOG.md'
|
||||
'LICENSE'
|
||||
'CODE_OF_CONDUCT.md'
|
||||
'CONTRIBUTING.md'
|
||||
'SECURITY.md'
|
||||
'README.md'
|
||||
'.github/CODEOWNERS'
|
||||
'.github/PULL_REQUEST_TEMPLATE.md'
|
||||
)
|
||||
Test-Path -Path $TargetObject.FullName;
|
||||
for ($i = 0; $i -lt $requiredFiles.Length; $i++) {
|
||||
$filePath = Join-Path -Path $TargetObject.FullName -ChildPath $requiredFiles[$i];
|
||||
$Assert.Create((Test-Path -Path $filePath -PathType Leaf), "$($requiredFiles[$i]) does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
# Synopsis: Check for license in code files
|
||||
Rule 'OpenSource.License' -Type 'System.IO.FileInfo' -If { $TargetObject.Extension -in '.cs', '.ps1', '.psd1', '.psm1' } {
|
||||
$commentPrefix = "`# ";
|
||||
if ($TargetObject.Extension -eq '.cs') {
|
||||
$commentPrefix = '// '
|
||||
}
|
||||
$header = GetLicenseHeader -CommentPrefix $commentPrefix;
|
||||
$content = Get-Content -Path $TargetObject.FullName -Raw;
|
||||
$content.StartsWith($header);
|
||||
}
|
||||
|
||||
function global:GetLicenseHeader {
|
||||
[CmdletBinding()]
|
||||
[OutputType([String])]
|
||||
param (
|
||||
[Parameter(Mandatory = $True)]
|
||||
[String]$CommentPrefix
|
||||
)
|
||||
process {
|
||||
$text = @(
|
||||
'Copyright (c) Microsoft Corporation.'
|
||||
'Licensed under the MIT License.'
|
||||
)
|
||||
$builder = [System.Text.StringBuilder]::new();
|
||||
foreach ($line in $text) {
|
||||
$Null = $builder.Append($CommentPrefix);
|
||||
$Null = $builder.Append($line);
|
||||
$Null = $builder.Append([System.Environment]::NewLine);
|
||||
}
|
||||
return $builder.ToString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
# Synopsis: Use short rule names
|
||||
Rule 'Rule.Name' -Type 'PSRule.Rules.Rule' {
|
||||
Recommend 'Rule name should be less than 35 characters to prevent being truncated.'
|
||||
Reason "The rule name is too long."
|
||||
$TargetObject.RuleName.Length -le 35
|
||||
$TargetObject.RuleName.StartsWith('CAF.')
|
||||
}
|
||||
|
||||
# Synopsis: Complete help documentation
|
||||
Rule 'Rule.Help' -Type 'PSRule.Rules.Rule' {
|
||||
$Assert.HasFieldValue($TargetObject, 'Info.Synopsis')
|
||||
$Assert.HasFieldValue($TargetObject, 'Info.Description')
|
||||
$Assert.HasFieldValue($TargetObject, 'Info.Recommendation')
|
||||
}
|
||||
|
||||
# Synopsis: Use online help
|
||||
Rule 'Rule.OnlineHelp' -Type 'PSRule.Rules.Rule' {
|
||||
$Assert.HasFieldValue($TargetObject, 'Info.Annotations.''online version''')
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "test",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build Test -AssertStyle Client",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$pester"
|
||||
],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "coverage",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build Test -CodeCoverage",
|
||||
"problemMatcher": [ "$pester" ],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build Build",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "clean",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build Clean",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "script-analyzer",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build Analyze",
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build-docs",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build BuildHelp",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "scaffold-docs",
|
||||
"type": "shell",
|
||||
"command": "Invoke-Build ScaffoldHelp",
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -15,6 +15,12 @@ If you do not see your problem captured, please file a new issue and follow the
|
|||
|
||||
If you have any problems with the [PSRule][engine] engine, please check the project GitHub [issues](https://github.com/Microsoft/PSRule/issues) page instead.
|
||||
|
||||
## Rule reference
|
||||
|
||||
For a list of rules included in the `PSRule.Rules.CAF` module see:
|
||||
|
||||
- [Module rule reference](docs/rules/en/module.md)
|
||||
|
||||
## Changes and versioning
|
||||
|
||||
Modules in this repository will use the [semantic versioning](http://semver.org/) model to declare breaking changes from v1.0.0.
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
Document 'module' {
|
||||
Title 'Module rule reference'
|
||||
|
||||
Import-Module .\out\modules\PSRule.Rules.CAF
|
||||
$rules = Get-PSRule -Module PSRule.Rules.CAF -WarningAction SilentlyContinue |
|
||||
Add-Member -MemberType ScriptProperty -Name Category -Value { $this.Info.Annotations.category } -PassThru |
|
||||
Sort-Object -Property Category;
|
||||
|
||||
Section 'Baselines' {
|
||||
# 'The following baselines are included within `PSRule.Rules.CAF`.'
|
||||
}
|
||||
|
||||
Section 'Rules' {
|
||||
'The following rules are included within `PSRule.Rules.CAF`.'
|
||||
|
||||
$categories = $rules | Group-Object -Property Category;
|
||||
|
||||
foreach ($category in $categories) {
|
||||
Section "$($category.Name)" {
|
||||
$category.Group |
|
||||
Sort-Object -Property RuleName |
|
||||
Table -Property @{ Name = 'Name'; Expression = {
|
||||
"[$($_.RuleName)]($($_.RuleName).md)"
|
||||
}}, Synopsis
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
# Module rule reference
|
||||
|
||||
## Rules
|
||||
|
||||
The following rules are included within `PSRule.Rules.CAF`.
|
||||
|
||||
### Naming
|
||||
|
||||
Name | Synopsis
|
||||
---- | --------
|
||||
[CAF.Name.Connection](CAF.Name.Connection.md) | Virtual network gateway connection names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.LoadBalancer](CAF.Name.LoadBalancer.md) | Load balancer names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.NSG](CAF.Name.NSG.md) | Network security group (NSG) names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.PublicIP](CAF.Name.PublicIP.md) | Public IP address names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.RG](CAF.Name.RG.md) | Resource group names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.Route](CAF.Name.Route.md) | Route table names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.Storage](CAF.Name.Storage.md) | Storage account names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.Subnet](CAF.Name.Subnet.md) | Subnet names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.VM](CAF.Name.VM.md) | Virtual machine names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.VNET](CAF.Name.VNET.md) | Virtual network names should use a standard prefix and meet naming requirements.
|
||||
[CAF.Name.VNG](CAF.Name.VNG.md) | Virtual network gateway names should use a standard prefix and meet naming requirements.
|
||||
|
||||
### Tagging
|
||||
|
||||
Name | Synopsis
|
||||
---- | --------
|
||||
[CAF.Tag.Environment](CAF.Tag.Environment.md) | Tag resources and resource groups with a valid environment.
|
||||
[CAF.Tag.Required](CAF.Tag.Required.md) | Tag resources and resource groups with mandatory tags.
|
|
@ -0,0 +1,316 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String]$Build = '0.0.1',
|
||||
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String]$Configuration = 'Debug',
|
||||
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String]$ApiKey,
|
||||
|
||||
[Parameter(Mandatory = $False)]
|
||||
[Switch]$CodeCoverage = $False,
|
||||
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String]$ArtifactPath = (Join-Path -Path $PWD -ChildPath out/modules),
|
||||
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String]$AssertStyle = 'AzurePipelines'
|
||||
)
|
||||
|
||||
Write-Host -Object "[Pipeline] -- PWD: $PWD" -ForegroundColor Green;
|
||||
Write-Host -Object "[Pipeline] -- ArtifactPath: $ArtifactPath" -ForegroundColor Green;
|
||||
Write-Host -Object "[Pipeline] -- BuildNumber: $($Env:BUILD_BUILDNUMBER)" -ForegroundColor Green;
|
||||
Write-Host -Object "[Pipeline] -- SourceBranch: $($Env:BUILD_SOURCEBRANCH)" -ForegroundColor Green;
|
||||
Write-Host -Object "[Pipeline] -- SourceBranchName: $($Env:BUILD_SOURCEBRANCHNAME)" -ForegroundColor Green;
|
||||
|
||||
if ($Env:SYSTEM_DEBUG -eq 'true') {
|
||||
$VerbosePreference = 'Continue';
|
||||
}
|
||||
|
||||
if ($Env:BUILD_SOURCEBRANCH -like '*/tags/*' -and $Env:BUILD_SOURCEBRANCHNAME -like 'v0.*') {
|
||||
$Build = $Env:BUILD_SOURCEBRANCHNAME.Substring(1);
|
||||
}
|
||||
|
||||
$version = $Build;
|
||||
$versionSuffix = [String]::Empty;
|
||||
|
||||
if ($version -like '*-*') {
|
||||
[String[]]$versionParts = $version.Split('-', [System.StringSplitOptions]::RemoveEmptyEntries);
|
||||
$version = $versionParts[0];
|
||||
|
||||
if ($versionParts.Length -eq 2) {
|
||||
$versionSuffix = $versionParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host -Object "[Pipeline] -- Using version: $version" -ForegroundColor Green;
|
||||
Write-Host -Object "[Pipeline] -- Using versionSuffix: $versionSuffix" -ForegroundColor Green;
|
||||
|
||||
if ($Env:coverage -eq 'true') {
|
||||
$CodeCoverage = $True;
|
||||
}
|
||||
|
||||
# Copy the PowerShell modules files to the destination path
|
||||
function CopyModuleFiles {
|
||||
param (
|
||||
[Parameter(Mandatory = $True)]
|
||||
[String]$Path,
|
||||
|
||||
[Parameter(Mandatory = $True)]
|
||||
[String]$DestinationPath
|
||||
)
|
||||
|
||||
process {
|
||||
$sourcePath = Resolve-Path -Path $Path;
|
||||
|
||||
Get-ChildItem -Path $sourcePath -Recurse -File -Include *.ps1,*.psm1,*.psd1,*.ps1xml,*.yaml | Where-Object -FilterScript {
|
||||
($_.FullName -notmatch '(\.(cs|csproj)|(\\|\/)(obj|bin))')
|
||||
} | ForEach-Object -Process {
|
||||
$filePath = $_.FullName.Replace($sourcePath, $destinationPath);
|
||||
|
||||
$parentPath = Split-Path -Path $filePath -Parent;
|
||||
|
||||
if (!(Test-Path -Path $parentPath)) {
|
||||
$Null = New-Item -Path $parentPath -ItemType Directory -Force;
|
||||
}
|
||||
|
||||
Copy-Item -Path $_.FullName -Destination $filePath -Force;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function Get-RepoRuleData {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Position = 0, Mandatory = $False)]
|
||||
[String]$Path = $PWD
|
||||
)
|
||||
process {
|
||||
GetPathInfo -Path $Path -Verbose:$VerbosePreference;
|
||||
}
|
||||
}
|
||||
|
||||
function GetPathInfo {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $True)]
|
||||
[String]$Path
|
||||
)
|
||||
begin {
|
||||
$items = New-Object -TypeName System.Collections.ArrayList;
|
||||
}
|
||||
process {
|
||||
$Null = $items.Add((Get-Item -Path $Path));
|
||||
$files = @(Get-ChildItem -Path $Path -File -Recurse -Include *.ps1,*.psm1,*.psd1,*.cs | Where-Object {
|
||||
!($_.FullName -like "*.Designer.cs") -and
|
||||
!($_.FullName -like "*/bin/*") -and
|
||||
!($_.FullName -like "*/obj/*") -and
|
||||
!($_.FullName -like "*\obj\*") -and
|
||||
!($_.FullName -like "*\bin\*") -and
|
||||
!($_.FullName -like "*\out\*") -and
|
||||
!($_.FullName -like "*/out/*")
|
||||
});
|
||||
$Null = $items.AddRange($files);
|
||||
}
|
||||
end {
|
||||
$items;
|
||||
}
|
||||
}
|
||||
|
||||
task VersionModule ModuleDependencies, {
|
||||
$modulePath = Join-Path -Path $ArtifactPath -ChildPath PSRule.Rules.CAF;
|
||||
$manifestPath = Join-Path -Path $modulePath -ChildPath PSRule.Rules.CAF.psd1;
|
||||
Write-Verbose -Message "[VersionModule] -- Checking module path: $modulePath";
|
||||
|
||||
if (![String]::IsNullOrEmpty($Build)) {
|
||||
# Update module version
|
||||
if (![String]::IsNullOrEmpty($version)) {
|
||||
Write-Verbose -Message "[VersionModule] -- Updating module manifest ModuleVersion";
|
||||
Update-ModuleManifest -Path $manifestPath -ModuleVersion $version;
|
||||
}
|
||||
|
||||
# Update pre-release version
|
||||
if (![String]::IsNullOrEmpty($versionSuffix)) {
|
||||
Write-Verbose -Message "[VersionModule] -- Updating module manifest Prerelease";
|
||||
Update-ModuleManifest -Path $manifestPath -Prerelease $versionSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
$manifest = Test-ModuleManifest -Path $manifestPath;
|
||||
$requiredModules = $manifest.RequiredModules | ForEach-Object -Process {
|
||||
if ($_.Name -eq 'PSRule' -and $Configuration -eq 'Release') {
|
||||
@{ ModuleName = 'PSRule'; ModuleVersion = '0.13.0' }
|
||||
}
|
||||
else {
|
||||
@{ ModuleName = $_.Name; ModuleVersion = $_.Version }
|
||||
}
|
||||
};
|
||||
Update-ModuleManifest -Path $manifestPath -RequiredModules $requiredModules;
|
||||
$manifestContent = Get-Content -Path $manifestPath -Raw;
|
||||
$manifestContent = $manifestContent -replace 'PSRule = ''System.Collections.Hashtable''', 'PSRule = @{ Baseline = ''CAF.Default'' }';
|
||||
$manifestContent | Set-Content -Path $manifestPath;
|
||||
}
|
||||
|
||||
# Synopsis: Publish to PowerShell Gallery
|
||||
task ReleaseModule VersionModule, {
|
||||
$modulePath = (Join-Path -Path $ArtifactPath -ChildPath PSRule.Rules.CAF);
|
||||
Write-Verbose -Message "[ReleaseModule] -- Checking module path: $modulePath";
|
||||
|
||||
if (!(Test-Path -Path $modulePath)) {
|
||||
Write-Error -Message "[ReleaseModule] -- Module path does not exist";
|
||||
}
|
||||
elseif (![String]::IsNullOrEmpty($ApiKey)) {
|
||||
Publish-Module -Path $modulePath -NuGetApiKey $ApiKey;
|
||||
}
|
||||
}
|
||||
|
||||
# Synopsis: Install NuGet provider
|
||||
task NuGet {
|
||||
if ($Null -eq (Get-PackageProvider -Name NuGet -ErrorAction Ignore)) {
|
||||
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser;
|
||||
}
|
||||
}
|
||||
|
||||
# Synopsis: Install Pester module
|
||||
task Pester NuGet, {
|
||||
if ($Null -eq (Get-InstalledModule -Name Pester -MinimumVersion 4.9.0 -ErrorAction Ignore)) {
|
||||
Install-Module -Name Pester -MinimumVersion 4.9.0 -Scope CurrentUser -Force -SkipPublisherCheck;
|
||||
}
|
||||
Import-Module -Name Pester -Verbose:$False;
|
||||
}
|
||||
|
||||
# Synopsis: Install PSScriptAnalyzer module
|
||||
task PSScriptAnalyzer NuGet, {
|
||||
if ($Null -eq (Get-InstalledModule -Name PSScriptAnalyzer -MinimumVersion 1.18.3 -ErrorAction Ignore)) {
|
||||
Install-Module -Name PSScriptAnalyzer -MinimumVersion 1.18.3 -Scope CurrentUser -Force;
|
||||
}
|
||||
Import-Module -Name PSScriptAnalyzer -Verbose:$False;
|
||||
}
|
||||
|
||||
# Synopsis: Install PSRule
|
||||
task PSRule NuGet, {
|
||||
if ($Null -eq (Get-InstalledModule -Name PSRule -MinimumVersion 0.13.0 -ErrorAction Ignore)) {
|
||||
Install-Module -Name PSRule -Repository PSGallery -MinimumVersion 0.13.0 -Scope CurrentUser -Force;
|
||||
}
|
||||
if ($Null -eq (Get-InstalledModule -Name PSRule.Rules.Azure -MinimumVersion 0.7.0 -ErrorAction Ignore)) {
|
||||
Install-Module -Name PSRule.Rules.Azure -Repository PSGallery -MinimumVersion 0.7.0 -Scope CurrentUser -Force;
|
||||
}
|
||||
Import-Module -Name PSRule.Rules.Azure -Verbose:$False;
|
||||
}
|
||||
|
||||
# Synopsis: Install PSDocs
|
||||
task PSDocs NuGet, {
|
||||
if ($Null -eq (Get-InstalledModule -Name PSDocs -MinimumVersion 0.6.3 -ErrorAction Ignore)) {
|
||||
Install-Module -Name PSDocs -Repository PSGallery -MinimumVersion 0.6.3 -Scope CurrentUser -Force;
|
||||
}
|
||||
Import-Module -Name PSDocs -Verbose:$False;
|
||||
}
|
||||
|
||||
# Synopsis: Install PlatyPS module
|
||||
task platyPS {
|
||||
if ($Null -eq (Get-InstalledModule -Name PlatyPS -MinimumVersion 0.14.0 -ErrorAction Ignore)) {
|
||||
Install-Module -Name PlatyPS -Scope CurrentUser -MinimumVersion 0.14.0 -Force;
|
||||
}
|
||||
Import-Module -Name PlatyPS -Verbose:$False;
|
||||
}
|
||||
|
||||
# Synopsis: Install module dependencies
|
||||
task ModuleDependencies NuGet, PSRule, {
|
||||
}
|
||||
|
||||
task CopyModule {
|
||||
CopyModuleFiles -Path src/PSRule.Rules.CAF -DestinationPath out/modules/PSRule.Rules.CAF;
|
||||
}
|
||||
|
||||
# Synopsis: Build modules only
|
||||
task BuildModule CopyModule
|
||||
|
||||
task TestModule PSRule, Pester, PSScriptAnalyzer, {
|
||||
# Run Pester tests
|
||||
$pesterParams = @{ Path = (Join-Path -Path $PWD -ChildPath tests/PSRule.Rules.CAF.Tests); OutputFile = 'reports/pester-unit.xml'; OutputFormat = 'NUnitXml'; PesterOption = @{ IncludeVSCodeMarker = $True }; PassThru = $True; };
|
||||
|
||||
if ($CodeCoverage) {
|
||||
$pesterParams.Add('CodeCoverage', (Join-Path -Path $PWD -ChildPath 'out/modules/**/*.psm1'));
|
||||
$pesterParams.Add('CodeCoverageOutputFile', (Join-Path -Path $PWD -ChildPath reports/pester-coverage.xml));
|
||||
}
|
||||
|
||||
if (!(Test-Path -Path reports)) {
|
||||
$Null = New-Item -Path reports -ItemType Directory -Force;
|
||||
}
|
||||
|
||||
$results = Invoke-Pester @pesterParams;
|
||||
|
||||
# Throw an error if pester tests failed
|
||||
if ($Null -eq $results) {
|
||||
throw 'Failed to get Pester test results.';
|
||||
}
|
||||
elseif ($results.FailedCount -gt 0) {
|
||||
throw "$($results.FailedCount) tests failed.";
|
||||
}
|
||||
}
|
||||
|
||||
# Synopsis: Run validation
|
||||
task Rules PSRule, {
|
||||
$assertParams = @{
|
||||
Path = './.ps-rule/'
|
||||
Style = $AssertStyle
|
||||
OutputFormat = 'NUnit3';
|
||||
}
|
||||
Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.CAF) -Force;
|
||||
Get-RepoRuleData -Path $PWD |
|
||||
Assert-PSRule @assertParams -OutputPath reports/ps-rule-file.xml;
|
||||
|
||||
$rules = Get-PSRule -Module PSRule.Rules.CAF;
|
||||
$rules | Assert-PSRule @assertParams -OutputPath reports/ps-rule-file2.xml;
|
||||
}
|
||||
|
||||
# Synopsis: Run script analyzer
|
||||
task Analyze Build, PSScriptAnalyzer, {
|
||||
Invoke-ScriptAnalyzer -Path out/modules/PSRule.Rules.CAF;
|
||||
}
|
||||
|
||||
# Synopsis: Build table of content for rules
|
||||
task BuildRuleDocs Build, PSRule, PSDocs, {
|
||||
Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.CAF) -Force;
|
||||
$Null = Invoke-PSDocument -Name module -OutputPath .\docs\rules\en\ -Path .\RuleToc.Doc.ps1;
|
||||
}
|
||||
|
||||
# Synopsis: Build help
|
||||
task BuildHelp BuildModule, PlatyPS, {
|
||||
if (!(Test-Path out/modules/PSRule.Rules.CAF/en/)) {
|
||||
$Null = New-Item -Path out/modules/PSRule.Rules.CAF/en/ -ItemType Directory -Force;
|
||||
}
|
||||
|
||||
# Copy generated help into module out path
|
||||
$Null = Copy-Item -Path docs/rules/en/*.md -Destination out/modules/PSRule.Rules.CAF/en/;
|
||||
}
|
||||
|
||||
task ScaffoldHelp Build, BuildRuleDocs, {
|
||||
# Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.CAF) -Force;
|
||||
# Update-MarkdownHelp -Path '.\docs\commands\PSRule.Rules.CAF\en-US';
|
||||
}
|
||||
|
||||
# Synopsis: Add shipit build tag
|
||||
task TagBuild {
|
||||
if ($Null -ne $Env:BUILD_DEFINITIONNAME) {
|
||||
Write-Host "`#`#vso[build.addbuildtag]shipit";
|
||||
}
|
||||
}
|
||||
|
||||
# Synopsis: Remove temp files.
|
||||
task Clean {
|
||||
Remove-Item -Path out,reports -Recurse -Force -ErrorAction SilentlyContinue;
|
||||
}
|
||||
|
||||
task Build Clean, BuildModule, VersionModule, BuildHelp
|
||||
|
||||
task Test Build, Rules, TestModule
|
||||
|
||||
task Release ReleaseModule, TagBuild
|
||||
|
||||
task . Build, Test
|
|
@ -0,0 +1,6 @@
|
|||
# PSRule options for QA
|
||||
|
||||
binding:
|
||||
targetName:
|
||||
- RuleName
|
||||
- FullName
|
Загрузка…
Ссылка в новой задаче