Skip to content

Latest commit

 

History

History
575 lines (411 loc) · 14.7 KB

File metadata and controls

575 lines (411 loc) · 14.7 KB

🔄 CI/CD and Publishing

This guide covers the automated CI/CD pipeline, versioning strategy, publishing to PowerShell Gallery, and repository maintenance.

CI/CD Pipeline Overview

The template includes a comprehensive GitHub Actions workflow that automates quality checks, builds, and releases.

Pipeline Architecture

graph TD
    A[Setup & Cache] --> B[Unit Tests]
    A --> C[Static Analysis]
    A --> D[Security Scans]
    A --> E[CodeQL Analysis]
    
    B --> F[Build & Publish]
    C --> F
    D --> F
    E --> F
    
    style A fill:#e1f5ff
    style B fill:#e8f5e9
    style C fill:#e8f5e9
    style D fill:#fff3e0
    style E fill:#fff3e0
    style F fill:#f3e5f5
Loading

Pipeline Stages:

  1. Setup & Cache → Prepares environment and caches dependencies
  2. Parallel Quality Gates:
    • Unit Tests (Pester)
    • Static Analysis (PSScriptAnalyzer)
    • Security Scans (InjectionHunter)
    • CodeQL Analysis
  3. Build & Publish → Compiles module, generates help, creates releases

Workflow Jobs

1. Setup and Caching

  • Caches PowerShell modules for faster builds
  • Sets up PowerShell 7+ environment
  • Installs dependencies via PSDepend

2. Unit Tests

  • Runs Pester tests with code coverage
  • Generates coverage reports (Cobertura format)
  • Uploads test results as artifacts
  • Fails build if tests don't pass

3. Static Code Analysis

  • Runs PSScriptAnalyzer on all source files
  • Validates code against best practices
  • Checks for style violations
  • Generates analysis report

4. Security Scans

InjectionHunter:

  • Scans for SQL/Command/Script injection vulnerabilities
  • Checks for unsafe string concatenation
  • Validates input sanitization

CodeQL:

  • Semantic code analysis
  • Detects security vulnerabilities
  • Runs weekly scheduled scans
  • Language: PowerShell

5. Build and Publish

  • Compiles module with ModuleBuilder
  • Generates help documentation (MAML + Markdown)
  • Creates GitHub Release (if on main branch)
  • Publishes to PowerShell Gallery (optional)

Workflow Triggers

Trigger When Quality Gates Publish
Pull Request PR opened/updated ✅ All jobs run ❌ No
Push to main PR merged ✅ All jobs run ⚠️ Prerelease only
Manual Dispatch User triggered ✅ All jobs run ✅ Optional
Schedule Weekly (CodeQL) 🔒 Security only ❌ No

Skipping Workflows

For documentation-only changes, the workflow intelligently skips unnecessary jobs:

# CI automatically skips tests for:
- *.md files
- docs/** files
- .github/** workflow files (except changes to ci.yml itself)

Versioning Strategy

GitVersion Configuration

This template uses Semantic Versioning (SemVer) with automated version management:

  • Workflow: GitHub Flow (main branch + feature branches)
  • Main branch: Production-ready code, every commit can be released
  • Feature branches: Development work, PRs required to merge
  • Version source: Git history and tags

Version Format

Major.Minor.Patch-PreReleaseLabel

Examples:
- 1.0.0           (Release)
- 1.2.3-alpha.1   (Prerelease)
- 2.0.0-beta.2    (Prerelease)

Controlling Version Bumps

Add semantic versioning keywords to commit messages:

Keyword Version Change Example Use Case
+semver: breaking or +semver: major 1.0.0 → 2.0.0 Breaking API changes Major release
+semver: feature or +semver: minor 1.0.0 → 1.1.0 New features (backward compatible) Minor release
+semver: fix or +semver: patch 1.0.0 → 1.0.1 Bug fixes Patch release
+semver: none or +semver: skip No change Documentation updates No version bump

Commit Message Examples

# Major version bump (breaking changes)
git commit -m "Remove deprecated Get-OldFunction command +semver: major"
git commit -m "Change parameter types to be more specific +semver: breaking"

# Minor version bump (new features)
git commit -m "Add Get-Something function +semver: minor"
git commit -m "Add optional -Force parameter to Get-Data +semver: feature"

# Patch version bump (bug fixes)
git commit -m "Fix parameter validation in Get-Something +semver: patch"
git commit -m "Correct error handling for edge case +semver: fix"

# No version change
git commit -m "Update README examples +semver: none"
git commit -m "Fix typo in comment +semver: skip"

Version Calculation

GitVersion automatically calculates versions based on:

  1. Latest Git tag - Starting point
  2. Commit history - Commits since last tag
  3. Branch name - Determines prerelease labels
  4. Semver keywords - Explicit version control

Example:

Current tag: v1.2.3

Commits on main:
- "Add feature X +semver: minor"
- "Fix bug Y +semver: patch"

Calculated version: 1.3.0

Build Types

Build Context Version Format Published Use Case
Release 1.2.3 ✅ PowerShell Gallery Production releases
Prerelease 1.2.3-alpha.5 ⚠️ Optional Testing releases
Debug 1.2.3-PullRequest.123 ❌ Never Development/PR builds

Publishing to PowerShell Gallery

Prerequisites

  1. PowerShell Gallery Account: Register here
  2. API Key: Generate in your PSGallery account settings
  3. GitHub Secret: Store API key as PSGALLERY_API_KEY in repository secrets

Setting Up Publishing

1. Create PowerShell Gallery API Key

  1. Log in to PowerShell Gallery
  2. Navigate to Account SettingsAPI Keys
  3. Click Create and set:
    • Key Name: GitHub Actions CI/CD
    • Select Scopes: Push new packages and package versions
    • Select Packages: All packages or specific module name
    • Expiration: 1 year (or your preference)

2. Add GitHub Repository Secret

  1. Go to your repository on GitHub
  2. Navigate to SettingsSecrets and variablesActions
  3. Click New repository secret
  4. Set:
    • Name: NUGETAPIKEY_PSGALLERY
    • Value: Your PowerShell Gallery API key
  5. Click Add secret

3. Configure Module Manifest

Ensure your module manifest has proper metadata:

# src/YourModuleName.psd1
@{
    ModuleVersion = '0.1.0'  # Auto-updated by GitVersion
    
    Author = 'Your Name'
    CompanyName = 'Your Company'
    Copyright = '(c) 2026 Your Name. All rights reserved.'
    Description = 'Comprehensive description for PowerShell Gallery'
    
    # PowerShell Gallery metadata
    PrivateData = @{
        PSData = @{
            Tags = @('PowerShell', 'Automation', 'Module', 'YourTag')
            LicenseUri = 'https://github.com/YourUsername/YourModule/blob/main/LICENSE'
            ProjectUri = 'https://github.com/YourUsername/YourModule'
            IconUri = 'https://github.com/YourUsername/YourModule/raw/main/icon.png'
            ReleaseNotes = 'See CHANGELOG.md or GitHub Releases'
        }
    }
}

Publishing Workflows

Automatic Publishing (Recommended)

On Main Branch:

Every merge to main creates a prerelease version:

# 1. Merge PR to main
# 2. CI automatically builds and creates GitHub Release
# 3. Prerelease published to PowerShell Gallery (if configured)

Manual Publishing

Via GitHub Actions Workflow Dispatch:

  1. Navigate to ActionsCI workflow
  2. Click Run workflow
  3. Configure:
    • version-tag: Optional version tag (e.g., v1.2.3)
    • publish: ✅ Check to publish to PowerShell Gallery
  4. Click Run workflow

Via Command Line:

# Build and publish from local machine
Invoke-Build -ReleaseType Release -NugetApiKey 'YOUR-API-KEY'

# Or publish existing build
Publish-Module -Path ./build/out/YourModuleName -NuGetApiKey 'YOUR-API-KEY'

Publishing Best Practices

Do:

  • Test thoroughly before publishing to PowerShell Gallery
  • Use prerelease versions for beta testing
  • Include comprehensive release notes
  • Tag releases with meaningful descriptions
  • Maintain a CHANGELOG.md
  • Verify module metadata is accurate

Don't:

  • Publish untested code
  • Skip version numbers (maintain semver)
  • Publish modules with hardcoded credentials
  • Forget to update documentation

Version Publishing Strategy

Development Flow:

feature/new-feature (PR)
    ↓ Tests, Analysis, Security Scans
    ↓ All checks pass
    ↓
main (Merge)
    ↓ Automatic build
    ↓ Version: 1.2.3-alpha.1
    ↓ GitHub Release created
    ↓ Optional: Prerelease to PSGallery
    ↓
Manual Workflow Dispatch
    ↓ User triggers with "publish" flag
    ↓ Version: 1.2.3
    ↓ GitHub Release updated
    ↓ Published to PowerShell Gallery

GitHub Releases

Automatic Release Creation

The CI workflow automatically creates GitHub Releases:

On main branch:

  • Creates release with version tag
  • Generates release notes from merged PRs
  • Attaches module package as artifact
  • Marks as prerelease

Components:

Release v1.2.3
├── Release Notes (auto-generated from PRs)
├── Assets:
│   ├── YourModuleName-1.2.3.zip
│   └── Source code (auto-attached by GitHub)
└── Metadata:
    ├── Tag: v1.2.3
    ├── Commit: abc123
    └── Prerelease: true/false

Release Notes

Release notes are automatically generated from:

  • PR titles: Main content
  • PR descriptions: Additional details
  • Labels: Categorization (bug, feature, breaking)

Example Release Notes:

## What's Changed

### 🚀 Features
- Add Get-Something function by @username in #123
- Support pipeline input for Get-Data by @username in #124

### 🐛 Bug Fixes
- Fix parameter validation in Get-Something by @username in #125

### 📖 Documentation
- Update README examples by @username in #126

**Full Changelog**: https://github.com/.../compare/v1.2.0...v1.2.3

Repository Maintenance

Automated Cleanup Workflows

The template includes automated maintenance to keep your repository clean:

Artifact Cleanup

Automatically removes old build artifacts:

  • Schedule: Daily at midnight (UTC)
  • Retention: 2 days (configurable)
  • Targets: Test results, coverage reports, build outputs

Workflow Run Cleanup

Removes old workflow runs to manage storage:

  • Schedule: Daily at midnight (UTC)
  • Retention: Keeps recent 2 runs per workflow (configurable)
  • Policy: Configurable by workflow status (success, failure, cancelled)

Manual Maintenance

Trigger Cleanup Manually

  1. Navigate to ActionsCleanup workflow
  2. Click Run workflow
  3. Configure retention period
  4. Click Run workflow

Adjust Cleanup Settings

Edit .github/workflows/cleanup.yml:

# Adjust retention periods
env:
  ARTIFACT_RETENTION_DAYS: 7     # Keep artifacts for 7 days
  MIN_RUNS_TO_KEEP: 5            # Keep at least 5 runs per workflow

Storage Management

Monitor storage usage:

  1. Go to SettingsActionsRunners
  2. View storage usage
  3. Adjust retention policies if needed

Typical storage usage:

Per Build:
- Artifacts: ~10-50 MB
- Workflow logs: ~5-10 MB

Monthly (with defaults):
- ~500 MB - 1 GB

Troubleshooting CI/CD

Build Failures

Problem: Tests fail in CI but pass locally

# Solution: Check for environment differences
# - Module versions (check requirements.psd1)
# - PowerShell version (CI uses 7.x)
# - Environment variables
# - File paths (use platform-agnostic paths)

Problem: PSScriptAnalyzer failures

# Solution: Run locally with same settings
Invoke-ScriptAnalyzer -Path ./src -Recurse `
    -Settings ./tests/PSScriptAnalyzer/PSScriptAnalyzerSettings.psd1

Publishing Failures

Problem: Publishing fails with authentication error

# Solution: Verify GitHub secret
# 1. Check NUGETAPIKEY_PSGALLERY exists
# 2. Verify API key hasn't expired
# 3. Regenerate key if needed

Problem: Version already exists on PowerShell Gallery

# Solution: Version conflict
# - You cannot republish the same version
# - Bump version with proper semver keyword
# - Or use prerelease version: 1.2.3-alpha.1

Version Issues

Problem: Version not incrementing

# Solution: Check commit message includes semver keyword
git commit -m "Your message +semver: minor"

# Verify GitVersion configuration
cat GitVersion.yml

Problem: Wrong version calculated

# Solution: Check git tags and history
git tag -l
git log --oneline --graph

# Manually tag if needed
git tag v1.0.0
git push origin v1.0.0

GitHub Actions Issues

Problem: Workflow not triggering

# Solution: Check workflow triggers in .github/workflows/ci.yml
# Ensure your branch/PR matches trigger conditions

Problem: Workflow steps failing

# Solution: Check workflow logs
# 1. Go to Actions tab
# 2. Select failed workflow run
# 3. Expand failed step
# 4. Review error messages

CI/CD Best Practices

Commit Practices

Do:

  • Include semver keywords in commit messages
  • Write descriptive commit messages
  • Keep commits focused and atomic
  • Reference issues in commit messages (#123)

Don't:

  • Commit without running tests locally
  • Mix multiple changes in one commit
  • Forget semver keywords (results in no version bump)

Pull Request Practices

Do:

  • Wait for all CI checks to pass before merging
  • Review CI test results and coverage reports
  • Update documentation if API changes
  • Request reviews from team members

Don't:

  • Merge failing PRs ("I'll fix it later")
  • Skip CI checks with admin override
  • Ignore PSScriptAnalyzer warnings

Release Practices

Do:

  • Use prereleases for testing
  • Test prereleases before promoting to release
  • Maintain semantic versioning discipline
  • Document breaking changes in release notes

Don't:

  • Skip versions (e.g., 1.0.0 → 1.0.2)
  • Make breaking changes in patch versions
  • Publish untested code to PowerShell Gallery

Resources


Automate everything! Ship with confidence! 🚀