Рубрики
Uncategorized

Изготовление PSScriptanalyzer первоклассным гражданином в трубопроводе PowerShell CI

Как вы уже знаете, если вы прочитали это или это, я большой поклонник PSScriptanalyzer, чтобы поддерживать … Помечено PowerShell, DevOps, Petter, Linking.

Как вы уже знаете, если вы прочитали Это или Это Я большой поклонник PSScriptanalyzer поддерживать определенный стандарт кодирования. Это особенно мощно внутри релиз-трубопровода, потому что это позволяет нам обеспечить применение этого стандарта кодирования.

В нашем CI Трубопровод, мы можем легко сделать постройку сбой, если наш код нарушает PSScriptanalyzer правила). Это здорово, но главная точка Непрерывная интеграция Состоит в том, чтобы дать быструю обратную связь разработчикам об изменении их кода. Речь идет о ловле проблем раннего исправить их рано. Итак, вопрос:

Как мы можем сделать наш инструмент CI опубликовать PSScriptanalyzer Результаты с информацией, которую мы должны исправить любое нарушение?

Все CI У инструментов есть способы публиковать результаты теста, чтобы сделать их очень видимыми, чтобы пройти сбой теста и сделать некоторую отчетность.

Так как мы говорим о PowerShell Трубопровод, мы, скорее всего, уже используем Petter, чтобы проверить наш код PowerShell. Pets может выпить результаты в том же XML Формат как nunit и эти nunit XML Файлы могут быть использованы и опубликованы большинством CI инструменты.

Это имеет много смысла использовать эту интеграцию для PEST как универсальную CI клей и беги наш PSScriptanalyzer Проверяет в качестве промежуточных испытаний. Давайте посмотрим на возможные способы сделать это.

Один компьютерный тест, проверка psscriptanalyzer вывод

Вот, наверное, самый простой способ вызвать PSScriptanalyzer Из прома:

Describe 'PSScriptAnalyzer analysis' {    
    $ScriptAnalyzerResults = Invoke-ScriptAnalyzer -Path '.\Example.ps1' -Severity Warning

    It 'Should not return any violation' {
        $ScriptAnalyzerResults | Should BeNullOrEmpty
    }
}

Здесь мы проверяем все правила, которые имеют серьезность предупреждения в течение одного единственного теста. Затем мы полагаемся на тот факт, что если PSScriptanalyzer Возвращает что-то, это означает, что они были хотя бы одно нарушение, а если PSScriptanalyzer ничего не возвращается, все хорошо.

Здесь здесь 2 проблемы:

  • Мы оцениваем целую кучу правил в одном тесте, поэтому название теста не может сказать нам Какое правило было нарушено
  • Если есть более чем одно нарушение, пришное сообщение дает нам бесполезную информацию

Как бесполезно? Ну, давайте посмотрим:

Invoke-Pester -Script '.\Example.Tests.ps1'
Executing all tests in .\Example.Tests.ps1

Executing script .\Example.Tests.ps1

  Describing PSScriptAnalyzer analysis
    [-] Should not return any violation 1.52s
      Expected: value to be empty but it was {Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord}
      at , E:\Example.Tests.ps1: line 5
      5: $ScriptAnalyzerResults | Should BeNullOrEmpty
Tests completed in 1.52s
Tests Passed: 0, Failed: 1, Skipped: 0, Pending: 0, Inconclusive: 0

Сообщение с отказом в Petter дает нам тип объекта PSScriptanalyzer результаты, а не их содержание.

Один компьютерный тест на PSScriptanalyzer правило

Это довольно типичный (и лучше) способ бегать PSScriptanalyzer Проверяет через Pester.

Describe 'PSScriptAnalyzer analysis' {    
    $ScriptAnalyzerRules = Get-ScriptAnalyzerRule -Name "PSAvoid*"

    Foreach ( $Rule in $ScriptAnalyzerRules ) {
        It "Should not return any violation for the rule : $($Rule.RuleName)" {
            Invoke-ScriptAnalyzer -Path ".\Example.ps1" -IncludeRule $Rule.RuleName |
            Should BeNullOrEmpty
        }
    }
}

В этом случае первый шаг — получить список правил, которые мы хотим оценить. Здесь я изменил список правил: все правила, которые имеют имя, начиная с Psavoid Отказ Это просто чтобы показать, что мы можем отфильтровать правила по имени, а также путем серьезности.

Затем мы зацикливаемся через этот список правил и проверим тест на баржи, оценивая каждое правило, один за другим. Как мы можем видеть ниже, вывод гораздо полезнее:

Это определенно лучше, но мы все еще сталкиваемся с той же проблемой, что и раньше, потому что было более чем одно нарушение для этого Psavoidusingwmicmdlet правило. Таким образом, мы все еще не получаем имя файла и номер строки.

Мы могли бы использовать вложенную петлю: для каждого правила мы будем расти в каждом файле. Это было бы более гранулированным и снижать риск этой конкретной проблемы. Но если один файл нарушил то же правило, больше один раз, у нас все равно будет та же проблема.

Итак, я решил пойти по другому маршруту, чтобы решить эту проблему: принимая вывод из PSScriptanalyzer и преобразование его в файл результата теста, используя то же самое XML Схема как Pester и Nunit.

Преобразование PSScriptanalyzer Выход на файл результата теста

Для этой цели я написал функцию имени Экспорт-NUNITXML , что доступно В этом модуле Отказ

Вот шаги высокого уровня того, что Экспорт-NUNITXML делает:

  • Возьмите вывод PSScriptanalyzer как его ввод
  • Создать XML Документ, содержащий узел «Тестовый» для каждого входного объекта (ы)
  • Напишите это XML Документ к файлу, указанному через Путь параметр

Вот пример того, как мы можем использовать это в сценарии сборки (в Appveveor , в этом случае):

$ScriptAnalyzerRules = Get-ScriptAnalyzerRule -Severity Warning
$ScriptAnalyzerResult = Invoke-ScriptAnalyzer -Path '.\CustomPSScriptAnalyzerRules\Example.ps1' -IncludeRule $ScriptAnalyzerRules
If ( $ScriptAnalyzerResult ) {  
    $ScriptAnalyzerResultString = $ScriptAnalyzerResult | Out-String
    Write-Warning $ScriptAnalyzerResultString
}
Import-Module '.\Export-NUnitXml\Export-NUnitXml.psm1' -Force
Export-NUnitXml -ScriptAnalyzerResult $ScriptAnalyzerResult -Path '.\ScriptAnalyzerResult.xml'

(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", '.\ScriptAnalyzerResult.xml')
If ( $ScriptAnalyzerResult ) {        
    # Failing the build
    Throw 'There was PSScriptAnalyzer violation(s). See test results for more information.'
}

И вот результат в Аппире:

Просто, читая название тестового корпуса, мы получаем основную информацию: имя правила, имя файла и даже номер строки.

Кроме того, мы можем расширить любой неудачный тест, чтобы получить дополнительную информацию. Например, последние 2 тесты расширяются ниже:

Раздел « Stacktrace » предоставляет дополнительные детали, такие как серьезность правила и фактический оскорбительный код. Другое приятное прикосновение — это то, что сообщение « сообщение об ошибке » дает нам сообщение правила, которое обычно предоставляет действительные рекомендации для исправления проблемы.

Но что если PSScriptanalyzer ничего не возвращается?

Экспорт-NUNITXML делает этот сценарий изящно, потому что его ScriptanalyZerresult Параметр принимает $ Null Отказ В этом случае файл результата теста будет содержать только 1 тестовый случай, и этот тест пройдет.

Так что теперь у нас не только быстрая обратная связь по нашему соблюдению стандартов кодирования, но мы также получаем действий по вопросам действий по улучшению. И помните, этот Нунит XML Формат широко поддерживается в мире CI/CD Tooling, так что это будет работать аналогично в TeamCity, Microsoft VST, а также другие …

Этот пост был первоначально опубликован на mathieubuisson.github.io

Оригинал: «https://dev.to/mathieubuisson/making-psscriptanalyzer-a-first-class-citizen-in-a-powershell-ci-pipeline»