Skip to content

1.0.0

Choose a tag to compare

@github-actions github-actions released this 02 Aug 23:59
6e2db2f

🌟 [Major]: New PowerShell module v1.0.0 with complete YAML 1.2.2 command suite (#47)

Yaml v1.0.0 is the first functional release of the Yaml PowerShell module on the PowerShell Gallery, delivering a complete YAML 1.2.2 command suite for parsing, validating, formatting, merging, reading, and writing.

New: Complete YAML 1.2.2 command suite

The module provides end-to-end YAML handling, grouped by the task you are doing.

Group Command User outcome
Conversion ConvertFrom-Yaml Parse YAML text into PowerShell objects
Conversion ConvertTo-Yaml Serialize PowerShell objects into YAML text
Files Import-Yaml Read YAML files directly into PowerShell objects
Files Export-Yaml Write PowerShell objects directly to YAML files
Streams Test-Yaml Validate YAML syntax and structure without object construction
Streams Format-Yaml Normalize YAML text with representation-preserving, idempotent output
Streams Merge-Yaml Deep-merge two or more YAML streams with configurable sequence, conflict, and null policies

New: Task-based documentation with a full object-model reference

Every command group ships an in-depth guide that is published as its own documentation section: Conversion, Files, and Streams. The Conversion guide includes a complete YAML-to-PowerShell object model reference, so you can predict the exact shape a document produces before running anything β€” scalar tag resolution to String, Boolean, Int32/Int64/BigInteger, Decimal/Double, DateTime/DateTimeOffset and Byte[]; PSCustomObject note-properties versus -AsHashtable ordered dictionaries; -NoEnumerate; multi-document streams; anchor and alias identity; the !!set, !!omap, !!pairs and !!binary collection tags; and the cases that deliberately fail rather than silently lose data.

New: Native YAML 1.2.2 engine with no third-party dependencies

Parsing and serialization are implemented entirely in PowerShell β€” no YamlDotNet or other runtime dependency. The engine enforces bounded parse, clone, merge, and emit work budgets, avoids arbitrary .NET type activation, and uses iterative graph traversal to stay stable on large or adversarial inputs. Duplicate YAML mapping keys are rejected by design to prevent ambiguous data projection.

New: YAML 1.2.2 conformance across the pipeline

The scanner, parser, constructor, serializer, and emitter are validated against the YAML 1.2.2 specification, including edge cases around BOM handling, NBSP behavior, flow scalars, and tag decoding.


Technical details
  • Consolidates the full YAML draft-stack delivery into release/v1.0.0, including prior preparatory PR slices (#37, #39, #40, #41, #42, #45) and the documentation/layout slice #53. The entry-removal slice (#46) was reverted out of this branch before release, so Remove-YamlEntry is not part of the shipped surface.
  • Implements a fully owned PowerShell YAML 1.2.2 pipeline (scanner -> parser/composer -> constructor -> projector -> serializer -> emitter) with no YamlDotNet dependency.
  • Conformance baseline uses the 402-input yaml-test-suite corpus plus chapter 2 fixtures under tests/fixtures/yaml-spec-1.2.2/chapter-02/.
  • Major is correct on the merits and not only as release framing: the diff deletes src/functions/public/Get-PSModuleTest.ps1, and removing a previously exported command is a breaking change under PSModule Versioning. The Major label also cuts v1.0.0 for the module go-live.
  • Two scalar defects found during the final review pass were corrected before release: folded block scalars with keep chomping (>+) dropped the b-chomped-last feed and could not round-trip trailing empty lines, and double-quoted scalars folded the l-empty lines after an escaped break into a space instead of emitting line feeds. Both have regression coverage in tests/ConvertFrom-Yaml.Tests.ps1.
  • src/manifest.psd1 is removed. Build-PSModule derives PowerShellVersion and CompatiblePSEditions from the #Requires statements it finds in the built root module and overwrites whatever a source manifest declared, and it builds an empty manifest when none exists. The two keys were dead weight duplicating src/header.ps1. The built artifact is unchanged, and tests/Packaging.Tests.ps1 still asserts 7.6/Core directly on the generated manifest.
  • Source layout follows PSModule domain grouping: public commands live under src/functions/public/{Conversion,Files,Streams}/, private helpers mirror those domains with a shared Engine group for helpers reachable from more than one public domain, and each public group carries a <Group>.md overview that Document-PSModule publishes as that section's landing page. Streams is a behavioural domain rather than a catch-all: Test-Yaml, Format-Yaml and Merge-Yaml all operate on YAML text at the representation level and never project to PowerShell objects. Grouping moves the generated command pages under their group, so all 98 .LINK values were repointed to the canonical grouped URLs.

Validation

  • The full Process-PSModule v6.1.15 pipeline is green on 6ec4321 (run 30757319554): plan, build module, build docs, build site, repository lint, source-code lint and tests on Linux/Windows/macOS, module lint and test on Linux/Windows/macOS, test results, and code coverage. 66 checks, 0 failures.
  • Per-command Pester suites run on Linux, Windows, and macOS: ConvertFrom-Yaml, ConvertTo-Yaml, Test-Yaml, Import-Yaml, Export-Yaml, Format-Yaml, and Merge-Yaml, plus Specification, Conformance, and Packaging.
  • tests/Conformance.Tests.ps1 runs the pinned, hash-verified yaml-test-suite release archive: 402 inputs, 400 syntax passes, 0 failures, and exactly 2 documented policy differences (2JQS, X38W) that come from rejecting duplicate mapping keys β€” the stricter, safer behavior this release ships. Both cases are genuine key collisions: 2JQS repeats the empty key, and X38W uses an alias as a second key that resolves to the same node as the first. YAML 1.2.2 Β§3.2.1.1 requires mapping keys to be unique and Β§3.3.2 lists duplicate keys as a legitimate failure point, so rejecting them is intentional and is not tracked as a defect.
  • tests/Specification.Tests.ps1 covers YAML 1.2.2 chapter-2 examples 2.01 through 2.28.
  • tests/Packaging.Tests.ps1 asserts the shipped package carries no YamlDotNet or third-party license artifacts, that the generated manifest declares PowerShellVersion = '7.6' and CompatiblePSEditions = @('Core'), that the workflow stays pinned to Process-PSModule v6.1.15, and that every function file sits under exactly one domain folder with a <Group>.md present for each public group.
  • The object-model reference in the Conversion guide was verified by executing every documented mapping against the built command surface rather than asserted from the source, including the widening boundaries between Int32, Int64 and BigInteger, Decimal versus Double selection, the YAML 1.1-only forms that intentionally stay strings, timestamp Kind/offset behavior, and the YamlInvalidTaggedScalar failure for a standard tag that does not match its text.
  • Automated review note: GitHub Copilot declined to review this pull request three times because the diff exceeds its 20,000-line limit. A compensating automated code review was run over the shipped surface (src/**, .github/workflows/**, .github/PSModule.yml) with a differential harness against a reference parser. It found the two scalar defects listed above, which are fixed here. A third reported divergence was investigated, prototyped, and disproven β€” the reference parser disagrees with the official corpus there, and the module matches the corpus (see #52). Resource guards, tag handling, atomic file writes, BOM sniffing, and emitter idempotency were all clean.

Standards and framework alignment pass (Pass A)

Changed surface Standards checked Framework docs checked Result
src/functions/public/{Conversion,Files,Streams}/**, src/functions/private/** MSX Coding Standards: PowerShell/Functions, Naming PSModule Standards (group by domain, mirror public and private domains, group documentation pages with source) Fixed in this PR via #53
src/header.ps1 (source of the runtime constraint) MSX Coding Standards: PowerShell/Version-Constraints PSModule Standards, Process-PSModule module anatomy Aligned β€” #Requires -Version 7.6, #Requires -PSEdition Core; redundant src/manifest.psd1 removed
tests/** MSX Coding Standards: PowerShell/Testing PSModule Standards, PSModule Test-Specification, Process-PSModule build-test-pack-publish Fixed in this PR
.github/workflows/**, .github/PSModule.yml, .github/linters/** MSX Coding Standards: GitHub Actions Process-PSModule repository structure and build-test-pack-publish Aligned
README.md, src/functions/public/*/*.md, examples/** MSX Coding Standards: Documentation PSModule Repository-Defaults (relocate depth only to a published home; do not duplicate generated command documentation) Fixed in this PR via #53
Repository baseline files (CONTRIBUTING.md, SECURITY.md, SUPPORT.md, CODE_OF_CONDUCT.md, AGENTS.md, CLAUDE.md) MSX Ways of Working: Repository Standard PSModule Repository-Defaults (required common files, managed distribution guidance) Fixed in this PR. .github/pull_request_template.md and .github/copilot-instructions.md are Distributor-managed shared files and are deliberately not hand-authored in this repository.

Issue convergence sweep (Pass B)

  • Sweep scope: existing PR-linked candidates (#2, #4, #5, #7, #8, #20, #21, #22, #24, #25, #26, #27, #29, #43, #44) plus targeted open-issue searches by command names, YAML chapter-2/conformance terms, and representation-preserving file and merge terms. #50 was added after its delivery slice (#53) merged into this branch.
  • Dedupe note: PSModule/Yaml#1 is a pull request, not an issue leaf, and PSModule/Yaml#3 is already closed historical work.

Convergence evidence by closed issue

  • PSModule/Yaml#2 β€” core conversion surface delivered via ConvertFrom-Yaml and ConvertTo-Yaml, with coverage in tests/ConvertFrom-Yaml.Tests.ps1 and tests/ConvertTo-Yaml.Tests.ps1.
  • PSModule/Yaml#4 β€” Test-Yaml delivered and covered in tests/Test-Yaml.Tests.ps1.
  • PSModule/Yaml#5 β€” deterministic stream formatting delivered via Format-Yaml, covered in tests/Format-Yaml.Tests.ps1.
  • PSModule/Yaml#7 and PSModule/Yaml#27 β€” flow sequence/mapping parsing delivered and covered in parser behavior tests and tests/Specification.Tests.ps1 chapter-2 examples.
  • PSModule/Yaml#8 β€” multiline literal/folded scalar support delivered and covered in tests/ConvertFrom-Yaml.Tests.ps1 and chapter-2 examples.
  • PSModule/Yaml#20 β€” chapter-2 compliance harness delivered in tests/Specification.Tests.ps1 (examples 2.01 through 2.28).
  • PSModule/Yaml#21 β€” multi-document stream support delivered and validated in chapter-2 stream examples and command tests.
  • PSModule/Yaml#22 β€” anchors/aliases support delivered and verified in tests/ConvertFrom-Yaml.Tests.ps1 and merge behavior suites.
  • PSModule/Yaml#24 β€” explicit tag and !! handling delivered and covered across conversion/specification tests.
  • PSModule/Yaml#25 β€” complex mapping key handling delivered (including hashtable-safe paths) and covered in conversion/specification tests.
  • PSModule/Yaml#26 β€” core-schema numeric forms and special floats delivered and covered in tests/ConvertFrom-Yaml.Tests.ps1, tests/ConvertTo-Yaml.Tests.ps1, and tests/Specification.Tests.ps1.
  • PSModule/Yaml#29 β€” file I/O commands delivered via Import-Yaml and Export-Yaml, covered in tests/Import-Yaml.Tests.ps1 and tests/Export-Yaml.Tests.ps1.
  • PSModule/Yaml#43 β€” representation-preserving merge delivered via Merge-Yaml, covered in tests/Merge-Yaml.Tests.ps1.
  • PSModule/Yaml#50 β€” domain grouping delivered via #53, which merged into this branch: public commands grouped into Conversion, Files and Streams, private helpers mirrored into those domains plus a shared Engine group, and a <Group>.md overview page beside each public group. Enforced by new layout assertions in tests/Packaging.Tests.ps1. The closing keyword lives here because closing keywords only fire on merge to the default branch.

Deferred (not delivered in this release)

  • PSModule/Yaml#44 β€” representation-preserving entry removal is intentionally out of scope for the v1.0.0 module go-live. The module surface is parse/serialize, validate, import/export, format, and merge; entry removal remains open for a future release and is kept as a non-closing reference below.
  • PSModule/Yaml#54 β€” the Process-PSModule workflow only triggers on pull requests targeting main, so pull requests stacked on a release branch run no checks and are not gated by the main ruleset. Found while stacking #53 on this branch; #53 was instead validated by an explicit workflow dispatch and then by this pull request's own run after merging. Fixing the trigger is repository plumbing, not release content.
Relevant issues (or links)
  • Fixes #2
  • Closes #4
  • Closes #5
  • Closes #7
  • Closes #8
  • Closes #20
  • Closes #21
  • Closes #22
  • Closes #24
  • Closes #25
  • Closes #26
  • Closes #27
  • Closes #29
  • Closes #43
  • Closes #50
  • #44 (deferred: representation-preserving entry removal is out of scope for the v1.0.0 module go-live and is not delivered in this diff)
  • #54 (deferred: release-stacked pull requests run no CI; repository plumbing, not release content)
  • #23 (partially convergent: explicit !!timestamp handling is delivered; implicit core-schema timestamp resolution remains open by design)
  • #28 (not convergent: comment-preserving ConvertFrom-Yaml | ConvertTo-Yaml round-trip is not delivered in this diff)
  • #30 (partially convergent: parser/emitter hardening and budget controls shipped, but full operator-to-.NET substitution scope remains open)
  • #52 (closed as not a defect while validating this release; the module matches the official corpus and the reference parser is the outlier)