diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8733b05 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +# Keeps the actions of .github/workflows/ci.yml up to date. The workflow pins +# each action by commit SHA with the version in a comment; Dependabot updates +# both and opens one pull request a week for all actions. +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + # Waits a week before it proposes a new release, so that a compromised + # release is more likely to be found and withdrawn first. + cooldown: + default-days: 7 + commit-message: + prefix: ci + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee5e7d6..fc25332 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -149,10 +149,10 @@ jobs: if: github.ref_type != 'tag' runs-on: ubuntu-latest timeout-minutes: 10 - # This job can write: it publishes the wiki from master. On pull requests, - # it shows the pages that would change. + # Shows the pages that would change. Read-only: on pull requests, including + # those of Dependabot, this job runs code that nobody has reviewed yet. permissions: - contents: write + contents: read steps: - name: Check out the repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -179,10 +179,39 @@ jobs: @('### Wiki', '', 'The wiki is up to date.') } Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY -Value $summary + + publish-wiki: + name: Publish the wiki + needs: wiki + if: github.ref == 'refs/heads/master' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + runs-on: ubuntu-latest + timeout-minutes: 10 + # This job can write, so it runs only for master, after the changes were + # reviewed and merged. + permissions: + contents: write + steps: + - name: Check out the repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Generate the wiki pages + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + run: | + gh auth setup-git + $wiki = Join-Path -Path $env:RUNNER_TEMP -ChildPath 'wiki' + git clone --quiet --depth 1 "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY.wiki.git" $wiki + if ($LASTEXITCODE -ne 0) { + throw "Cloning the wiki failed with exit code $LASTEXITCODE." + } + ./.github/scripts/Export-WikiContent.ps1 -Path ./Docs -DestinationPath $wiki -RepositoryUrl "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY" + git -C $wiki add --all Add-Content -LiteralPath $env:GITHUB_ENV -Value "WIKI_PATH=$wiki" - name: Publish the wiki - if: ${{ github.ref == 'refs/heads/master' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }} shell: pwsh env: GH_TOKEN: ${{ github.token }} diff --git a/.gitignore b/.gitignore index 261a1bd..3a665f9 100644 --- a/.gitignore +++ b/.gitignore @@ -244,5 +244,6 @@ ModelManifest.xml # FAKE - F# Make .fake/ -# Memory Bank: local prompt history, not version-controlled +# Memory Bank: local prompt history and session checkpoints, not version-controlled /.memory-bank/promptHistory.md +/.memory-bank/session/ diff --git a/.memory-bank/activeContext.md b/.memory-bank/activeContext.md index 1b3907c..90f556c 100644 --- a/.memory-bank/activeContext.md +++ b/.memory-bank/activeContext.md @@ -9,36 +9,37 @@ source: current task evidence ## Current focus -Release 5.0.0 through CI, with the prerelease `5.0.0-rc1` first -(Decision 12). The release workflow, scripts, tests, and docs are PR-ready -on the local branch `ai/release-5.0.0`; the maintainer pushes it, opens the -PR, sets up the Gallery key and the environment `powershell-gallery`, and -tags `5.0.0-rc1` after the merge. Work package 5 (code defects) and the -open issues come after the release. +Overnight run 2026-10-04/05 (autopilot, maintainer asleep): fix the code +defects A to D of `progress.md`, implement the maintainer's E decisions, +triage the 37 open issues, and prepare 5.0.0-rc2. Eight stacked local +branches, each a PR against `master`, to be merged in this order with merge +commits: `ai/maintenance`, `ai/defects-a`, `ai/defects-b`, `ai/defects-c`, +`ai/defects-d`, `ai/decisions-e`, `ai/issue-fixes`, +`ai/release-5.0.0-rc2`. Nothing is pushed; the maintainer pushes, opens +the PRs, and tags `5.0.0-rc2` after the merges. + +## Maintainer decisions for the run (2026-10-04) + +- D1: the fixes ship in 5.0.0; entries go under `[Unreleased]` (`Fixed`; + intended behavior changes under `Changed` with the way back). The last + PR sets `Prerelease = 'rc2'`. +- D2: `Clear-NTFSAccess -DisableInheritance` keeps leaving an empty DACL; + the page states the result and the risk. +- D3: `Set-NTFSInheritance` keeps entries like the dedicated cmdlets. +- D4: `-RemoveInheritedAuditRules` and `-RemoveExplicitAuditRules`, with + the `*AccessRules` names as aliases. +- D5: `Get-FileHash2` works in PowerShell 7 for every algorithm .NET has; + a missing one fails only when requested. +- D7: Dependabot for `github-actions` only; AlphaFS 2.2.1 in + `NTFSSecurity\packages.config` (no upgrade, no changelog entry). ## Evidence -- Test first: `Tests\Release.Tests.ps1` failed 15 of 15 (Windows - PowerShell: 9 failed, 6 skipped) before the scripts existed; the command - tag test failed before the tags were added. Final: full suite 268 tests, - PowerShell 7 232 passed and 36 skipped, Windows PowerShell 261 passed and - 7 skipped (packaging needs PowerShell 7). -- Package dry run: `NTFSSecurity.5.0.0-rc1.nupkg` (about 275 KB) with the 11 - `FileList` files, version `5.0.0-rc1`, release notes link, and 83 tags - (36 `PSCmdlet_`, 36 `PSCommand_`, `PSIncludes_Cmdlet`); the extracted - package imports in Windows PowerShell 5.1 and PowerShell 7.6.1 with 36 - cmdlets and working help. 4.2.6 on the Gallery has 37 + 37 command tags; - PSResourceGet 1.2.0 `Compress-PSResource` adds none. -- actionlint, PSScriptAnalyzer, and markdownlint: no findings. -- `master` has 37 open issues; several overlap the work package 5 defects - (for example #4) or are already fixed (#19 in 4.2.4; #15, #47, #66 by the - documentation). -- The local branch `ai/read-the-docs` keeps the dropped strict-build work - (`886c874`, `325ec76`); delete it once it is no longer wanted. +- Baseline at `e0f5366` (Release build, workstation): Windows PowerShell + 261 passed, 7 skipped; PowerShell 7 232 passed, 36 skipped (268 tests). +- `ai/maintenance` adds `Tests\Repository.Tests.ps1` (8 tests): Windows + PowerShell 269 passed, 7 skipped; PowerShell 7 240 passed, 36 skipped. ## Next step -After the maintainer opens the PR: read its CI run, and download the -`packages` artifact (`gh run download`) to compare it with the local dry -run. After the `5.0.0-rc1` tag: check the release job, the Gallery entry -(version, tags, `Find-Command Get-NTFSAccess`), and the GitHub prerelease. +Group A on `ai/defects-a`, starting with the shared test helpers. diff --git a/.memory-bank/decisions/0011-github-actions.md b/.memory-bank/decisions/0011-github-actions.md index 741309a..e664e03 100644 --- a/.memory-bank/decisions/0011-github-actions.md +++ b/.memory-bank/decisions/0011-github-actions.md @@ -21,7 +21,9 @@ source: maintainer decision after work package 4 checks appear on the pull request without a third-party service. - Consequences: `Docs` stays the only source (Decision 9); the wiki is a generated mirror, and edits made in the wiki are overwritten. Only the - `wiki` job has `contents: write`; actions are pinned by commit SHA. Test + `publish-wiki` job, which runs for `master` alone, has `contents: write`; + the `wiki` job that previews pull requests, including Dependabot's, is + read-only (2026-10-04). Actions are pinned by commit SHA. Test results appear in the job summary and as the `test-results` artifact. - Rejected: a hand-maintained wiki next to `Docs`, publishing the wiki by hand at release time, and keeping AppVeyor for build and tests. diff --git a/.memory-bank/progress.md b/.memory-bank/progress.md index 9e73a97..2f930e8 100644 --- a/.memory-bank/progress.md +++ b/.memory-bank/progress.md @@ -9,49 +9,33 @@ source: repository evidence ## Current status -PRs #91 to #97 are merged; `master` (`59663c9`) carries version 5.0.0, -which is not released yet. CI runs on GitHub Actions: build, docs checks, -and tests in Windows PowerShell 5.1 and PowerShell 7, plus the wiki, which -is generated from `Docs` (43 pages). PR-ready locally: `ai/release-5.0.0`, -releases by CI on a version tag (Decision 12), starting with the -prerelease `5.0.0-rc1`. +PRs #91 to #98 are merged. CI published the prerelease 5.0.0-rc1 from +`master` (`e0f5366`, tag `5.0.0-rc1`) to the PowerShell Gallery and GitHub; +the stable Gallery version is still 4.2.6. CI runs on GitHub Actions: +build, docs checks, tests in Windows PowerShell 5.1 and PowerShell 7, +packages, the wiki generated from `Docs` (43 pages), and releases on a +version tag (Decision 12). Next: the maintainer tests 5.0.0-rc1. ## Recent milestones -- 2026-10-02: Memory Bank initialized. PR #91 aligned the documentation - with the code (36 cmdlet pages, conceptual pages, README, `mkdocs.yml`, - `.readthedocs.yml`, `CHANGELOG.md`) and made `appveyor.yml` build the - module and check the docs against that build (Decision 6); squash-merged - as `690d8dd`. -- 2026-10-02: PR #83 (TechNet links) closed by the maintainer as superseded - by #91. -- 2026-10-04: Work package 1 merged as PR #92 with a merge commit - (`d917832`): `promptHistory.md` ignored, Decision 7, Decisions moved to - `decisions/`. -- 2026-10-04: Work package 2 squash-merged as PR #93 (`14799fb`): generated - help file shipped (Decision 8), stale help files removed, `FileList` - complete, `Tests\Help.Tests.ps1` (218 Pester tests), CI steps 03 (help - file current) and 04 (Pester, one Tests-tab entry per test; the NUnit - upload had listed 870), six cmdlet-page links reworded for the help - text. AppVeyor passed 218 of 218 on the PR (54834295) and on `master` - (54834350). -- 2026-10-04: Work packages 3 (#94, `bde59a5`), 4 (#95, `6665825`), and the - move to GitHub Actions (#96, `4f9f7cc`) merged with merge commits: Read - the Docs dropped (Decision 9), version 5.0.0 with a valid manifest - (Decision 10), CI and a wiki generated from `Docs` on GitHub Actions - (Decision 11). The first `master` run (37218869672) passed and published - the wiki (`62ec94a`, 43 pages). -- 2026-10-04: The maintainer kept the version history separate from - `CHANGELOG.md` and had it completed from the six PowerShell Gallery - packages and the commit history (#97, `59663c9`): release dates, notes - for 4.2.2, detailed notes for 4.2.4, and separate notes for 4.2.5 and - 4.2.6. The wiki republished it. -- 2026-10-04: The maintainer chose to release 5.0.0 next, through CI and a - prerelease first (Decision 12): `ai/release-5.0.0` adds the `release` job, - `Get-ReleaseInfo.ps1`, `New-ModulePackage.ps1`, `Tests\Release.Tests.ps1`, - the label `rc1`, and `Docs/Contributing/05-Releasing.md`. The package - dry run found that PSResourceGet drops the command tags that 4.2.6 had; - the script adds them back. +- 2026-10-02 to 2026-10-04: #91 aligned the docs with the code (Decision + 6; #83 closed as superseded), #92 did housekeeping (Decision 7), and + #93 shipped the generated help file (Decision 8, `Tests\Help.Tests.ps1`). +- 2026-10-04: #94 to #96 dropped Read the Docs (Decision 9), set version + 5.0.0 with a valid manifest (Decision 10), and moved CI and a wiki + generated from `Docs` to GitHub Actions (Decision 11). #97 completed the + version history, kept separate from `CHANGELOG.md`, from the six Gallery + packages and the commit history. +- 2026-10-04: #98 (`e0f5366`) added releases on a version tag through CI + (Decision 12), with a prerelease first; `New-ModulePackage.ps1` adds the + command tags that PSResourceGet drops. The tag `5.0.0-rc1` (run + 37230802387) published to the Gallery at 20:12 UTC and created the + GitHub prerelease. Verified: the Gallery nupkg and the GitHub zip are + byte-identical to the CI artifacts, the DLLs are optimized Release + builds, the Gallery shows the prerelease flag, the release notes link, + and all 36 `PSCmdlet_` and `PSCommand_` tags, and the installed module + passes the full suite (Windows PowerShell 261 passed, 7 skipped; + PowerShell 7 232 passed, 36 skipped). ## Stable capabilities @@ -68,31 +52,42 @@ Work packages in the order agreed with the maintainer. Each gets one opens the PR (the agent can't; see `techContext.md`, Constraints), and the next package starts only after the maintainer's go-ahead. -1. Housekeeping: done (#92). -2. Ship help: done (#93). -3. Docs on GitHub: done (#94). -4. Manifest and version 5.0.0: done (#95). -4b. CI and the wiki on GitHub Actions: done (#96). Left to the maintainer: - revoke AppVeyor's GitHub access if it is still granted, consider - **Restrict editing to collaborators only** for the wiki, and optionally - ask `Sup3rlativ3` to delete the Read the Docs project. -4c. Version history from the PowerShell Gallery: done (#97). -4d. Release 5.0.0 through CI (Decision 12): PR-ready on `ai/release-5.0.0`. - Before the first tag, the maintainer creates the Gallery API key, the - environment `powershell-gallery`, and its secret `PSGALLERY_API_KEY` - (steps in `Docs/Contributing/05-Releasing.md`). Then: merge, tag - `5.0.0-rc1`, test the prerelease, check its Gallery tags and - `Find-Command`, and for the final release remove the label and date the - changelog section. Releases no longer come from a local build, so the - old manual steps (cleaning - `C:\Program Files\WindowsPowerShell\Modules\NTFSSecurity`, Debug - builds) no longer apply. +Items 1 to 4c are done: housekeeping (#92), shipped help (#93), docs on +GitHub (#94), manifest and version 5.0.0 (#95), CI and the wiki on GitHub +Actions (#96), version history from the Gallery (#97). Optional for the +maintainer: delete the AppVeyor project and revoke its GitHub +authorization, restrict wiki editing to collaborators, and ask +`Sup3rlativ3` to delete the Read the Docs project. + +4d. Release 5.0.0 through CI (Decision 12): 5.0.0-rc1 published and + verified (#98); the maintainer tests it. The final release PR comes on + release day (CI warns when the changelog date isn't that day): remove + the label, date `[Unreleased]` as `[5.0.0]`, tag `5.0.0` (steps in + `Docs/Contributing/05-Releasing.md`). Also consider the manifest + `Description` ("Windows PowerShell Module") and the `5.0.0-rc1` example + in `Docs/README.md`. Releases no longer come from a local Debug build. +4e. Repository settings, proposed to the maintainer on 2026-10-04 (not yet + agreed): the `powershell-gallery` environment has no protection rules + and no deployment policy, so a workflow on any branch can use + `PSGALLERY_API_KEY` (`nyanhp` also has write access); `master` has no + protection or ruleset; head branches aren't deleted on merge; the + remote branches `fix/#34` and `test/transfer` (2023-11-28, two commits + each) aren't merged. Dependabot for the SHA-pinned actions comes with + `ai/maintenance` (maintainer decision D7, 2026-10-04). 5. Code defects, listed below: `review: on`, one PR per group, regression test first. Pester 5 tests import `NTFSSecurity\bin\Release`, run in a `$env:TEMP` sandbox and in the CI workflow (pattern: - `Tests\Help.Tests.ps1`), and skip elevated cases when not elevated; - check whether the GitHub Actions Windows runner runs elevated. Each fix - updates its cmdlet page and `CHANGELOG.md`. + `Tests\Help.Tests.ps1`), and skip elevated cases when not elevated. + GitHub-hosted Windows runners run as administrators with UAC disabled + (GitHub docs, checked 2026-10-04), so elevated cases run in CI; the + workstation session isn't elevated. Each fix updates its cmdlet page + and `CHANGELOG.md`. Start by triaging the 37 open issues (none newer + than May 2025): #15, #47, and #66 (documentation) and #19 (fixed in + 4.2.4) can be closed; #4 is defect (5); #34 has the WIP branch + `fix/#34` (`Extensions.cs`, `FileSystemSecurity2.cs`, `TestClient`); + `test/transfer` only adds a 3 MB `New.zip`. The E decisions set the + next version: fixes only 5.0.1, additions 5.1.0, changed defaults + 6.0.0, unless they ship in 5.0.0 (rc2). ### Code defects (work package 5) @@ -164,11 +159,17 @@ Numbered as agreed with the maintainer; each is documented on its page. #### E: Maintainer decisions before changing behavior -- `Clear-NTFSAccess -DisableInheritance` discards inherited entries: keep - that, or copy them? -- `Set-NTFSInheritance` defaults are the opposite of the dedicated - inheritance cmdlets: align? +- `Clear-NTFSAccess -DisableInheritance` removes the explicit entries and + then disables inheritance without copying the inherited ones, which + leaves an empty DACL: keep that, or copy them? +- `Set-NTFSInheritance` differs from the dedicated cmdlets in two of four + directions: `-AccessInheritanceEnabled $false` removes the inherited + access entries, and `-AuditInheritanceEnabled $true` removes the + explicit audit entries; the dedicated cmdlets keep them unless a switch + is given. Align? - The audit inheritance switches are named `*AccessRules`: add `*AuditRules` aliases? - `Get-FileHash2` fails in PowerShell 7 (`RIPEMD160`): drop the algorithm - there, load it lazily, or deprecate the cmdlet? + there, load it lazily, or deprecate the cmdlet? To verify: + `MACTripleDES.Create()` may use a random key, so its result would differ + on every call. diff --git a/.memory-bank/systemPatterns.md b/.memory-bank/systemPatterns.md index bec4064..aac475a 100644 --- a/.memory-bank/systemPatterns.md +++ b/.memory-bank/systemPatterns.md @@ -33,10 +33,9 @@ NTFSSecurity.dll ── cmdlets ──> Security2.dll (FileSystemAccessRule2, descriptor, and privilege cmdlets) enables Backup, Restore, TakeOwnership, and Security in `BeginProcessing` when `PrivateData.EnablePrivileges` is `$true`, and disables the ones it enabled in `EndProcessing`. -- `PrivateData` switches: `EnablePrivileges` (base cmdlet), - `GetInheritedFrom` (`Get-NTFSAccess`, `Get-NTFSAudit`), - `GetFileSystemModeProperty` and `IdentifyHardLinks` (`Get-ChildItem2`), - `ShowAccountSid` (format file). +- `PrivateData` switches: `EnablePrivileges` (base cmdlet), `GetInheritedFrom` + (`Get-NTFSAccess`, `Get-NTFSAudit`), `GetFileSystemModeProperty` and + `IdentifyHardLinks` (`Get-ChildItem2`), `ShowAccountSid` (format file). - Cmdlets accept either `-Path` (alias `FullName`) or `-SecurityDescriptor` (from `Get-NTFSSecurityDescriptor`); SD sets change the in-memory object until `Set-NTFSSecurityDescriptor` writes it back. @@ -66,18 +65,14 @@ Each Decision record is a file in `decisions/`; read only the relevant ones. - Run platyPS in Windows PowerShell 5.1 against a module build; a copy of `Docs/Cmdlets` must round-trip through `Update-MarkdownHelp` unchanged. -- GitHub renders the docs (Decision 9), and CI publishes them to the wiki - (Decision 11). The MarkdownLinkCheck step covers only relative links in - `Docs` and ignores anchors; `Tests\Wiki.Tests.ps1` checks every link of - the generated wiki, including anchors (GitHub's slug rules: lowercase, - punctuation removed, spaces to hyphens). Check the links in `README.md` - and `CHANGELOG.md` separately. -- The wiki is generated: edit `Docs`, never the wiki. - `Export-WikiContent.ps1` names a page after its file (`Docs/README.md` - becomes Home), rewrites links, and builds the sidebar from the cmdlet - groups of `Docs/README.md`; a cmdlet missing there fails `Wiki.Tests.ps1`. -- platyPS rewrites non-ASCII punctuation such as em dashes; keep cmdlet pages - ASCII-only. + platyPS rewrites non-ASCII punctuation, so keep cmdlet pages ASCII-only. +- GitHub renders the docs (Decision 9); CI publishes them to the wiki + (Decision 11). MarkdownLinkCheck: relative `Docs` links, no anchors; + `Tests\Wiki.Tests.ps1`: every wiki link and anchor (GitHub slug rules). + Neither covers the links in `README.md` and `CHANGELOG.md`. +- The wiki is generated from `Docs`; never edit the wiki. Pages are named + after their files, `Docs/README.md` becomes Home, and its cmdlet groups + form the sidebar; a cmdlet missing there fails `Wiki.Tests.ps1`. - In cmdlet pages, end a sentence with a link: platyPS renders a link as `text (url)` in the help file and drops the space after it. - Verify examples in a `$env:TEMP` sandbox, never on real data; parse every @@ -88,18 +83,14 @@ Each Decision record is a file in `decisions/`; read only the relevant ones. - Pester 5 tests in `Tests/*.Tests.ps1` import `NTFSSecurity\bin\Release\NTFSSecurity.psd1`; CI runs them in Windows PowerShell 5.1 and in PowerShell 7 (Decision 11). -- `Get-Help -Online` is tested with the internal test hook - `BypassOnlineHelpRetrieval`, which returns the URI instead of opening a - browser. In PowerShell 7 the hook also skips the help file, so that test - runs only in Windows PowerShell (36 skipped tests in PowerShell 7); - PowerShell 7 resolves the same URI. -- `.github/scripts/Invoke-Tests.ps1` runs Pester for CI: the counts and the - failed tests go to the job summary, the NUnit file to the `test-results` - artifact, and it fails on failed test files too (`Result -ne 'Passed'`). -- `Tests\Manifest.Tests.ps1` checks the built manifest: `Test-ModuleManifest` - without errors or warnings, exactly 36 cmdlets, and the same version in - the manifest and the assemblies (Decision 10). Add a new cmdlet to - `CmdletsToExport` and to the expected count in the same change. +- `Get-Help -Online` tests use the internal hook `BypassOnlineHelpRetrieval` + (URI instead of a browser); it skips the help file in PowerShell 7, so + those 36 tests run only in Windows PowerShell. +- `.github/scripts/Invoke-Tests.ps1` runs Pester in CI: counts and failures + to the job summary, NUnit to `test-results`; failed test files fail too. +- `Tests\Manifest.Tests.ps1`: `Test-ModuleManifest` without errors or + warnings, exactly 36 cmdlets, one version in manifest and assemblies + (Decision 10). A new cmdlet updates `CmdletsToExport` and that count. - `Tests\Release.Tests.ps1` checks that `CHANGELOG.md` has release notes for the manifest version (dated section, or `[Unreleased]` for a prerelease) and the packages: only `FileList` files, version with label, diff --git a/.memory-bank/techContext.md b/.memory-bank/techContext.md index 649cc21..9f97a6f 100644 --- a/.memory-bank/techContext.md +++ b/.memory-bank/techContext.md @@ -65,12 +65,12 @@ source: repository evidence ## Constraints -- `ModuleVersion` on `master` is `5.0.0` (not released); the latest tag and - Gallery release is `4.2.6`. On `ai/release-5.0.0`, the manifest adds the - prerelease label `rc1`, so the next tag is `5.0.0-rc1`. The manifest - requires PowerShell 5.1 and .NET Framework 4.5.2, uses `RootModule`, and - lists exactly 36 cmdlets; `Test-ModuleManifest` passes in Windows - PowerShell 5.1 and PowerShell 7.6. +- `ModuleVersion` on `master` is `5.0.0` with the prerelease label `rc1`; + 5.0.0-rc1 is on the Gallery (published 2026-10-04 by CI). The latest + stable tag and Gallery release is `4.2.6`. The manifest requires + PowerShell 5.1 and .NET Framework 4.5.2, uses `RootModule`, and lists + exactly 36 cmdlets; `Test-ModuleManifest` passes in Windows PowerShell 5.1 + and PowerShell 7.6. - Besides the shipped help file and its tests (#93), the module source at `master` differs from tag `4.2.6` by the `Remove-Item2 -PassThur` to `-PassThru` rename (with a `-PassThur` alias), the manifest changes of @@ -118,15 +118,17 @@ source: repository evidence `Get-MarkdownLink -BrokenOnly`; 03 regenerate the help file and fail on `git status --porcelain -- NTFSSecurity/en-US`; 04 `Invoke-Tests.ps1` in Windows PowerShell 5.1 and in PowerShell 7. Job `wiki` on `ubuntu-latest` - clones the wiki (`gh auth setup-git` with the built-in token), runs - `Export-WikiContent.ps1`, lists the changed pages in the job summary, and - publishes from `master` only. After the tests, `build` runs + (read-only) clones the wiki (`gh auth setup-git` with the built-in token), + runs `Export-WikiContent.ps1`, and lists the changed pages in the job + summary; job `publish-wiki` (`contents: write`) repeats that and publishes, + for `master` only. After the tests, `build` runs `New-ModulePackage.ps1` and uploads the artifact `packages` (nupkg and `NTFSSecurity.zip`). Job `release` runs only for tags matching `[0-9]+.[0-9]+.[0-9]+` or `[0-9]+.[0-9]+.[0-9]+-*`, in the environment `powershell-gallery` (secret `PSGALLERY_API_KEY`); see Decision 12. Actions are pinned by commit SHA: `actions/checkout` v7.0.1, - `actions/upload-artifact` v7.0.1, `actions/download-artifact` v8.0.1. + `actions/upload-artifact` v7.0.1, `actions/download-artifact` v8.0.1; + Dependabot proposes updates weekly, one week after a release. - Packaging needs PSResourceGet (`Compress-PSResource`, PowerShell 7.4 or later); its tests skip in Windows PowerShell. Dry run locally: run `New-ModulePackage.ps1` against `NTFSSecurity\bin\Release` into diff --git a/NTFSSecurity/packages.config b/NTFSSecurity/packages.config index fcefae4..169cee2 100644 --- a/NTFSSecurity/packages.config +++ b/NTFSSecurity/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Tests/Repository.Tests.ps1 b/Tests/Repository.Tests.ps1 new file mode 100644 index 0000000..4f519e0 --- /dev/null +++ b/Tests/Repository.Tests.ps1 @@ -0,0 +1,77 @@ +<# + Tests repository files that the build and GitHub use, without a build: every packages.config lists the AlphaFS + version that the projects reference and ship, and Dependabot keeps the actions of the CI workflow up to date. +#> +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Pester shares variables between blocks.' +)] +param () + +BeforeDiscovery { + $repositoryPath = Join-Path -Path $PSScriptRoot -ChildPath '..' + $packageConfigs = foreach ($project in Get-ChildItem -Path $repositoryPath -Filter '*.csproj' -Recurse -Depth 1) { + $configPath = Join-Path -Path $project.DirectoryName -ChildPath 'packages.config' + if ((Test-Path -LiteralPath $configPath) -and (Select-String -LiteralPath $configPath -Pattern 'id="AlphaFS"' -Quiet)) { + @{ Project = $project.Directory.Name; Path = $configPath } + } + } +} + +Describe 'NuGet packages of the projects' { + BeforeAll { + $repositoryPath = Join-Path -Path $PSScriptRoot -ChildPath '..' + $projects = Get-ChildItem -Path $repositoryPath -Filter '*.csproj' -Recurse -Depth 1 + $hintPathVersions = @($projects | Select-String -Pattern 'packages\\AlphaFS\.(\d+\.\d+\.\d+)\\' | + ForEach-Object -Process { $_.Matches[0].Groups[1].Value } | Sort-Object -Unique) + } + + It 'Should reference one AlphaFS version in the HintPaths of all projects' { + $hintPathVersions | Should -HaveCount 1 + } + + It 'Should find the packages.config of the three projects that reference AlphaFS' -ForEach @(@{ Configs = $packageConfigs }) { + $Configs | Should -HaveCount 3 + } + + It 'Should list the AlphaFS version of the HintPaths in \packages.config' -ForEach $packageConfigs { + $package = ([xml] (Get-Content -LiteralPath $Path -Raw)).packages.package | + Where-Object -Property id -EQ -Value 'AlphaFS' + + $package.version | Should -BeExactly $hintPathVersions[0] + } +} + +Describe 'Dependabot configuration' { + BeforeAll { + $configPath = Join-Path -Path $PSScriptRoot -ChildPath '..\.github\dependabot.yml' + $lines = if (Test-Path -LiteralPath $configPath) { Get-Content -LiteralPath $configPath } else { @() } + $raw = $lines -join "`n" + $ecosystems = @($lines | Select-String -Pattern '^\s*-\s*package-ecosystem:\s*"?([\w-]+)"?\s*$' | + ForEach-Object -Process { $_.Matches[0].Groups[1].Value }) + } + + It 'Should exist in the .github folder' { + $configPath | Should -Exist + } + + It 'Should use version 2 of the format and the root folder of the repository' { + $lines -match '^version:\s*2\s*$' | Should -HaveCount 1 + $lines -match '^\s+directory:\s*"?/"?\s*$' | Should -HaveCount 1 + } + + It 'Should update only the actions of the CI workflow' { + $ecosystems | Should -BeExactly @('github-actions') + } + + It 'Should check for updates every week' { + $lines -match '^\s+interval:\s*"?weekly"?\s*$' | Should -HaveCount 1 + } + + It 'Should wait at least a week before it proposes a new release' { + $raw | Should -Match '(?m)^\s+cooldown:\s*\n\s+default-days:\s*([7-9]|[1-9]\d+)\s*$' + } + + It 'Should group all updates into one pull request' { + $raw | Should -Match '(?m)^\s+groups:\s*\n\s+[\w-]+:\s*\n\s+patterns:\s*\n\s+-\s*["'']\*["'']\s*$' + } +}