The psake/Invoke-Build task drift guard compares nothing against nothing
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Facilidade para iniciantes
- 72/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- powershell
- Domínio
- build-system, testing-qa
Direção de pesquisa
Comece em tests/IBTasks.tests.ps1 nos blocos It chamados 'Parseable by invoke-build' e 'Contains all the tasks that were in the Psake file' e, em seguida, execute a suíte do Pester para reproduzir o falso positivo. Compare a verificação do nome da tarefa com as comparações adjacentes de configurações e assinatura. Está concluído quando os arquivos inalterados passam e uma divergência deliberada do nome da tarefa falha.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
tests/IBTasks.tests.ps1, the It 'Contains all the tasks that were in the Psake file', is the only guard that psake and Invoke-Build still define the same tasks. It cannot fail. Two independent defects cancel each other out, and fixing either one alone turns it red.
What happens
Defect one: $IBTasksResult is $null inside the It that reads it.
$IBTasksResult = $null # Describe body: runs at discovery only
It 'Parseable by invoke-build' {
$IBTasksResult = Start-Job { ... } | Wait-Job | Receive-Job # assigned here
...
}
It 'Contains all the tasks that were in the Psake file' {
$IBTaskNames = $IBTasksResult.all.name # ...and $null here
Each It block runs in its own scope, so the assignment in the first block is not visible in the second, and the $IBTasksResult = $null at the Describe level runs during discovery rather than during the run. $IBTaskNames is therefore $null.
Defect two: $psakeTaskNames is a collection of $null.
$psakeTaskNames = Start-Job -ScriptBlock {
Invoke-PSake -docs -buildfile $using:psakeFilePath | Where-Object name -notmatch '^(default|\?)$' | ForEach-Object name
} | Wait-Job | Receive-Job
Invoke-PSake -docs formats a table to the output stream. What crosses the job boundary is therefore format records, not task objects, and a format record has no Name property. Measured on this repository at 484f24f:
Deserialized.Microsoft.PowerShell.Commands.Internal.Format.FormatStartData 1
Deserialized.Microsoft.PowerShell.Commands.Internal.Format.GroupStartData 1
Deserialized.Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData 17
Deserialized.Microsoft.PowerShell.Commands.Internal.Format.GroupEndData 1
Deserialized.Microsoft.PowerShell.Commands.Internal.Format.FormatEndData 1
$psakeTaskNames.Count = 21
non-null entries = 0
Where-Object name -notmatch ... also passes all 21 through, because $null -notmatch anything is true.
The two cancel. The loop becomes foreach ($taskItem in @($null, $null, ...)), the test is $null -notin $null, which evaluates to False, so the throw never fires. The closing assertion is @($null, $null, ...) | Should -Not -BeNullOrEmpty, which passes because the array has 21 elements even though every one of them is $null.
Measured: the guard does not fire on the divergence it exists to catch
Renaming a single task in the built IB.tasks.ps1 so it no longer matches psakeFile.ps1 — exactly the drift the test was written for:
-Task Sign SignModule, SignCatalog
+Task RenamedSignTask SignModule, SignCatalog
Describing Invoke-Build Tasks
[+] IB.tasks.ps1 exists
[+] Parseable by invoke-build
[+] Contains all the tasks that were in the Psake file <-- should be red
Tests Passed: 8, Failed: 0
PowerShell 7.6.5, Pester 6.1.0, psake 5.0.4, Windows 11.
Why it matters
Divergence between the two task files is not hypothetical; it is this repository's most productive defect class, and it reaches Invoke-Build consumers only.
- #178:
IB.tasks.ps1readTest.CodeCoverage.OutputFormatwhile the defaults defineOutputFileFormat, so no Invoke-Build consumer had a working code coverage format. - #193:
IB.tasks.ps1never passedSkipValidation, so$PSBPreference.Sign.SkipCertificateValidationwas dead for every Invoke-Build consumer while it worked for psake consumers.
Both were found by hand and then covered by the other Describe blocks in this same file — the settings-path comparison and the signing-settings comparison — which do work. The task-name comparison, the oldest of the three and the one everything else was layered on top of, has never worked. A task added to psakeFile.ps1 and forgotten in IB.tasks.ps1 would ship silently today.
Options
- Fix both defects and keep the test. Move the whole thing into one
It(or hoist the Invoke-Build run into aBeforeAllthat assigns to a$script:variable), and get real task names out of psake withGet-PSakeScriptTasks -buildFile $psakeFilePathinstead ofInvoke-PSake -docs, which returns objects rather than a formatted table. Both halves must change together; either alone makes the test fail for the wrong reason. - Replace it with a static comparison, like its two neighbours. The
Settings referenced by the task filesandSigning settings referenced by the task filesblocks in this same file parse the two task files with a regular expression and compare, with no job, no psake invocation, and no format-record hazard. Task names could be compared the same way, which would also make the test fast and immune to psake's output format changing again. - Delete it. It has never tested anything, and the two working
Describeblocks below it cover the settings-level drift that has actually bitten. This is the cheapest option and the one that loses real coverage, since neither of those blocks can see a task that exists in one file and not the other.
(2) looks like the best value: it keeps the coverage, matches the pattern the rest of the file already uses, and removes the job entirely.
Related: #178, #193.
- Linguagem predominante
- PowerShell
- Estrelas
- 145
- Forks
- 27
- Merge médio
- 10h 16min
- PRs com merge (30d)
- 34
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de psake/PowerShellBuild
-
Nothing tests the Build-PSBuildUpdatableHelp branch that deletes a consumer's output directory Abertabug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
psake/PowerShellBuild#218 · 1 comentário ·
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
psake/PowerShellBuild#211 · 1 comentário ·
-
CI: Install the built module from a local repository to verify install-time dependency behaviour Abertaenhancement github_actions
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 68/100
psake/PowerShellBuild#229 ·
-
bug
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 55/100
psake/PowerShellBuild#222 ·
-
bug
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 68/100
psake/PowerShellBuild#221 ·
Todas as issues de psake/PowerShellBuild
Issues semelhantes
-
comp/dashboard P3 type/bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 86/100
NousResearch/hermes-agent#117722 ·
-
Use zstd compression? AbertaNeeds Design Priority: Wishlist
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
elementary/flatpak-platform#253 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
objectionary/hone-maven-plugin#1060 ·
-
0.kind: build failure
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
-
Update Vish to 1.1.5 Abertapackage-update
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
oSoWoSo/vOid_Community_repOsitory#144 · 1 comentário ·