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
30 changes: 20 additions & 10 deletions .github/workflows/pester.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@ on:
branches:
- main
paths:
- 'scripts/**'
- 'src/**'
- 'tests/**'
- 'PSScriptAnalyzerSettings.psd1'

# The "Publish Test Results" step creates a check run, which requires write
# access to checks. The default GITHUB_TOKEN is read-only on repositories
# created with the modern default, so grant the minimum needed here.
permissions:
contents: read
checks: write
pull-requests: write

jobs:
test:
Expand All @@ -17,7 +26,7 @@ jobs:

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

- name: Install Pester
shell: pwsh
Expand All @@ -38,7 +47,7 @@ jobs:
Invoke-Pester -Configuration $config

- name: Upload test results
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
if: always()
with:
name: test-results
Expand All @@ -47,6 +56,7 @@ jobs:
- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action/composite@v2
if: always()
continue-on-error: true
with:
files: |
test-results.xml
Expand All @@ -58,7 +68,7 @@ jobs:

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

- name: Install PSScriptAnalyzer
shell: pwsh
Expand All @@ -68,16 +78,16 @@ jobs:
- 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
}
# Analyze our own code only: the entry script and the SPSCleanDependencies.Common module.
$results = @()
$results += Invoke-ScriptAnalyzer -Path ./src/SPSCleanDependencies.ps1 -Settings ./PSScriptAnalyzerSettings.psd1
$results += Invoke-ScriptAnalyzer -Path ./src/Modules/SPSCleanDependencies.Common -Recurse -Settings ./PSScriptAnalyzerSettings.psd1

if ($results) {
$results | Format-Table -AutoSize
Write-Error "PSScriptAnalyzer found issues"
exit 1
} else {
}
else {
Write-Host "No issues found by PSScriptAnalyzer"
}
18 changes: 13 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# This is a basic workflow to help you get started with Actions
# This is the SPSCleanDependencies CI Release workflow to create a release from a
# tag push. Triggered by pushing a v* tag (e.g. v1.3.0). It packages the *contents*
# of the src/ folder into a ZIP (so the archive extracts straight to Modules/ and
# SPSCleanDependencies.ps1, with no src/ wrapper) and publishes a GitHub Release
# using RELEASE-NOTES.md as the body.

name: SPSCleanDependencies CI Release

Expand All @@ -8,24 +12,27 @@ on:
tags:
- "v*" # Push events to matching v*, i.e. v1.0, v20.15.10

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest
steps:
# Checkout code
- name: Checkout code
id: checkout_code
uses: actions/checkout@v4
uses: actions/checkout@v7
# Create a ZIP file with project name and tag version
- name: Create ZIP file of scripts
- name: Create ZIP file of src contents
run: |
zip_name="SPSCleanDependencies-${{ github.ref_name }}.zip"
zip -r $zip_name scripts/
( cd src && zip -r "../$zip_name" . )
shell: bash
# Create Release with tag version
- name: Create GitHub Release
id: create_release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand All @@ -35,3 +42,4 @@ jobs:
files: |
LICENSE
SPSCleanDependencies-${{ github.ref_name }}.zip

4 changes: 2 additions & 2 deletions .github/workflows/wiki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
repository: ${{github.repository}}
path: ${{github.repository}}

- name: Checkout Wiki
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
repository: ${{github.repository}}.wiki
path: ${{github.repository}}.wiki
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,31 @@
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.3.0] - 2026-07-09

### Changed

- Restructure the helper module into `src/Modules/SPSCleanDependencies.Common` following the `SPSUpdate` pattern:
- One function per file under `Public/` (`Get-SPSInstalledProductVersion`, `Get-SPSMissingServerDependencies` and the six `Remove-SPS*` cleanups) and the internal SQL helpers under `Private/` (`Get-SQLMissing*`, no longer exported to callers).
- Add a loader `SPSCleanDependencies.Common.psm1` that dot-sources `Private/` + `Public/` and exports only the public functions.
- Add a clean `SPSCleanDependencies.Common.psd1` manifest (`ModuleVersion` `1.3.0`, correct `FunctionsToExport`) replacing the mis-named, never-imported `SPSCleanDependencies.util.util.psd1`.
- Fold the former module-level classes, `ArrayList` collections and `jsonObject` into `Get-SPSMissingServerDependencies` (their only consumer) so the module holds no mutable state.
- Move the entry script to `src/SPSCleanDependencies.ps1` and import the module through its manifest. The script version is now sourced from `(Get-Module SPSCleanDependencies.Common).Version` instead of a hard-coded string.
- Relocate the import-time prelude (administrator check, High Performance power plan and SharePoint snap-in / `SharePointServer` module load) from the module into the entry script, making the module import-safe by design (the `SPSCD_SKIP_PRELUDE` gate is no longer needed).
- Behaviour on a real SharePoint farm is unchanged. [issue #6](https://github.com/luigilink/SPSCleanDependencies/issues/6)

- Tests:
- Rename the module test file to `tests/Modules/SPSCleanDependencies.Common.Tests.ps1` and adapt it to the new layout (import via the `.psd1` manifest, resolve the internal SQL helpers through `InModuleScope`, assert `FunctionsToExport` matches the exported set, match the `SPMissing*` classes against `Public/Get-SPSMissingServerDependencies.ps1`).
- Point the entry-script tests at `src/SPSCleanDependencies.ps1` and assert the manifest-based import and version sourcing.

- CI:
- `pester.yml` / `release.yml` / `wiki.yml` adapted to the `src/` layout (workflow `paths`, PSScriptAnalyzer targets, release ZIP of `src/` contents).
- Bump deprecated GitHub Actions (Node 20 runtime warnings): `actions/checkout@v4` -> `v7`, `actions/upload-artifact@v4` -> `v7`, `softprops/action-gh-release@v2` -> `v3`.

### Fixed

- Home wiki page: describe the WebParts and Orphaned Sites cleanups as implemented (they stopped being placeholders in 1.2.0).

## [1.2.0] - 2026-06-11

### Added
Expand Down
31 changes: 12 additions & 19 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
# SPSCleanDependencies - Release Notes

## [1.2.0] - 2026-06-11
## [1.3.0] - 2026-07-09

### Added
### Changed

- 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.
- Restructure the helper module into `src/Modules/SPSCleanDependencies.Common` (aligned on the `SPSUpdate` pattern):
- One function per file under `Public/`, internal SQL helpers under `Private/` (`Get-SQLMissing*`, no longer exported).
- A loader `.psm1` dot-sourcing `Private/` + `Public/`, and a clean `.psd1` manifest (`ModuleVersion` 1.3.0, correct `FunctionsToExport`) replacing the mis-named, never-imported `SPSCleanDependencies.util.util.psd1`.
- The former module-level classes / `ArrayList` collections / `jsonObject` are folded into `Get-SPSMissingServerDependencies`, so the module holds no mutable state.
- The entry script moves to `src/SPSCleanDependencies.ps1`, imports the module through its manifest, and sources its version from `(Get-Module SPSCleanDependencies.Common).Version`.
- The import-time prelude (administrator check, High Performance power plan, SharePoint snap-in load) moves from the module into the entry script, making the module import-safe by design.
- 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.
### CI

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

- `.github/workflows/pester.yml` CI workflow running Pester 5.3+ and `PSScriptAnalyzer` on `windows-latest`.

### Fixed

- 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.
- Workflows adapted to the `src/` layout (`paths`, PSScriptAnalyzer targets, release ZIP of `src/` contents).
- Deprecated GitHub Actions bumped: `actions/checkout@v4` -> `v7`, `actions/upload-artifact@v4` -> `v7`, `softprops/action-gh-release@v2` -> `v3`.

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