Skip to content
Merged
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ In this revision:
compare runtime logic into the template
- the checked-in governance proof contract for those surfaces lives in
`docs/policy/docker-execution-profile-governance-surface.json`
- the checked-in capability-manifest schema for descendant-facing CompareVI
contract proof lives in
`docs/schemas/labview-template-comparevi-capabilities-v1.schema.json`
- the checked-in Docker lane-policy schema for descendant-facing policy proof
lives in `docs/schemas/labview-template-docker-lane-policy-v1.schema.json`
- the checked-in Docker receipt schema for descendant-facing proof lives in
Expand All @@ -129,6 +132,9 @@ Generated repositories now include:
- `.github/workflows/vi-history.yml`
- `docs/VI_HISTORY_CAPABILITY.md`

The checked-in schema contract for `.github/comparevi/capabilities.json` lives
at `docs/schemas/labview-template-comparevi-capabilities-v1.schema.json`.

Generated `validate.yml` now fails closed unless the pinned CompareVI.Tools
bundle exposes `consumerContract.capabilities.viHistory`, then runs the hosted
consumer smoke against the same released producer-native pin.
Expand Down
2 changes: 2 additions & 0 deletions docs/COMPAREVI_PLATFORM_INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Generated `validate.yml` should stay lightweight while still consuming the
released CompareVI.Tools bundle through the distributed capability manifest:

1. read `.github/comparevi/capabilities.json`
- canonical capability-manifest schema source:
`LabVIEW-Community-CI-CD/LabviewGitHubCiTemplate/docs/schemas/labview-template-comparevi-capabilities-v1.schema.json`
2. resolve `authoritativeConsumerPin`
3. download `CompareVI.Tools-$pin.zip` from the released compare bundle
4. fail closed unless the manifest exposes `consumerContract.capabilities.viHistory`
Expand Down
2 changes: 2 additions & 0 deletions docs/CONSUMER_PROVING_RAIL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ standing-priority work.
adoption
- the checked-in execution-profile governance proof contract lives in
`docs/policy/docker-execution-profile-governance-surface.json`
- the checked-in CompareVI capability-manifest schema lives in
`docs/schemas/labview-template-comparevi-capabilities-v1.schema.json`
- the checked-in Docker lane-policy schema for that scaffold lives in
`docs/schemas/labview-template-docker-lane-policy-v1.schema.json`
- the checked-in Docker receipt schema for that scaffold lives in
Expand Down
2 changes: 2 additions & 0 deletions docs/VI_HISTORY_CAPABILITY_DISTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Generated repositories receive:
- `.github/comparevi/lineage.json`
- `.github/workflows/vi-history.yml`
- `docs/VI_HISTORY_CAPABILITY.md`
- canonical capability-manifest schema source:
`LabVIEW-Community-CI-CD/LabviewGitHubCiTemplate/docs/schemas/labview-template-comparevi-capabilities-v1.schema.json`

For `docker` and `mixed` renders, `.github/comparevi/capabilities.json` also
records the Producer-published Docker capability contract pointer:
Expand Down
220 changes: 220 additions & 0 deletions docs/schemas/labview-template-comparevi-capabilities-v1.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/LabVIEW-Community-CI-CD/LabviewGitHubCiTemplate/blob/develop/docs/schemas/labview-template-comparevi-capabilities-v1.schema.json",
"title": "LabVIEW Template CompareVI Capabilities Manifest",
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"templateDistributorRepository",
"templateDistributorBranch",
"capabilities"
],
"properties": {
"schema": {
"const": "labview-template/comparevi-capabilities@v1"
},
"templateDistributorRepository": {
"const": "LabVIEW-Community-CI-CD/LabviewGitHubCiTemplate"
},
"templateDistributorBranch": {
"const": "develop"
},
"capabilities": {
"type": "object",
"additionalProperties": false,
"required": [
"viHistory"
],
"properties": {
"viHistory": {
"$ref": "#/$defs/viHistoryCapability"
},
"dockerProfile": {
"$ref": "#/$defs/dockerProfileCapability"
}
}
}
},
"$defs": {
"releaseAssetName": {
"type": "string",
"pattern": "^CompareVI\\.Tools-.+\\.zip$"
},
"viHistoryContractPaths": {
"type": "object",
"additionalProperties": false,
"required": [
"historyFacade",
"localRuntimeProfiles",
"localOperatorSession",
"diagnosticsCommentRenderer",
"hostedNiLinuxRunner"
],
"properties": {
"historyFacade": {
"const": "consumerContract.historyFacade"
},
"localRuntimeProfiles": {
"const": "consumerContract.localRuntimeProfiles"
},
"localOperatorSession": {
"const": "consumerContract.localOperatorSession"
},
"diagnosticsCommentRenderer": {
"const": "consumerContract.diagnosticsCommentRenderer"
},
"hostedNiLinuxRunner": {
"const": "consumerContract.hostedNiLinuxRunner"
}
}
},
"viHistoryCapability": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled",
"distributionRole",
"upstreamProducerRepository",
"upstreamCapabilitySchema",
"distributionModel",
"authoritativeConsumerPin",
"releaseAssetName",
"releaseMetadataPath",
"generatedWorkflowPath",
"integrationDocPath",
"contractPaths"
],
"properties": {
"enabled": {
"type": "boolean"
},
"distributionRole": {
"const": "template-distributor"
},
"upstreamProducerRepository": {
"const": "LabVIEW-Community-CI-CD/compare-vi-cli-action"
},
"upstreamCapabilitySchema": {
"const": "comparevi-tools/vi-history-capability@v1"
},
"distributionModel": {
"const": "release-bundle"
},
"authoritativeConsumerPin": {
"type": "string",
"minLength": 1
},
"releaseAssetName": {
"$ref": "#/$defs/releaseAssetName"
},
"releaseMetadataPath": {
"const": "comparevi-tools-release.json"
},
"generatedWorkflowPath": {
"const": ".github/workflows/vi-history.yml"
},
"integrationDocPath": {
"const": "docs/VI_HISTORY_CAPABILITY.md"
},
"contractPaths": {
"$ref": "#/$defs/viHistoryContractPaths"
}
}
},
"dockerProfileCapability": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled",
"distributionRole",
"upstreamProducerRepository",
"upstreamCapabilitySchema",
"distributionModel",
"authoritativeConsumerPin",
"releaseAssetName",
"releaseMetadataPath",
"bundleImportPath",
"authoritativeImageContractSource",
"requestedExecutionProfile",
"hostedSurfaceRetained"
],
"properties": {
"enabled": {
"const": true
},
"distributionRole": {
"const": "template-distributor"
},
"upstreamProducerRepository": {
"const": "LabVIEW-Community-CI-CD/compare-vi-cli-action"
},
"upstreamCapabilitySchema": {
"const": "comparevi-tools/docker-profile-capability@v1"
},
"distributionModel": {
"const": "release-bundle"
},
"authoritativeConsumerPin": {
"type": "string",
"minLength": 1
},
"releaseAssetName": {
"$ref": "#/$defs/releaseAssetName"
},
"releaseMetadataPath": {
"const": "comparevi-tools-release.json"
},
"bundleImportPath": {
"const": "tools/CompareVI.Tools/CompareVI.Tools.psd1"
},
"authoritativeImageContractSource": {
"const": "consumerContract.dockerImageContract"
},
"requestedExecutionProfile": {
"enum": [
"docker",
"mixed"
]
},
"hostedSurfaceRetained": {
"type": "boolean"
}
},
"allOf": [
{
"if": {
"properties": {
"requestedExecutionProfile": {
"const": "docker"
}
}
},
"then": {
"properties": {
"hostedSurfaceRetained": {
"const": false
}
}
}
},
{
"if": {
"properties": {
"requestedExecutionProfile": {
"const": "mixed"
}
}
},
"then": {
"properties": {
"hostedSurfaceRetained": {
"const": true
}
}
}
}
]
}
}
}
61 changes: 38 additions & 23 deletions tests/Test-TemplateSmokeRender.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
$capabilitiesSchemaPath = Join-Path $repoRoot 'docs/schemas/labview-template-comparevi-capabilities-v1.schema.json'
$dockerLanePolicySchemaPath = Join-Path $repoRoot 'docs/schemas/labview-template-docker-lane-policy-v1.schema.json'
$dockerReceiptSchemaPath = Join-Path $repoRoot 'docs/schemas/labview-template-docker-profile-plan-v1.schema.json'
$runnerTemp = if ([string]::IsNullOrWhiteSpace($env:RUNNER_TEMP)) { [System.IO.Path]::GetTempPath() } else { $env:RUNNER_TEMP }
Expand Down Expand Up @@ -79,13 +80,26 @@ try {
$generatedPlatformDoc = Get-Content -LiteralPath $generatedPlatformDocPath -Raw
$generatedProvingDocPath = Join-Path $generatedRoot 'docs/CONSUMER_PROVING_RAIL.md'
$generatedProvingDoc = Get-Content -LiteralPath $generatedProvingDocPath -Raw
$generatedViHistoryDocPath = Join-Path $generatedRoot 'docs/VI_HISTORY_CAPABILITY.md'
$generatedViHistoryDoc = Get-Content -LiteralPath $generatedViHistoryDocPath -Raw
$imageContractSnippet = 'authoritative image-contract source: `consumerContract.dockerImageContract`'
$capabilitySchemaSourcePath = 'LabVIEW-Community-CI-CD/LabviewGitHubCiTemplate/docs/schemas/labview-template-comparevi-capabilities-v1.schema.json'
$dockerDocPath = Join-Path $generatedRoot 'docs/DOCKER_PROFILE.md'
$dockerPolicyPath = Join-Path $generatedRoot '.github/comparevi/docker-lane-policy.json'
$dockerReceiptScriptPath = Join-Path $generatedRoot '.github/comparevi/Emit-DockerProfileReceipt.ps1'
$dockerReceiptPath = Join-Path $generatedRoot 'tests/results/docker-profile/docker-profile-plan.json'
$dockerWorkflowPath = Join-Path $generatedRoot '.github/workflows/docker-profile.yml'

if (-not $generatedReadme.Contains($capabilitySchemaSourcePath)) {
throw 'Generated README is missing the canonical capability-manifest schema source.'
}
if (-not $generatedPlatformDoc.Contains($capabilitySchemaSourcePath)) {
throw 'Generated platform integration doc is missing the canonical capability-manifest schema source.'
}
if (-not $generatedViHistoryDoc.Contains($capabilitySchemaSourcePath)) {
throw 'Generated vi-history capability doc is missing the canonical capability-manifest schema source.'
}

switch ($ExecutionProfile) {
'hosted' {
foreach ($relativePath in @($profileContract.forbiddenOutputs)) {
Expand Down Expand Up @@ -179,23 +193,30 @@ try {
}

$capabilityPath = Join-Path $generatedRoot '.github/comparevi/capabilities.json'
$capability = Get-Content -LiteralPath $capabilityPath -Raw | ConvertFrom-Json -AsHashtable
$capabilityJson = Get-Content -LiteralPath $capabilityPath -Raw
if (-not (Test-Json -Json $capabilityJson -SchemaFile $capabilitiesSchemaPath)) {
throw 'Rendered capability manifest should validate against the checked-in capability-manifest schema.'
}
$capability = $capabilityJson | ConvertFrom-Json -AsHashtable
if (-not $capability.capabilities.viHistory.enabled) {
throw 'Rendered capability manifest should enable vi-history for template smoke.'
}
if ($capability.capabilities.viHistory.authoritativeConsumerPin -ne $CompareViPin) {
throw 'Rendered capability manifest did not preserve the CompareVI.Tools consumer pin.'
}
if ($capability.capabilities.viHistory.contractPaths.historyFacade -ne 'consumerContract.historyFacade') {
throw 'Rendered capability manifest is missing the distributed historyFacade contract path.'
if ($capability.capabilities.viHistory.releaseAssetName -ne "CompareVI.Tools-$CompareViPin.zip") {
throw 'Rendered capability manifest did not preserve the CompareVI.Tools release asset name.'
}
if ($capability.capabilities.viHistory.releaseMetadataPath -ne 'comparevi-tools-release.json') {
throw 'Rendered capability manifest did not preserve the CompareVI.Tools release metadata path.'
}

$dockerCapability = if ($capability.capabilities.ContainsKey('dockerProfile')) {
$capability.capabilities.dockerProfile
}
else {
$null
}
$dockerCapability = if ($capability.capabilities.ContainsKey('dockerProfile')) {
$capability.capabilities.dockerProfile
}
else {
$null
}
switch ($ExecutionProfile) {
'hosted' {
if ($null -ne $dockerCapability) {
Expand All @@ -206,15 +227,6 @@ else {
if ($null -eq $dockerCapability) {
throw 'Docker render should emit a dockerProfile capability entry.'
}
if (-not $dockerCapability.enabled) {
throw 'Docker render should enable the dockerProfile capability entry.'
}
if ($dockerCapability.upstreamCapabilitySchema -ne 'comparevi-tools/docker-profile-capability@v1') {
throw 'Docker render should record the published docker-profile capability schema.'
}
if ($dockerCapability.authoritativeImageContractSource -ne 'consumerContract.dockerImageContract') {
throw 'Docker render should record the authoritative image contract source.'
}
if ($dockerCapability.authoritativeConsumerPin -ne $CompareViPin) {
throw 'Docker render should keep the CompareVI.Tools pin on the dockerProfile capability.'
}
Expand All @@ -238,6 +250,9 @@ else {
}

$dockerDoc = Get-Content -LiteralPath $dockerDocPath -Raw
if (-not $dockerDoc.Contains($capabilitySchemaSourcePath)) {
throw 'Docker render should document the canonical capability-manifest schema source.'
}
foreach ($snippet in @(
'workflow scaffold: `.github/workflows/docker-profile.yml`',
'receipt helper: `.github/comparevi/Emit-DockerProfileReceipt.ps1`',
Expand Down Expand Up @@ -338,11 +353,8 @@ else {
if ($null -eq $dockerCapability) {
throw 'Mixed render should emit a dockerProfile capability entry.'
}
if (-not $dockerCapability.enabled) {
throw 'Mixed render should enable the dockerProfile capability entry.'
}
if ($dockerCapability.authoritativeImageContractSource -ne 'consumerContract.dockerImageContract') {
throw 'Mixed render should record the authoritative image contract source.'
if ($dockerCapability.authoritativeConsumerPin -ne $CompareViPin) {
throw 'Mixed render should keep the CompareVI.Tools pin on the dockerProfile capability.'
}
if ($dockerCapability.releaseAssetName -ne "CompareVI.Tools-$CompareViPin.zip") {
throw 'Mixed render should record the released CompareVI.Tools asset name on the dockerProfile capability.'
Expand All @@ -364,6 +376,9 @@ else {
}

$dockerDoc = Get-Content -LiteralPath $dockerDocPath -Raw
if (-not $dockerDoc.Contains($capabilitySchemaSourcePath)) {
throw 'Mixed render should document the canonical capability-manifest schema source.'
}
foreach ($snippet in @(
'hosted surface retained: `true`',
'receipt helper: `.github/comparevi/Emit-DockerProfileReceipt.ps1`',
Expand Down
Loading
Loading