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
83 changes: 83 additions & 0 deletions .github/workflows/pester.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# This is the SPSCleanDependencies CI Pester workflow to run tests on pull requests

name: SPSCleanDependencies CI Pester Tests

on:
pull_request:
branches:
- main
paths:
- 'scripts/**'
- 'tests/**'

jobs:
test:
name: Run Pester Tests
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Pester
shell: pwsh
run: |
Install-Module -Name Pester -MinimumVersion 5.3.0 -Force -SkipPublisherCheck -Scope CurrentUser
Import-Module Pester

- name: Run Pester Tests
shell: pwsh
run: |
$config = New-PesterConfiguration
$config.Run.Path = './tests'
$config.Run.Exit = $true
$config.TestResult.Enabled = $true
$config.TestResult.OutputPath = './test-results.xml'
$config.Output.Verbosity = 'Detailed'

Invoke-Pester -Configuration $config

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: test-results.xml

- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action/composite@v2
if: always()
with:
files: |
test-results.xml
check_name: Pester Test Results

code-quality:
name: Code Quality Check
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install PSScriptAnalyzer
shell: pwsh
run: |
Install-Module -Name PSScriptAnalyzer -Force -SkipPublisherCheck -Scope CurrentUser

- name: Run PSScriptAnalyzer
shell: pwsh
run: |
$scriptFiles = Get-ChildItem -Path ./scripts -Include '*.ps1', '*.psm1' -Recurse

$results = $scriptFiles | ForEach-Object {
Invoke-ScriptAnalyzer -Path $_.FullName -Severity Error,Warning -Settings ./PSScriptAnalyzerSettings.psd1
}

if ($results) {
$results | Format-Table -AutoSize
Write-Error "PSScriptAnalyzer found issues"
exit 1
} else {
Write-Host "No issues found by PSScriptAnalyzer"
}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore vscode files
.vscode/

# Ignore DS_Store files
**/.DS_Store
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@
The format is based on and uses the types of changes according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2026-06-11

### Added

- SPSCleanDependencies.util.psm1:
- Add `Get-SQLMissingWebPartInfo` helper to resolve missing WebPart class IDs to per-page locations (SiteID/WebID/ListID/DirName/LeafName).
- Add `Remove-SPSMissingWebPart` cleanup function (uses `GetLimitedWebPartManager` and temporarily clears the site `ReadOnly` flag).
- Extend `SPMissingWebPartInfo` class with `ClassName`, `StorageKey`, `SiteID`, `WebID`, `ListID`, `DirName`, `LeafName`.
- All `Remove-SPS*` functions now declare `[CmdletBinding(SupportsShouldProcess = $true)]` and gate destructive calls with `$PSCmdlet.ShouldProcess`, enabling `-WhatIf` / `-Confirm` for every cleanup branch.
- Import-time prelude (admin check, `powercfg`, SharePoint snap-in load) is now gated behind the `SPSCD_SKIP_PRELUDE` environment variable so the module can be imported on non-SharePoint hosts (CI, Pester) without elevation or SharePoint installed. Behaviour on a real SharePoint farm is unchanged.

- SPSCleanDependencies.ps1:
- Implement the `MissingWebPart` cleanup branch (previously a no-op).
- Implement the `SiteOrphan` cleanup branch by wiring up the existing `Remove-SPSOrphanedSite` function.

- Pester test suite under `tests/`:
- `tests/SPSCleanDependencies.Tests.ps1` - script-level tests (metadata, parameters, module imports, Clean branch wiring).
- `tests/Modules/SPSCleanDependencies.util.Tests.ps1` - module-level tests (public/SQL function contracts, class shapes, safety net for empty `StorageKey`, `SupportsShouldProcess` coverage on every `Remove-SPS*` function).

- CI:
- `.github/workflows/pester.yml` - runs Pester 5.3+ on `windows-latest` for pull requests to `main`, plus a `PSScriptAnalyzer` code-quality job.

### Fixed

- SPSCleanDependencies.util.psm1:
- Replace `Write-Host` in `Remove-SPSMissingSetupFile` with `Write-Output` (PSScriptAnalyzer `PSAvoidUsingWriteHost`).

- CI / repo configuration:
- Add `PSScriptAnalyzerSettings.psd1` at the repo root, excluding `PSUseSingularNouns` so the public `Get-SPSMissingServerDependencies` function can keep its current (plural) name for backward compatibility. The CI workflow now invokes `Invoke-ScriptAnalyzer` with `-Settings ./PSScriptAnalyzerSettings.psd1`.

- tests/Modules/SPSCleanDependencies.util.Tests.ps1:
- Surface real `Import-Module` failures instead of silently swallowing them with `-ErrorAction SilentlyContinue`, which had been hiding the actual cause of cascading test failures on CI.

## [1.1.0] - 2025-10-21

### Changed
Expand Down
12 changes: 12 additions & 0 deletions PSScriptAnalyzerSettings.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@{
# Settings consumed by Invoke-ScriptAnalyzer in CI and the local lint task.
#
# PSUseSingularNouns is excluded because the public function
# Get-SPSMissingServerDependencies must keep its current (plural) name
# for backward compatibility with existing callers, documentation, and
# the wiki. Attribute-based per-function suppression is unreliable for
# this rule, so we exclude it project-wide.
ExcludeRules = @(
'PSUseSingularNouns'
)
}
29 changes: 17 additions & 12 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
# SPSCleanDependencies - Release Notes

## [1.1.0] - 2025-10-21
## [1.2.0] - 2026-06-11

### Changed
### Added

- SPSCleanDependencies.util.psm1:
- Add `Get-SQLMissingWebPartInfo` helper to resolve missing WebPart class IDs to per-page locations.
- Add `Remove-SPSMissingWebPart` cleanup function (uses `GetLimitedWebPartManager` and temporarily clears the site `ReadOnly` flag).
- Extend `SPMissingWebPartInfo` class with location fields (`StorageKey`, `SiteID`, `WebID`, `ListID`, `DirName`, `LeafName`).
- All `Remove-SPS*` functions now support `-WhatIf` / `-Confirm` via `SupportsShouldProcess`.
- Import-time prelude (admin check, `powercfg`, SharePoint snap-in load) is now gated behind the `SPSCD_SKIP_PRELUDE` environment variable so the module can be imported on CI / non-SharePoint hosts.

- SPSCleanDependencies.ps1:
- Resolve Invoke-Sqlcmd does not work because sqlserver is not present [issue #2](https://github.com/luigilink/SPSCleanDependencies/issues/2)
- Resolve Performing the operation "Set-SPSite" on target "*sitemaster-*" [issue #3](https://github.com/luigilink/SPSCleanDependencies/issues/3)
- Implement the `MissingWebPart` cleanup branch (previously a no-op).
- Implement the `SiteOrphan` cleanup branch by wiring up the existing `Remove-SPSOrphanedSite` function.

- Pester test suite under `tests/` covering the script and helper module, including `SupportsShouldProcess` coverage on every `Remove-SPS*` function.

- Wiki Documentation in repository - Update :
- wiki/Home.md
- wiki/Getting-Started.md
- wiki/Usage.md
- `.github/workflows/pester.yml` CI workflow running Pester 5.3+ and `PSScriptAnalyzer` on `windows-latest`.

- Issue Templates files:
- 1_bug_report.yml Update version
### Fixed

- README.md
- Add Requirements for PowerShell 5 and SqlServer PowerShell Module
- Replace `Write-Host` with `Write-Output` in `Remove-SPSMissingSetupFile` and clear remaining `PSScriptAnalyzer` warnings via a new `PSScriptAnalyzerSettings.psd1` at the repo root (excluding `PSUseSingularNouns` to preserve the public `Get-SPSMissingServerDependencies` name).
- Stop hiding real `Import-Module` failures in the module Pester tests so future regressions surface immediately.

A full list of changes in each version can be found in the [change log](CHANGELOG.md)
Loading
Loading