Skip to content

Commit

Permalink
Add docs reference for AVM latest version (#3076)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Oct 2, 2024
1 parent 9085acb commit 371e717
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ data/types_index.json
*.log
*.min.json
docs/**/rules/metadata.json
docs/**/rules/avm_versions.json
6 changes: 3 additions & 3 deletions docs/customization/using-custom-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ When naming custom rules we recommend that you:

## Related content

- [Using Bicep source](using-bicep.md)
- [Using templates](using-templates.md)
- [Creating your pipeline](creating-your-pipeline.md)
- [Using Bicep source](../using-bicep.md)
- [Using templates](../using-templates.md)
- [Creating your pipeline](../creating-your-pipeline.md)

*[IaC]: Azure Resource Manager
2 changes: 1 addition & 1 deletion docs/en/rules/Azure.VMSS.ZoneBalance.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2023-09-01' = {
}
```

<!-- external:avm res/compute/virtual-machine-scale-set zoneBalance -->
<!-- external:avm avm/res/compute/virtual-machine-scale-set:0.4.0 zoneBalance -->

## LINKS

Expand Down
50 changes: 41 additions & 9 deletions docs/hooks/shortcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import logging
import os
import re
import json

from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.files import File, Files
Expand Down Expand Up @@ -57,7 +58,7 @@ def replace(match: re.Match) -> str:
type, args = match.groups()
args = args.strip()
if type == "avm":
return _external_reference_avm(args)
return _external_reference_avm(args, page)

raise RuntimeError(f"Unknown shortcode external:{type}")

Expand Down Expand Up @@ -145,7 +146,7 @@ def _reference_block(style: str, title: str, text: str = "") -> str:
lines = text.replace('\r\n', '\n').replace('\r', '\n').replace('\n', '\n ').strip()
return f"!!! {style} \"{title}\"\n {lines}"

def _external_reference_avm(text: str) -> str:
def _external_reference_avm(text: str, page: Page) -> str:
'''Create a reference to AVM.'''

# Extract the reference.
Expand All @@ -156,22 +157,53 @@ def _external_reference_avm(text: str) -> str:
pathParts = referenceParts[0].split(':')

avm_path = pathParts[0]
avm_suggested_version = ''

# Use the suggested version if set.
avm_suggested_version = ''
if len(pathParts) > 1:
avm_suggested_version = pathParts[1]

# Build the body of the reference.
syntax = f"br/public:{avm_path}:<version>"
suggestion_body = ''
# Load latest version from cache.
avm_latest_version = _avm_module_latest_tag(page, avm_path)

# Add the reference syntax.
syntax_body = _avm_code_reference(avm_path, None)

# Add suggested version.
suggestion_body = ''
if avm_suggested_version != '':
suggested = f"br/public:{avm_path}:{avm_suggested_version}"
suggestion_body = f"\n\nFor example:\n\n```text\n{suggested}\n```"
suggestion_body = f"\n\nFor example:{_avm_code_reference(avm_path, avm_suggested_version)}"

# Add latest version.
latest_body = ''
if avm_latest_version != '':
latest_body = f"\n\nTo use the latest version:{_avm_code_reference(avm_path, avm_latest_version)}"

return _reference_block(
style = "Example",
title = f"Configure with [Azure Verified Modules](https://github.com/Azure/bicep-registry-modules/tree/main/{avm_path})",
text = f"A pre-built module is available on the Azure Bicep public registry.\nTo reference the module, please use the following syntax:\n\n```text\n{syntax}\n```{suggestion_body}"
text = f"A pre-built module provided by Microsoft is available from the Azure Bicep public registry.\nTo reference the module, please use the following syntax:{syntax_body}{suggestion_body}{latest_body}"
)

def _avm_code_reference(path: str, version: str) -> str:
'''Create a reference to Bicep public registry.'''

if version == '' or version == None:
version = '<version>'

return f"\n\n```text\nbr/public:{path}:{version}\n```"

def _avm_module_latest_tag(page: Page, name: str) -> str:
'''Load latest AVM module version details for any examples.'''

log.debug(f"Loading avm module versions page: {page.abs_url}")

latest = ''

file: str = os.path.join(os.path.dirname(page.file.abs_src_path), 'avm_versions.json')
with open(file) as f:
data = json.load(f)
if data.get(name, None) != None and data[name].get('Latest', None) != None:
latest = data[name]['Latest']

return latest
51 changes: 46 additions & 5 deletions pipeline.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ task Analyze Build, Dependencies, {
}

# Synopsis: Build documentation
task BuildDocs BuildRuleDocs, BuildBaselineDocs
task BuildDocs BuildRuleDocs, BuildBaselineDocs, BuildRuleMetadataCache, BuildAVMVersionCache

# Synopsis: Build table of content for rules
task BuildRuleDocs Build, Dependencies, {
Expand All @@ -369,6 +369,16 @@ task BuildRuleDocs Build, Dependencies, {
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name index -OutputPath ./docs/en/rules/ -Culture 'en' -Path ./RuleToc.Doc.ps1;
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name module -OutputPath ./docs/en/rules/ -Culture 'en' -Path ./RuleToc.Doc.ps1;
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name resource -OutputPath ./docs/en/rules/ -Culture 'en' -Path ./RuleToc.Doc.ps1;

# Spanish
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name index -OutputPath ./docs/es/rules/ -Culture 'es' -Path ./RuleToc.Doc.ps1;
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name module -OutputPath ./docs/es/rules/ -Culture 'es' -Path ./RuleToc.Doc.ps1;
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name resource -OutputPath ./docs/es/rules/ -Culture 'es' -Path ./RuleToc.Doc.ps1;
}

task BuildRuleMetadataCache {
Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.Azure);

$metadata = @{}
Get-PSRule -Module PSRule.Rules.Azure -Baseline Azure.All -Culture 'en' | ForEach-Object {

Expand Down Expand Up @@ -397,10 +407,6 @@ task BuildRuleDocs Build, Dependencies, {
}
$metadata | ConvertTo-Json -Depth 5 | Set-Content -Path ./docs/en/rules/metadata.json -Force;

# Spanish
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name index -OutputPath ./docs/es/rules/ -Culture 'es' -Path ./RuleToc.Doc.ps1;
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name module -OutputPath ./docs/es/rules/ -Culture 'es' -Path ./RuleToc.Doc.ps1;
$Null = './out/modules/PSRule.Rules.Azure' | Invoke-PSDocument -Name resource -OutputPath ./docs/es/rules/ -Culture 'es' -Path ./RuleToc.Doc.ps1;
$metadata = @{}
Get-PSRule -Module PSRule.Rules.Azure -Baseline Azure.All -Culture 'es' | ForEach-Object {

Expand Down Expand Up @@ -430,6 +436,41 @@ task BuildRuleDocs Build, Dependencies, {
$metadata | ConvertTo-Json -Depth 5 | Set-Content -Path ./docs/es/rules/metadata.json -Force;
}

task BuildAVMVersionCache {
# Get unique module paths for any included modules.
$modulePaths = Get-ChildItem -Path docs/**/rules/*.md | ForEach-Object {
Get-Content -Path $_.FullName | Where-Object {
$_ -like "<!-- external:avm * -->"
}
} | ForEach-Object {
$_.Replace("<!-- external:avm ", "").Replace(" -->", "").Split(" ")[0].Split(":")[0]
} | Select-Object -Unique

$avmVersions = @{}

# For each module, get the latest version and update the data.
$modulePaths | ForEach-Object {
$modulePath = $_
try {
$latest = (Invoke-RestMethod -Method Get -Uri "https://mcr.microsoft.com/v2/bicep/$modulePath/tags/list" -ErrorAction Stop -ContentType 'application/json').tags | Sort-Object -Descending | Select-Object -First 1

if (![String]::IsNullOrWhiteSpace($latest)) {
$avmVersions[$modulePath] = [PSCustomObject]@{
Latest = $latest.ToString()
}
}
}
catch {
Write-Warning "Failed to get version for: '$modulePath'"
}
}

$avmVersions.GetEnumerator() | Select-Object -Property Name, @{ Name = 'Latest'; Expression = { $_.Value.Latest } } | Sort-Object -Property Name | Format-Table -Property Name, Latest -AutoSize

$avmVersions | ConvertTo-Json -Depth 5 | Set-Content -Path ./docs/en/rules/avm_versions.json -Encoding utf8 -Force;
$avmVersions | ConvertTo-Json -Depth 5 | Set-Content -Path ./docs/es/rules/avm_versions.json -Encoding utf8 -Force;
}

# Synopsis: Build table of content for baselines
task BuildBaselineDocs Build, Dependencies, {
Import-Module (Join-Path -Path $PWD -ChildPath out/modules/PSRule.Rules.Azure) -Force;
Expand Down

0 comments on commit 371e717

Please sign in to comment.