Added support for specific versions #132 #136 (#135)

This commit is contained in:
Bernie White 2022-02-03 16:44:39 +10:00 коммит произвёл GitHub
Родитель f9b96ca850
Коммит 9672f3693f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 289 добавлений и 51 удалений

2
.github/workflows/build.yaml поставляемый
Просмотреть файл

@ -10,7 +10,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@main
uses: actions/checkout@v2.4.0
- name: Run PSRule analysis
uses: ./

47
.github/workflows/dependencies.yaml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,47 @@
#
# Automated dependency updates
#
# NOTES:
# This automatically bumps PowerShell dependency versions.
name: Dependencies
on:
schedule:
- cron: '50 1 * * 1' # At 01:50 AM, on Monday each week
workflow_dispatch:
env:
WORKING_BRANCH: dependencies/powershell-bump
jobs:
dependencies:
name: Bump dependencies
runs-on: ubuntu-latest
if: github.repository == 'microsoft/ps-rule'
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v2.4.0
with:
fetch-depth: 0
- name: Configure
run: |
git config user.name github-actions
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
- name: Get working branch
run: |
git checkout -B ${{ env.WORKING_BRANCH }} --force
- name: Check dependencies
run: |
Import-Module ./scripts/dependencies.psm1;
Update-Dependencies -Path ./modules.json;
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Просмотреть файл

@ -1,13 +0,0 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
ARG MODULE_VERSION=1.11.0
FROM mcr.microsoft.com/powershell:7.2.1-alpine-3.14-20220131
SHELL ["pwsh", "-Command"]
RUN $ProgressPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue; \
$Null = New-Item -Path /ps_modules/ -ItemType Directory -Force; \
Save-Module -Name PSRule -RequiredVersion ${MODULE_VERSION} -Force -Path /ps_modules/;
COPY LICENSE README.md powershell.ps1 /
CMD ["pwsh", "-File", "/powershell.ps1"]

Просмотреть файл

@ -12,14 +12,14 @@ To get the latest stable release use:
```yaml
- name: Run PSRule analysis
uses: Microsoft/ps-rule@v1.12.0
uses: microsoft/ps-rule@v1.12.0
```
To get the latest bits use:
```yaml
- name: Run PSRule analysis
uses: Microsoft/ps-rule@main
uses: microsoft/ps-rule@main
```
For a list of changes please see the [change log].
@ -28,18 +28,19 @@ For a list of changes please see the [change log].
```yaml
- name: Run PSRule analysis
uses: Microsoft/ps-rule@main
uses: microsoft/ps-rule@main
with:
inputType: repository, inputPath # Optional. Determines the type of input to use for PSRule.
inputPath: string # Optional. The path PSRule will look for files to validate.
modules: string # Optional. A comma separated list of modules to use for analysis.
source: string # Optional. A path containing rules to use for analysis.
baseline: string # Optional. The name of a PSRule baseline to use.
conventions: string # Optional. A comma separated list of conventions to use.
outputFormat: None, Yaml, Json, NUnit3, Csv, Markdown # Optional. The format to use when writing results to disk.
outputPath: string # Optional. The file path to write results to.
path: string # Optional. The working directory PSRule is run from.
prerelease: boolean # Optional. Determine if a pre-release module version is installed.
inputType: repository, inputPath # Optional. Determines the type of input to use for PSRule.
inputPath: string # Optional. The path PSRule will look for files to validate.
modules: string # Optional. A comma separated list of modules to use for analysis.
source: string # Optional. A path containing rules to use for analysis.
baseline: string # Optional. The name of a PSRule baseline to use.
conventions: string # Optional. A comma separated list of conventions to use.
outputFormat: None, Yaml, Json, NUnit3, Csv, Markdown, Sarif # Optional. The format to use when writing results to disk.
outputPath: string # Optional. The file path to write results to.
path: string # Optional. The working directory PSRule is run from.
prerelease: boolean # Optional. Determine if a pre-release module version is installed.
version: string # Optional. The specific version of PSRule to use.
```
### `inputType`
@ -95,7 +96,7 @@ For example: `conventions: Monitor.LogAnalytics.Import`
### `outputFormat`
The output format to write result to disk.
Supported formats are `Yaml`, `Json`, `NUnit3`, `Csv`, `Markdown`.
Supported formats are `Yaml`, `Json`, `NUnit3`, `Csv`, `Markdown`, `Sarif`.
Defaults to `None`.
### `outputPath`
@ -111,17 +112,27 @@ Options specified in `ps-rule.yaml` from this directory will be used unless over
### `prerelease`
Determine if a pre-release rules module version is installed.
Determine if a pre-release module versions are installed.
When set to `true` the latest pre-release or stable module version is installed.
If this input is not configured, invalid, or set to `false` only stable module versions will be installed.
### `version`
The specific version of PSRule to use.
By default, the latest stable version of PSRule will be used.
When set:
- The specific version of PSRule will be installed and imported for use.
- If a pre-release version is specified, `prerelease: true` must also be specified.
- If the version is not found, an error will be thrown.
## Using the action
To use PSRule:
1. See [Creating a workflow file](https://help.github.com/en/articles/configuring-a-workflow#creating-a-workflow-file).
2. Reference `Microsoft/ps-rule@main`.
2. Reference `microsoft/ps-rule@v1.12.0`.
For example:
```yaml
@ -134,10 +145,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@main
uses: actions/checkout@v2.4.0
- name: Run PSRule analysis
uses: Microsoft/ps-rule@main
uses: microsoft/ps-rule@v1.12.0
```
3. Create rules within the `.ps-rule/` directory.

Просмотреть файл

@ -1,3 +1,6 @@
#
# GitHub Action manifest for PSRule
#
name: 'PSRule'
description: 'Run rules in a GitHub repository.'
author: 'Microsoft'
@ -56,6 +59,16 @@ inputs:
default: 'false'
required: false
version:
description: 'The specific version of PSRule to use.'
default: ''
required: false
runs:
using: 'docker'
image: 'Dockerfile'
using: 'composite'
steps:
- name: 'Analysis'
shell: pwsh
working-directory: ${{ github.workspace }}
run: |-
${{ github.action_path }}/powershell.ps1 -InputType '${{ inputs.inputType }}' -InputPath '${{ inputs.inputPath }}' -Modules '${{ inputs.modules }}' -Source '${{ inputs.source }}' -Baseline '${{ inputs.baseline }}' -Conventions '${{ inputs.conventions }}' -OutputFormat '${{ inputs.outputFormat }}' -OutputPath '${{ inputs.outputPath }}' -Path '${{ inputs.path }}' -PreRelease '${{ inputs.prerelease }}' -Version '${{ inputs.version }}'

Просмотреть файл

@ -6,6 +6,19 @@ See [upgrade notes][upgrade-notes] for helpful information when upgrading from p
## Unreleased
What's changed since v1.12.0:
- New features:
- Added support for using a specific version of PSRule. [#132](https://github.com/microsoft/ps-rule/issues/132)
- To install a specific version set the `version` parameter.
- By default, the latest stable version of PSRule is used.
- Added support for outputting analysis results as SARIF. [#136](https://github.com/microsoft/ps-rule/issues/136)
- To use the SARIF output format set the `outputFormat` parameter to `Sarif`.
- Currently a pre-release version of PSRule must be used.
To configure this:
- Set the `prerelease` parameter to `true` to include pre-release versions.
- Set the `version` parameter to `2.0.0-B2201161` or newer version.
## v1.12.0
What's changed since v1.11.0:

7
modules.json Normal file
Просмотреть файл

@ -0,0 +1,7 @@
{
"dependencies": {
"PSRule": {
"version": "1.11.0"
}
}
}

Просмотреть файл

@ -40,7 +40,7 @@ param (
# The output format
[Parameter(Mandatory = $False)]
[ValidateSet('None', 'Yaml', 'Json', 'NUnit3', 'Csv', 'Markdown')]
[ValidateSet('None', 'Yaml', 'Json', 'NUnit3', 'Csv', 'Markdown', 'Sarif')]
[String]$OutputFormat = $Env:INPUT_OUTPUTFORMAT,
# The path to store formatted output
@ -49,7 +49,11 @@ param (
# Determine if a pre-release module version is installed.
[Parameter(Mandatory = $False)]
[String]$PreRelease = $Env:INPUT_PRERELEASE
[String]$PreRelease = $Env:INPUT_PRERELEASE,
# The specific version of PSRule to use.
[Parameter(Mandatory = $False)]
[String]$Version = $Env:INPUT_VERSION
)
$workspacePath = $Env:GITHUB_WORKSPACE;
@ -115,28 +119,33 @@ function WriteDebug {
}
}
# Setup paths for importing modules
$modulesPath = '/ps_modules/';
if ((Get-Variable -Name IsMacOS -ErrorAction Ignore) -or (Get-Variable -Name IsLinux -ErrorAction Ignore)) {
$moduleSearchPaths = $Env:PSModulePath.Split(':', [System.StringSplitOptions]::RemoveEmptyEntries);
if ($modulesPath -notin $moduleSearchPaths) {
$Env:PSModulePath += [String]::Concat($Env:PSModulePath, ':', $modulesPath);
}
#
# Check and install modules
#
$dependencyFile = Join-Path -Path $Env:GITHUB_ACTION_PATH -ChildPath 'modules.json';
$latestVersion = (Get-Content -Path $dependencyFile -Raw | ConvertFrom-Json -AsHashtable -Depth 5).dependencies.PSRule.version;
$checkParams = @{
RequiredVersion = $latestVersion
}
else {
$moduleSearchPaths = $Env:PSModulePath.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries);
if ($modulesPath -notin $moduleSearchPaths) {
$Env:PSModulePath += [String]::Concat($Env:PSModulePath, ';', $modulesPath);
if (![String]::IsNullOrEmpty($Version)) {
$checkParams['RequiredVersion'] = $Version;
if ($PreRelease -eq 'true') {
$checkParams['AllowPrerelease'] = $True;
}
}
# Look for existing modules
$installed = @(Get-InstalledModule)
# Look for existing versions of PSRule
$installed = @(Get-InstalledModule -Name PSRule @checkParams -ErrorAction Ignore)
if ($installed.Length -eq 0) {
Write-Host "[info] Installing PSRule: $($checkParams.RequiredVersion)";
$Null = Install-Module -Name PSRule @checkParams -Scope CurrentUser -Force;
}
foreach ($m in $installed) {
Write-Host "[info] Using existing module $($m.Name): $($m.Version)";
}
Write-Host '';
# Look for existing modules
Write-Host '';
$moduleNames = @()
if (![String]::IsNullOrEmpty($Modules)) {
$moduleNames = $Modules.Split(',', [System.StringSplitOptions]::RemoveEmptyEntries);
@ -176,7 +185,7 @@ foreach ($m in $moduleNames) {
}
try {
$Null = Import-Module PSRule -ErrorAction Stop;
$Null = Import-Module PSRule @checkParams -ErrorAction Stop;
$version = (Get-Module PSRule).Version;
}
catch {
@ -184,6 +193,9 @@ catch {
$Host.SetShouldExit(1);
}
#
# Run assert pipeline
#
Write-Host '';
Write-Host "[info] Using Version: $version";
Write-Host "[info] Using Action: $Env:GITHUB_ACTION";

Просмотреть файл

@ -15,4 +15,5 @@ output:
input:
pathIgnore:
- '*.md'
- '*.json'
- '.vscode/'

147
scripts/dependencies.psm1 Normal file
Просмотреть файл

@ -0,0 +1,147 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Note:
# Handles dependencies updates.
function Update-Dependencies {
[CmdletBinding()]
param (
[Parameter(Mandatory = $True)]
[String]$Path,
[Parameter(Mandatory = $False)]
[String]$Repository = 'PSGallery'
)
process {
$modules = Get-Content -Path $Path -Raw | ConvertFrom-Json -AsHashtable;
$dependencies = CheckVersion $modules.dependencies -Repository $Repository;
$devDependencies = CheckVersion $modules.devDependencies -Repository $Repository -Dev;
$modules = [Ordered]@{
dependencies = $dependencies
devDependencies = $devDependencies
}
$modules | ConvertTo-Json -Depth 10 | Set-Content -Path $Path;
$updates = @(git status --porcelain);
if ($Null -ne $Env:WORKING_BRANCH -and $Null -ne $updates -and $updates.Length -gt 0) {
git add modules.json;
git commit -m "Update $path";
git push --force -u origin $Env:WORKING_BRANCH;
$existingBranch = @(gh pr list --head $Env:WORKING_BRANCH --state open --json number | ConvertFrom-Json);
if ($Null -eq $existingBranch -or $existingBranch.Length -eq 0) {
gh pr create -B 'main' -H $Env:WORKING_BRANCH -l 'dependencies' -t 'Bump PowerShell dependencies' -F 'out/updates.txt';
}
else {
$pr = $existingBranch[0].number
gh pr edit $pr -F 'out/updates.txt';
}
}
}
}
function Install-Dependencies {
[CmdletBinding()]
param (
[Parameter(Mandatory = $True)]
[String]$Path,
[Parameter(Mandatory = $False)]
[String]$Repository = 'PSGallery'
)
process {
$modules = Get-Content -Path $Path -Raw | ConvertFrom-Json;
InstallVersion $modules.dependencies -Repository $Repository;
InstallVersion $modules.devDependencies -Repository $Repository -Dev;
}
}
function CheckVersion {
[CmdletBinding()]
[OutputType([System.Collections.Specialized.OrderedDictionary])]
param (
[Parameter(Mandatory = $True)]
[Hashtable]$InputObject,
[Parameter(Mandatory = $True)]
[String]$Repository,
[Parameter(Mandatory = $False)]
[Switch]$Dev,
[Parameter(Mandatory = $False)]
[String]$OutputPath = 'out/'
)
begin {
$group = 'Dependencies';
if ($Dev) {
$group = 'DevDependencies';
}
if (!(Test-Path -Path $OutputPath)) {
$Null = New-Item -Path $OutputPath -ItemType Directory -Force;
}
$changeNotes = Join-Path -Path $OutputPath -ChildPath 'updates.txt';
}
process {
$dependencies = [Ordered]@{ };
$InputObject.GetEnumerator() | Sort-Object -Property Name | ForEach-Object {
$dependencies[$_.Name] = $_.Value
}
foreach ($module in $dependencies.GetEnumerator()) {
Write-Host -Object "[$group] -- Checking $($module.Name)";
$installParams = @{}
$installParams += $module.Value;
$installParams.MinimumVersion = $installParams.version;
$installParams.Remove('version');
$available = @(Find-Module -Repository $Repository -Name $module.Name @installParams -ErrorAction Ignore);
foreach ($found in $available) {
if (([Version]$found.Version) -gt ([Version]$module.Value.version)) {
Write-Host -Object "[$group] -- Newer version found $($found.Version)";
$dependencies[$module.Name].version = $found.Version;
$Null = Add-Content -Path $changeNotes -Value "Bump $($module.Name) to $($found.Version).";
}
else {
Write-Host -Object "[$group] -- Already up to date.";
}
}
}
return $dependencies;
}
}
function InstallVersion {
[CmdletBinding()]
[OutputType([void])]
param (
[Parameter(Mandatory = $True)]
[PSObject]$InputObject,
[Parameter(Mandatory = $True)]
[String]$Repository,
[Parameter(Mandatory = $False)]
[Switch]$Dev
)
begin {
$group = 'Dependencies';
if ($Dev) {
$group = 'DevDependencies';
}
}
process {
foreach ($module in $InputObject.PSObject.Properties.GetEnumerator()) {
Write-Host -Object "[$group] -- Installing $($module.Name) v$($module.Value.version)";
$installParams = @{ MinimumVersion = $module.Value.version };
if ($Null -eq (Get-InstalledModule -Name $module.Name @installParams -ErrorAction Ignore)) {
Install-Module -Name $module.Name @installParams -Force -Repository $Repository;
}
}
}
}
Export-ModuleMember -Function @(
'Update-Dependencies'
'Install-Dependencies'
)