Browse Source

ci: keep pull request runs read-only and delay Dependabot proposals

Resolves the review of this branch (one Major, three Minor findings):

- Major: a Dependabot pull request runs the action versions it proposes
  before anyone reviews them, and the wiki job of that run held
  contents: write. The wiki job is now read-only and only previews the
  changed pages; the new publish-wiki job, the only one besides release
  with write access, publishes for master alone, after a merge.
  dependabot.yml waits 7 days (cooldown) before it proposes a release.
- Minor: Repository.Tests.ps1 asserts that it found the 3 packages.config
  files, checks version 2 and the directory, accepts either quote style,
  and checks that the "*" pattern sits under groups (11 tests; the
  cooldown test failed before the change).

Memory Bank: Decision 11 and techContext.md describe the two wiki jobs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/99/head
Raimund Andree 1 week ago
parent
commit
36605d1c8f
  1. 4
      .github/dependabot.yml
  2. 37
      .github/workflows/ci.yml
  3. 4
      .memory-bank/decisions/0011-github-actions.md
  4. 10
      .memory-bank/techContext.md
  5. 17
      Tests/Repository.Tests.ps1

4
.github/dependabot.yml

@ -7,6 +7,10 @@ updates:
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:

37
.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 }}

4
.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.

10
.memory-bank/techContext.md

@ -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

17
Tests/Repository.Tests.ps1

@ -29,6 +29,10 @@ Describe 'NuGet packages of the 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 <Project>\packages.config' -ForEach $packageConfigs {
$package = ([xml] (Get-Content -LiteralPath $Path -Raw)).packages.package |
Where-Object -Property id -EQ -Value 'AlphaFS'
@ -41,6 +45,7 @@ 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 })
}
@ -49,6 +54,11 @@ Describe 'Dependabot configuration' {
$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')
}
@ -57,8 +67,11 @@ Describe 'Dependabot configuration' {
$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' {
$lines -match '^\s+groups:\s*$' | Should -HaveCount 1
$lines -match '^\s+-\s*"\*"\s*$' | Should -HaveCount 1
$raw | Should -Match '(?m)^\s+groups:\s*\n\s+[\w-]+:\s*\n\s+patterns:\s*\n\s+-\s*["'']\*["'']\s*$'
}
}

Loading…
Cancel
Save