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
51 changes: 51 additions & 0 deletions .github/scripts/check-docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash
# Purpose: Fail when the docs drift from the scripts.
# Checks: (1) relative links in tracked .md files resolve, (2) every script folder has a README.md,
# (3) every env var in a script's "Environment Variables" header appears in its folder README.
set -euo pipefail

cd "$(git rev-parse --show-toplevel)"
fail=0

while IFS= read -r md; do
dir=$(dirname "${md}")
while IFS= read -r target; do
path="${target%%#*}"
[ -z "${path}" ] && continue
if [ ! -e "${dir}/${path}" ]; then
echo "BROKEN LINK: ${md} -> ${target}"
fail=1
fi
done < <(grep -oE '\]\(\.{1,2}/[^)]*\)|\]\(\.{1,2}\)' "${md}" | sed -E 's/^\]\(//; s/\)$//' || true)
done < <(git ls-files '*.md' ':!:.github/skills/*' ':!:.github/agents/*')

while IFS= read -r script; do
dir=$(dirname "${script}")
readme="${dir}/README.md"
if [ ! -f "${readme}" ]; then
echo "MISSING README: ${readme} (for ${script})"
fail=1
continue
fi
vars=$(awk '
/^(#|REM)[[:space:]]+Environment Variables:/ { in_block = 1; next }
in_block && !/^(#|REM)[[:space:]]/ { in_block = 0 }
in_block && !/^(#|REM)[[:space:]]+NOTE:/ && /^(#|REM)[[:space:]]+(-[[:space:]]+)?[A-Z][A-Z0-9_]+[[:space:]]*[-:]/ {
line = $0
sub(/^(#|REM)[[:space:]]+(-[[:space:]]+)?/, "", line)
sub(/[[:space:]]*[-:].*/, "", line)
print line
}
' "${script}")
for var in ${vars}; do
if ! grep -q "\`${var}\`" "${readme}"; then
echo "UNDOCUMENTED ENV VAR: ${var} is in ${script} header but not in ${readme}"
fail=1
fi
done
done < <(git ls-files '*.sh' '*.bat' ':!:.github/*')

if [ "${fail}" -eq 0 ]; then
echo "Docs checks passed"
fi
exit "${fail}"
34 changes: 34 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Docs

on:
pull_request:
paths:
- '**.md'
- '**.sh'
- '**.bat'
- '.github/scripts/check-docs.sh'
- '.github/workflows/docs.yml'
push:
branches:
- main
paths:
- '**.md'
- '**.sh'
- '**.bat'
- '.github/scripts/check-docs.sh'
- '.github/workflows/docs.yml'

permissions:
contents: read

jobs:
docs-check:
name: Docs match scripts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1

- name: Check links, folder READMEs and documented env vars
run: .github/scripts/check-docs.sh
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ A new script | Root `README.md` Scripts table, the table above, and the PID lock

## CI and Releases

CI runs shellcheck, the self-update drift check, the self-update test and actionlint; run the first three locally. Never tag releases by hand — merging the auto-opened "Release vYYYY.MM.DD" PR does it. Details are in `CONTRIBUTING.md` → **CI** and **Releases**.
CI runs shellcheck, the self-update drift check, the self-update test and actionlint; run the first three and `.github/scripts/check-docs.sh` locally. Never tag releases by hand — merging the auto-opened "Release vYYYY.MM.DD" PR does it. Details are in `CONTRIBUTING.md` → **CI** and **Releases**.

## Adding a New Script

Expand Down
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Before opening a PR:
2. Run the CI helpers locally:
- `.github/scripts/check-self-update.sh`
- `.github/scripts/test-self-update.sh`
- `.github/scripts/check-docs.sh`
3. Test in a staging or dev Plesk environment and cover the error paths: missing credentials, an empty database list, a missing directory, and concurrent runs (PID lock).
4. Check that files written on Linux have restrictive permissions (600).
5. Test Windows scripts with paths containing spaces and parentheses.
Expand All @@ -100,6 +101,8 @@ Before opening a PR:
- `.github/scripts/test-self-update.sh`: runs the gated updater against a stubbed `curl` (update, pin, checksum mismatch, no release, bad version)
- actionlint on the workflows

`.github/workflows/docs.yml` runs `.github/scripts/check-docs.sh` (also on markdown-only changes): relative links resolve, every script folder has a `README.md`, and every env var in a script's header "Environment Variables" block appears in backticks in that README.

## Releases

Never tag by hand. Add a `CHANGELOG.md` entry under `[Unreleased]` for any script change users should pick up. On pushes to `main` that have unreleased entries, `release-pr.yml` opens or updates a "Release vYYYY.MM.DD" PR that renames `[Unreleased]`. Merging it triggers `release.yml`, which re-runs shellcheck and the drift check, then creates the tag and release with `SHA256SUMS`. This needs the repository setting *Actions → Allow GitHub Actions to create pull requests*.
Expand All @@ -120,4 +123,4 @@ Folder README template:
6. Scheduling
7. Troubleshooting

Keep the env var table in the README in step with the script header. Update `GLOSSARY.md` when you introduce or change a domain term, and add an ADR in `docs/adr/` only for decisions that are hard to reverse, surprising without context, and the result of a real trade-off.
List every header env var in the README table (CI enforces this). Update `GLOSSARY.md` when you introduce or change a domain term, and add an ADR in `docs/adr/` only for decisions that are hard to reverse, surprising without context, and the result of a real trade-off.
2 changes: 1 addition & 1 deletion docs/adr/0003-per-script-readmes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ Each script is meant to be copied onto a server on its own, and its users are sy

- Changing a script means editing its folder README, so the maintenance matrix in `AGENTS.md` points at folder READMEs.
- Shared behaviour such as self-update is documented once in the root README and linked from each folder.
- Environment variables are listed in both the script header and the folder README; there is no CI check for drift between them.
- Environment variables are listed in both the script header and the folder README; `check-docs.sh` fails CI when a header variable is missing from the README. Defaults and descriptions are not checked.
23 changes: 14 additions & 9 deletions monitor-domain-hosting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ monitor-aspnet.bat example.com recipient@example.com

## Configuration

Set these variables at the top of `monitor-aspnet.bat` before the first run:

| Variable | Description |
| --- | --- |
| `MYSQL_PASSWORD` | Replace `<password_for_mysql>` with your Plesk MySQL admin password |
| `SMTP_SERVER` | External SMTP relay hostname |
| `SMTP_PORT` | Typically `25`, `465` (SSL) or `587` (STARTTLS) |
| `SMTP_AUTH_USER` / `SMTP_AUTH_PASS` | Relay credentials; leave blank if not required |
| `SMTP_SECURE` | `ssl` or `starttls` if required; blank for plain SMTP |
Before the first run, edit `monitor-aspnet.bat`: replace the `MYSQL_PASSWORD` placeholder and set the SMTP defaults. Each SMTP value can also be overridden by an environment variable of the same name.

| Variable | Default | Description |
| --- | --- | --- |
| `MYSQL_PASSWORD` | `<password_for_mysql>` | Set in the script: your Plesk MySQL admin password |
| `MYSQL_PORT` | `8306` | Plesk MySQL port (set in the script) |
| `DOMAIN` | none | Domain to monitor; the first argument overrides it |
| `NOTIFY_EMAIL` | none | Alert recipient; the second argument overrides it |
| `SMTP_SERVER` | `mail.example.com` | External SMTP relay hostname |
| `SMTP_PORT` | `25` | Typically `25`, `465` (SSL) or `587` (STARTTLS) |
| `SMTP_AUTH_USER` / `SMTP_AUTH_PASS` | blank | Relay credentials; leave blank if not required |
| `SMTP_SECURE` | blank | `ssl` or `starttls` if required; blank for plain SMTP |
| `SMTP_FROM` | `plesk-monitor@<domain>` | Sender address |
| `STATE_DIR` | `%TEMP%\plesk-monitor` | Directory for state files |

> [!WARNING]
> Never commit real passwords. Keep the `<password_for_mysql>` placeholder in the repository and edit only your server's copy.
Expand Down
Loading