Skip to content

feat: initial PowerShell module base scaffold#1

Merged
samhodgkinson merged 3 commits into
mainfrom
claude/pwsh-module-base-setup-32Mot
Jun 7, 2026
Merged

feat: initial PowerShell module base scaffold#1
samhodgkinson merged 3 commits into
mainfrom
claude/pwsh-module-base-setup-32Mot

Conversation

@samhodgkinson

Copy link
Copy Markdown
Owner

Complete PowerShell module base template — ready to clone and rename.

What's included

  • src/MyModule/ — Public/Private source layout, dev loader PSM1, manifest
  • tests/Unit/ — Pester 5 tests for public and private functions
  • Build.ps1 — Invoke-Build tasks: Lint, Test, Manifest, Build, Docs, Publish*
  • PSScriptAnalyzerSettings.psd1 — all-severity rules, tuned to avoid noise
  • .github/workflows/ci.yml — lint + test (Linux/Windows/macOS) + security + build
  • .github/workflows/publish.yml — PSGallery + GitHub Packages + ADO Artifacts on tag
  • .devcontainer/devcontainer.json — PowerShell 7.4 dev container
  • docs/about_MyModule.md — module help; cmdlet pages auto-generated by platyPS
  • CLAUDE.md, README.md, SECURITY.md, CHANGELOG.md

Key design decisions

  • Build never touches source files — manifest patches use regex to preserve comments
  • Monolithic PSM1 in .build/ for distribution; dot-source loader in src/ for dev
  • FunctionsToExport auto-discovered from Public/ at build time
  • Version synced from git tag in publish workflow
  • Test-ModuleManifest validates build output before publish

Generated by Claude Code

Full project template with:
- src/MyModule/ layout (Public/ Private/ one-file-per-function)
- Pester 5 unit tests with JaCoCo coverage
- PSScriptAnalyzer configuration (all severities, formatting rules)
- Invoke-Build task script (lint, test, build, docs, publish)
- platyPS documentation generation
- GitHub Actions CI (lint, test, security, build)
- GitHub Actions publish pipeline (PSGallery, GitHub Packages, ADO Artifacts)
- Dev container (PowerShell 7.4)
- VS Code settings, extensions, launch configs
- Claude Code helper commands
- README with publishing paths for PSGallery / GitHub Packages / ADO Artifacts
- CLAUDE.md AI context
- Build.ps1: Manifest task auto-discovers Public/ functions + validates GUID;
  Build produces a monolithic PSM1 for distribution with explicit exports
- PSD1: FunctionsToExport = '*' in src (dev/test); build writes explicit list
- CI: install all tools once up-front, then delegate to Invoke-Build tasks;
  cross-platform matrix (Linux/Windows/macOS) with Pester wired correctly
- Get-Example.ps1: richer comment-based help (all sections, multiple examples)
- docs/about_MyModule.md: proper module-level about_ help file
- README + CLAUDE.md: full rewrite with clearer structure
Bugs fixed:
- B1: ci.yml test job had -MinimumVersion @{Pester='5.0'} (invalid syntax);
  split into separate Install-Module calls
- B2: Manifest task no longer called from Build; Build never touches source files.
  Manifest task uses [regex]::Replace to preserve comments (no Update-ModuleManifest
  on source). Build uses inline regex to update only the .build/ manifest copy
- B3: PowerShellGet no longer needed in CI; manifest updates use regex throughout
- B4: Added .TrimEnd() to monolithic PSM1 concatenation to prevent double-newlines
  from CRLF source files

Design improvements:
- D1: publish.yml now extracts version from tag (v1.2.3 -> 1.2.3) and patches
  ModuleVersion in the built manifest before uploading artifact
- D2: Pester coverage threshold added (80% CoveragePercentTarget)
- D3: Test-ModuleManifest called after Build to validate manifest before publish
- D4: Docs task now calls New-ExternalHelp to compile MAML into en-US/;
  Get-Help about_MyModule now works for installed module
- D5: Get-Example gains begin{} and end{} blocks with usage guidance
- D6: Added test for ValueFromPipelineByPropertyName
- D7: PSAlignAssignmentStatement moved to ExcludeRules (too noisy in practice)
- D8: Publish artifact name includes tag version
- D9: CompatiblePSEditions = @('Core') added to manifest (PS 7 = Core only)

Minor:
- devcontainer postCreateCommand uses array form (avoids shell quoting issues)
- Added SECURITY.md placeholder
@samhodgkinson samhodgkinson merged commit 1a0b6af into main Jun 7, 2026
1 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant