Skip to content

Commit 1c69fd7

Browse files
committed
ci: report settings and docker variable drift against the poweradmin repo weekly
1 parent 9202bb4 commit 1c69fd7

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

.github/workflows/drift.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Check Drift Against Poweradmin
2+
3+
# Scheduled rather than blocking: this drift is caused by changes in the
4+
# poweradmin repo, not by the docs commit under test, so it must not fail a
5+
# deploy. Same reasoning as the external link check.
6+
on:
7+
schedule:
8+
- cron: '0 7 * * 1' # Mondays, 07:00 UTC
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
drift:
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout docs
20+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21+
22+
- name: Checkout poweradmin
23+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
24+
with:
25+
repository: poweradmin/poweradmin
26+
path: poweradmin
27+
ref: master
28+
29+
- name: Settings reference is current
30+
run: |
31+
python3 scripts/gen_settings_reference.py \
32+
--settings poweradmin/config/settings.defaults.php \
33+
--version "$(grep -oE "'[0-9]+\.[0-9]+\.[0-9]+'" poweradmin/lib/Version.php | head -1 | tr -d "'")" \
34+
--out docs/configuration/settings-reference.md --check
35+
36+
# DOCKER.md lives in the code repo by design; this only reports on it.
37+
- name: Docker variables are documented
38+
if: always()
39+
run: |
40+
python3 scripts/check_docker_env.py \
41+
--entrypoint poweradmin/docker-entrypoint.sh \
42+
--docs poweradmin/DOCKER.md

scripts/check_docker_env.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python3
2+
"""Report PA_* environment variables the Docker entrypoint uses but DOCKER.md omits.
3+
4+
Both files live in the poweradmin repo; this only checks them, because that is
5+
where the fix belongs.
6+
"""
7+
import argparse
8+
import re
9+
import sys
10+
from pathlib import Path
11+
12+
VAR_RE = re.compile(r"\bPA_[A-Z0-9_]+\b")
13+
# Secrets are supplied either as PA_FOO or PA_FOO__FILE; documenting one covers both.
14+
FILE_SUFFIX = "__FILE"
15+
16+
17+
def names(path):
18+
return {canonical(v) for v in VAR_RE.findall(path.read_text())}
19+
20+
21+
def canonical(var):
22+
return var[:-len(FILE_SUFFIX)] if var.endswith(FILE_SUFFIX) else var
23+
24+
25+
def used_names(path):
26+
"""Variables the entrypoint actually consumes.
27+
28+
Two kinds of match are not real variables:
29+
- a truncated prefix from a glob in a log message (PA_SAML_*_ENABLED)
30+
- a name the entrypoint tests only so it can warn that it is NOT
31+
recognised (PA_PDNS_BACKEND exists purely to redirect to PA_DNS_BACKEND)
32+
"""
33+
lines = path.read_text().split("\n")
34+
seen = {}
35+
for line in lines:
36+
for var in VAR_RE.findall(line):
37+
seen.setdefault(canonical(var), []).append(line)
38+
return {
39+
var for var, refs in seen.items()
40+
if not var.endswith("_")
41+
and not any(f"{var} is not a recognized variable" in ref for ref in refs)
42+
}
43+
44+
45+
def main():
46+
ap = argparse.ArgumentParser()
47+
ap.add_argument("--entrypoint", required=True, type=Path)
48+
ap.add_argument("--docs", required=True, type=Path)
49+
args = ap.parse_args()
50+
51+
used, documented = used_names(args.entrypoint), names(args.docs)
52+
undocumented = sorted(used - documented)
53+
unused = sorted(documented - used)
54+
55+
print(f"{len(used)} variables used, {len(documented)} documented")
56+
if unused:
57+
print(f"\nDocumented but not referenced by the entrypoint ({len(unused)}):")
58+
for v in unused:
59+
print(f" {v}")
60+
if undocumented:
61+
print(f"\nUsed by the entrypoint but missing from DOCKER.md ({len(undocumented)}):")
62+
for v in undocumented:
63+
print(f" {v}")
64+
sys.exit(1)
65+
print("\nEvery variable the entrypoint uses is documented.")
66+
67+
68+
if __name__ == "__main__":
69+
main()

0 commit comments

Comments
 (0)