Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions docs/progress/2026-08-14-avm-docs-parity-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# AVM documentation parity template

**Status**: complete
**Started**: 2026-08-14
**Updated**: 2026-08-15
**Branch**: `jaredfholgate-avm-docs-parity-template`

## Outcome

Add the finalized Scriban templates, semantic model index template, and
PowerShell verifiers for Bicep AVM README documentation parity.

## Checklist

- [x] Add the templates and verifier under `scripts/avm-docs/`.
- [x] Add all-module reporting with genuine compilation failures retained.
- [x] Document invocation and validation scope.
- [x] Validate PowerShell syntax and the repository pre-commit gate.

## Dependencies

- Validated against `Azure/bicep-registry-modules` commit
`55c62d45eaf6675c09bf663616c3e7fdd8c4560f`.

## Validation

- `Test-AvmDocsParity.ps1` parses without PowerShell syntax errors.
- The definitive full run compared 573 modules in `00:06:59.1954771`: 572
generated READMEs matched byte-for-byte, one module had a genuine compilation
failure, and 49 semantic-model mismatches were retained in detailed reports.
- The failure was `avm/ptn/app/container-job-toolkit` with BCP426, BCP104,
BCP287, and BCP036; no README was generated for that module.
- `validation.txt` includes those captured compiler diagnostics rather than only
referring to the per-module stderr report.
- The verifier does not create or modify `bicepconfig.json`. All-module reports
record the Bicep version and executable SHA256 alongside the comparison data.
- The verifier uses Bicep's renamed `--custom-template-value` CLI option when
passing Scriban template values.
- Of the semantic-model mismatches, 34 involved parameters and 15 involved
example names.
- The final templates match their validated source after LF normalization, both
PowerShell scripts parse, and `./build.ps1 pre-commit` passed.
26 changes: 26 additions & 0 deletions docs/progress/2026-08-17-avm-docs-config-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# AVM docs configuration contract

**Status**: complete
**Started**: 2026-08-17
**Updated**: 2026-08-17
**Branch**: `jaredfholgate-avm-docs-parity-template`

## Outcome

Align the AVM documentation-parity configuration and its script references with
the final Azure/bicep documentation configuration contract.

## Checklist

- [x] Rename the configuration to `bicepdocsconfig.json`.
- [x] Add the Bicep docs configuration schema and explicit `main.bicep` input
selection.
- [x] Preserve the example reassignment settings and update all references.
- [x] Validate JSON, PowerShell syntax, and the pre-commit gate.

## Validation

- `bicepdocsconfig.json` parses as JSON and contains the required schema,
input include, input exclude, and three example reassignments.
- Both parity scripts parse without PowerShell syntax errors.
- `./build.ps1 pre-commit` passed.
22 changes: 22 additions & 0 deletions docs/progress/2026-08-18-avm-docs-config-json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# AVM docs configuration JSON correction

**Status**: complete
**Started**: 2026-08-18
**Updated**: 2026-08-18
**Branch**: `jaredfholgate-avm-docs-parity-template`

## Outcome

Remove the trailing comma that prevents Bicep from parsing the AVM documentation
parity `bicepconfig.json`.

## Checklist

- [x] Remove the trailing comma after the final example reassignment.
- [x] Validate strict JSON parsing and targeted PowerShell syntax.

## Validation

- .NET strict JSON parsing with trailing commas disabled passed.
- Both parity scripts parse without PowerShell syntax errors.
- `./build.ps1 pre-commit` passed.
30 changes: 30 additions & 0 deletions docs/progress/2026-08-18-avm-docs-final-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# AVM docs final configuration contract

**Status**: complete
**Started**: 2026-08-18
**Updated**: 2026-08-18
**Branch**: `jaredfholgate-avm-docs-parity-template`

## Outcome

Align the AVM documentation parity utility with the accepted Bicep
`bicepconfig.json` documentation contract and `docs generate` command shape.

## Checklist

- [x] Use a root `bicepconfig.json` with documentation-scoped example
reassignments.
- [x] Use standard configuration discovery and copy the configuration into the
validation working checkout.
- [x] Use `docs generate --stdout` for semantic model output.
- [x] Represent exported types and variables in semantic templates and indexes.
- [x] Validate JSON, PowerShell syntax, and the pre-commit gate.

## Validation

- `bicepconfig.json` parses as JSON, contains only the `documentation` section,
and retains all three example reassignments.
- Both parity scripts parse without PowerShell syntax errors.
- Static contract checks confirm no `--config-file-path` or `docs output`
invocations remain.
- `./build.ps1 pre-commit` passed.
176 changes: 176 additions & 0 deletions scripts/avm-docs/Invoke-AllAvmDocsParity.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string] $BicepPath,

[Parameter(Mandatory)]
[string] $SourceRepositoryPath,

[Parameter(Mandatory)]
[string] $WorkingRepositoryPath,

[Parameter(Mandatory)]
[string] $OutputPath,

[int] $ThrottleLimit = 8,

[string] $VerifierPath = (Join-Path $PSScriptRoot 'Test-AvmDocsParity.ps1')
)

$ErrorActionPreference = 'Stop'
$stopwatch = [Diagnostics.Stopwatch]::StartNew()
$templatePath = Join-Path $PSScriptRoot 'README.byte-parity.scriban'
$modelIndexTemplatePath = Join-Path $PSScriptRoot 'model-index.scriban'
$docsConfigPath = Join-Path $PSScriptRoot 'bicepconfig.json'
$modulePaths = @(Get-ChildItem (Join-Path $SourceRepositoryPath 'avm') -Recurse -Filter main.bicep -File |
Where-Object {
(Test-Path (Join-Path $_.DirectoryName 'README.md')) -and
(Test-Path (Join-Path $_.DirectoryName 'main.json'))
} |
ForEach-Object { [IO.Path]::GetRelativePath($SourceRepositoryPath, $_.DirectoryName).Replace('\', '/') } |
Sort-Object)

New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
Copy-Item -LiteralPath $docsConfigPath -Destination (Join-Path $WorkingRepositoryPath 'bicepconfig.json') -Force

$results = @($modulePaths | ForEach-Object -Parallel {
$modulePath = $_
$moduleRoot = Join-Path $using:WorkingRepositoryPath $modulePath
$moduleOutputPath = Join-Path $using:OutputPath $modulePath
New-Item -ItemType Directory -Path $moduleOutputPath -Force | Out-Null

try {
$result = & $using:VerifierPath `
-BicepPath $using:BicepPath `
-AvmRepositoryPath $using:WorkingRepositoryPath `
-ExpectedRepositoryPath $using:SourceRepositoryPath `
-ModulePaths @($modulePath) `
-TemplatePath $using:templatePath `
-ModelIndexTemplatePath $using:modelIndexTemplatePath `
-GenerateInPlace `
-PassThru

$fragmentRoot = Join-Path $moduleRoot '.bicep-docs-parity'
$generatedPath = Join-Path $moduleRoot 'README.md'
Copy-Item (Join-Path $fragmentRoot 'README.stderr.txt') (Join-Path $moduleOutputPath 'README.stderr.txt') -Force
if (Test-Path (Join-Path $fragmentRoot 'model-index.tsv')) {
Copy-Item (Join-Path $fragmentRoot 'model-index.tsv') (Join-Path $moduleOutputPath 'model-index.tsv') -Force
}
if (Test-Path (Join-Path $fragmentRoot 'model-index.stderr.txt')) {
Copy-Item (Join-Path $fragmentRoot 'model-index.stderr.txt') (Join-Path $moduleOutputPath 'model-index.stderr.txt') -Force
}

if (-not $result.ReadmeMatches) {
$diffPath = Join-Path $moduleOutputPath 'README.diff.txt'
git --no-pager diff --no-index -- (Join-Path $using:SourceRepositoryPath "$modulePath/README.md") $generatedPath 2>&1 |
Set-Content $diffPath
}

[pscustomobject]@{
Module = $modulePath
Matches = $result.Matches
ReadmeMatches = $result.ReadmeMatches
ModelMatches = $result.ModelMatches
ExpectedParameterCount = $result.ExpectedParameterCount
ActualParameterCount = $result.ActualParameterCount
MissingParameters = $result.MissingParameters
UnexpectedParameters = $result.UnexpectedParameters
ExpectedExampleCount = $result.ExpectedExampleCount
ActualExampleCount = $result.ActualExampleCount
MissingExamples = $result.MissingExamples
UnexpectedExamples = $result.UnexpectedExamples
ExpectedSha256 = $result.ExpectedSha256
ActualSha256 = $result.ActualSha256
GeneratedReadme = $generatedPath
Error = $null
}
} catch {
$fragmentRoot = Join-Path $moduleRoot '.bicep-docs-parity'
foreach ($logName in @('README.stderr.txt', 'model-index.stderr.txt')) {
$logPath = Join-Path $fragmentRoot $logName
if (Test-Path $logPath) {
Copy-Item $logPath (Join-Path $moduleOutputPath $logName) -Force
}
}

[pscustomobject]@{
Module = $modulePath
Matches = $false
ReadmeMatches = $false
ModelMatches = $false
ExpectedParameterCount = $null
ActualParameterCount = $null
MissingParameters = $null
UnexpectedParameters = $null
ExpectedExampleCount = $null
ActualExampleCount = $null
MissingExamples = $null
UnexpectedExamples = $null
ExpectedSha256 = $null
ActualSha256 = $null
GeneratedReadme = $null
Error = $_.Exception.Message
}
}
} -ThrottleLimit $ThrottleLimit)

$results = @($results | Sort-Object Module)
$results | Export-Csv (Join-Path $OutputPath 'comparison.csv') -NoTypeInformation
$results | ConvertTo-Json -Depth 5 | Set-Content (Join-Path $OutputPath 'comparison.json')
$semanticMismatches = @($results | Where-Object { -not $_.Error -and -not $_.ModelMatches })
$semanticMismatches | Export-Csv (Join-Path $OutputPath 'model-mismatches.csv') -NoTypeInformation

$stopwatch.Stop()
$summary = [pscustomobject]@{
BicepVersion = (& $BicepPath --version)
BicepExecutableSha256 = (Get-FileHash $BicepPath -Algorithm SHA256).Hash
RepositoryCommit = (git -C $SourceRepositoryPath rev-parse HEAD)
TotalModules = $results.Count
GeneratedReadmes = @($results | Where-Object GeneratedReadme).Count
Matches = @($results | Where-Object Matches).Count
ReadmeMismatches = @($results | Where-Object { -not $_.ReadmeMatches }).Count
ModelMismatches = @($results | Where-Object { -not $_.ModelMatches }).Count
SemanticModelMismatches = $semanticMismatches.Count
ParameterModelMismatches = @($semanticMismatches | Where-Object { $_.MissingParameters -or $_.UnexpectedParameters }).Count
ExampleModelMismatches = @($semanticMismatches | Where-Object { $_.MissingExamples -or $_.UnexpectedExamples }).Count
Errors = @($results | Where-Object { $_.Error }).Count
DurationSeconds = [Math]::Round($stopwatch.Elapsed.TotalSeconds, 3)
Duration = $stopwatch.Elapsed.ToString()
}
$summary | ConvertTo-Json | Set-Content (Join-Path $OutputPath 'summary.json')
$errorDetails = @($results | Where-Object Error | ForEach-Object {
$module = $_.Module
$stderrPath = Join-Path $OutputPath "$module/README.stderr.txt"
$diagnostics = if (Test-Path $stderrPath) {
@(Get-Content $stderrPath | Where-Object { $_ -match ' : Error ' })
} else {
@()
}

if ($diagnostics.Count -gt 0) {
@("$module`:") + @($diagnostics | ForEach-Object { " $_" })
} else {
"$module`: $($_.Error)"
}
})
@(
"Bicep version: $($summary.BicepVersion)"
"Bicep executable SHA256: $($summary.BicepExecutableSha256)"
"Repository commit: $($summary.RepositoryCommit)"
"Total modules compared: $($summary.TotalModules)"
"Generated READMEs: $($summary.GeneratedReadmes)"
"Byte-for-byte matches: $($summary.Matches)"
"Generation errors: $($summary.Errors)"
"Semantic model mismatches: $($summary.SemanticModelMismatches)"
"Parameter model mismatches: $($summary.ParameterModelMismatches)"
"Example model mismatches: $($summary.ExampleModelMismatches)"
"Duration: $($summary.Duration)"
""
"Generation errors:"
$errorDetails
) | Set-Content (Join-Path $OutputPath 'validation.txt')
$summary | Format-List

if ($results.ReadmeMatches -contains $false) {
exit 1
}
Loading
Loading