fixing wiki generation
Generate and publish developer Wiki / generated-wiki (pull_request) Successful in 14s

This commit is contained in:
2026-07-19 21:32:10 +00:00
parent 8bf3e03de8
commit f5d14b0a79
13 changed files with 105 additions and 62 deletions
+42 -5
View File
@@ -1,9 +1,15 @@
name: Validate source documentation name: Generate and publish developer Wiki
on: on:
pull_request: pull_request:
push:
branches: [main]
workflow_dispatch: workflow_dispatch:
concurrency:
group: openunifi-wiki
cancel-in-progress: false
permissions: permissions:
code: read code: read
@@ -11,10 +17,41 @@ jobs:
generated-wiki: generated-wiki:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Check out source repository
uses: actions/checkout@v4
with: with:
fetch-depth: 2 fetch-depth: 2
- name: Check generated Gitea Wiki pages path: source
run: ./scripts/docs/generate-wiki.py --check
- name: Check patch whitespace - name: Check patch whitespace
run: git diff --check HEAD^ run: git -C source diff --check HEAD^ HEAD
- name: Validate documentation generator
run: |
mkdir -p "$RUNNER_TEMP/openuf-wiki"
python3 source/scripts/docs/generate-wiki.py --output "$RUNNER_TEMP/openuf-wiki"
python3 source/scripts/docs/generate-wiki.py --check --output "$RUNNER_TEMP/openuf-wiki"
- name: Check out Wiki repository
if: github.event_name != 'pull_request'
uses: actions/checkout@v4
with:
repository: Koda/openunifi.wiki
token: ${{ secrets.GITEA_TOKEN }}
path: wiki
- name: Generate and verify Gitea Wiki pages
if: github.event_name != 'pull_request'
run: |
python3 source/scripts/docs/generate-wiki.py --output wiki
python3 source/scripts/docs/generate-wiki.py --check --output wiki
- name: Publish changed Wiki pages
if: github.event_name != 'pull_request'
working-directory: wiki
run: |
set -eu
git config user.name "openUF documentation bot"
git config user.email "actions@openuf.invalid"
git add -- Home.md Developer-Guide.md Call-Graph.md Runtime-Flow.md _Sidebar.md
if git diff --cached --quiet; then
echo "Gitea Wiki is already current"
exit 0
fi
git commit -m "docs: update generated developer wiki"
git push origin HEAD
+5 -2
View File
@@ -22,8 +22,11 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Verify generated developer Wiki - name: Validate documentation generator
run: ./scripts/docs/generate-wiki.py --check run: |
mkdir -p "$RUNNER_TEMP/openuf-wiki"
python3 ./scripts/docs/generate-wiki.py --output "$RUNNER_TEMP/openuf-wiki"
python3 ./scripts/docs/generate-wiki.py --check --output "$RUNNER_TEMP/openuf-wiki"
- name: Install metadata dependencies - name: Install metadata dependencies
run: sudo apt-get update && sudo apt-get install --yes jq run: sudo apt-get update && sudo apt-get install --yes jq
- name: Read release configuration - name: Read release configuration
+3 -3
View File
@@ -74,11 +74,11 @@ make package/OpenUniFi/compile
packages installed; it is not a host-side substitute for the cross-build. packages installed; it is not a host-side substitute for the cross-build.
Architecture pages for the Gitea Wiki are generated from the recursive C source Architecture pages for the Gitea Wiki are generated from the recursive C source
tree. After source or architecture changes, run: tree into a separate checkout. After source or architecture changes, run:
```sh ```sh
./scripts/docs/generate-wiki.py ./scripts/docs/generate-wiki.py --output /path/to/openunifi.wiki
./scripts/docs/generate-wiki.py --check ./scripts/docs/generate-wiki.py --check --output /path/to/openunifi.wiki
``` ```
There is currently no automated test suite. For documentation-only changes, There is currently no automated test suite. For documentation-only changes,
+16 -9
View File
@@ -48,25 +48,32 @@ architecture map, invariants, and validation checklist.
## Developer documentation and Gitea Wiki ## Developer documentation and Gitea Wiki
The publish-ready Gitea Wiki pages live in [`wiki/`](wiki/). They include a The publish-ready pages live in the separate `Koda/openunifi.wiki` repository.
developer guide, a generated Mermaid function-call graph, and runtime flow They include a developer guide, a generated Mermaid function-call graph, and
charts. Refresh them after source or architecture changes: runtime flow charts. Check out that repository, then refresh it after source or
architecture changes:
```shell ```shell
./scripts/docs/generate-wiki.py ./scripts/docs/generate-wiki.py --output /path/to/openunifi.wiki
``` ```
Use the same tool as a linter to reject stale pages, oversized C modules, Use the same tool as a linter to reject stale pages, oversized C modules,
missing documented entry points, or known non-English comment fragments: missing documented entry points, or known non-English comment fragments:
```shell ```shell
./scripts/docs/generate-wiki.py --check ./scripts/docs/generate-wiki.py --check --output /path/to/openunifi.wiki
``` ```
Because Gitea stores Wiki pages in a separate Git repository, publishing is an The generator uses only the Python 3 standard library, and the publisher uses
explicit authenticated step: `./scripts/docs/publish-wiki.sh`. The script POSIX shell utilities and Git. Neither downloads or executes an x86-only helper,
derives the `.wiki.git` URL from `origin` and accepts an explicit URL override. so both run natively on ARM and x86 build agents.
No credentials are stored in this repository.
Publishing is an explicit authenticated step: `./scripts/docs/publish-wiki.sh`.
The script derives the lowercase `.wiki.git` repository URL from `origin`,
checks it out before generating, and accepts an explicit URL override. No
credentials are stored in this repository. The documentation workflow performs
the same two-checkout process and requires `GITEA_TOKEN` to have write access to
`Koda/openunifi.wiki`.
## Automated releases ## Automated releases
+26 -18
View File
@@ -12,7 +12,6 @@ from pathlib import Path
REPOSITORY_ROOT = Path(__file__).resolve().parents[2] REPOSITORY_ROOT = Path(__file__).resolve().parents[2]
SOURCE_ROOT = REPOSITORY_ROOT / "src" SOURCE_ROOT = REPOSITORY_ROOT / "src"
DEFAULT_WIKI_ROOT = REPOSITORY_ROOT / "wiki"
MAX_IMPLEMENTATION_LINES = 900 MAX_IMPLEMENTATION_LINES = 900
CONTROL_WORDS = { CONTROL_WORDS = {
@@ -325,18 +324,22 @@ development packages installed. It is not a host-side test substitute.
## Documentation workflow ## Documentation workflow
Generate pages after changing C code or architecture: Check out the separate `openunifi.wiki` repository, then generate pages after
changing C code or architecture:
```sh ```sh
./scripts/docs/generate-wiki.py ./scripts/docs/generate-wiki.py --output /path/to/openunifi.wiki
``` ```
Run the linter-style drift and structure check in CI or before committing: Run the linter-style drift and structure check in CI or before committing:
```sh ```sh
./scripts/docs/generate-wiki.py --check ./scripts/docs/generate-wiki.py --check --output /path/to/openunifi.wiki
``` ```
The generator uses only the Python 3 standard library. The publisher uses POSIX
shell utilities and Git, so neither path depends on the runner CPU architecture.
The checker parses C functions recursively, rebuilds internal call edges, The checker parses C functions recursively, rebuilds internal call edges,
validates required runtime entry points, rejects known non-English comment validates required runtime entry points, rejects known non-English comment
fragments, and limits each implementation unit to fragments, and limits each implementation unit to
@@ -344,21 +347,20 @@ fragments, and limits each implementation unit to
## Publishing to the Gitea Wiki ## Publishing to the Gitea Wiki
Gitea stores a repository Wiki in a separate Git repository whose URL normally Gitea stores this documentation in the separate lowercase
ends in `.wiki.git`. The generated `wiki/` directory is ready for that remote. `openunifi.wiki` repository. Run `scripts/docs/publish-wiki.sh` from a trusted
Run `scripts/docs/publish-wiki.sh` from a trusted machine with suitable machine with suitable credentials. It derives that repository from `origin`;
credentials. It derives the Wiki remote from `origin`; an explicit URL may be an explicit URL may be passed when needed. The publisher checks out the Wiki
passed when needed. The publisher regenerates and checks the pages, repository before generating, updates only the generated Markdown files,
updates only the generated Markdown files, commits changed pages, and pushes commits changed pages, and pushes them back to the Wiki repository.
them to the Wiki repository.
""" """
def home_page() -> str: def home_page() -> str:
return """# openUF Developer Wiki return """# openUF Developer Wiki
This Wiki is generated from the current source tree and maintained in the main This Wiki is generated from the current source tree and maintained in the
repository so architecture documentation changes can be reviewed with code. separate `openunifi.wiki` repository.
- [[Developer Guide|Developer-Guide]] — architecture, invariants, extension - [[Developer Guide|Developer-Guide]] — architecture, invariants, extension
points, build validation, and Wiki publishing. points, build validation, and Wiki publishing.
@@ -367,7 +369,8 @@ repository so architecture documentation changes can be reviewed with code.
- [[Function Call Graph|Call-Graph]] — generated internal caller/callee graph - [[Function Call Graph|Call-Graph]] — generated internal caller/callee graph
and searchable function table. and searchable function table.
Run `./scripts/docs/generate-wiki.py --check` to verify these pages are current. Run `./scripts/docs/generate-wiki.py --check --output /path/to/openunifi.wiki`
from the source checkout to verify these pages are current.
""" """
@@ -543,8 +546,10 @@ def main() -> int:
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--check", action="store_true", parser.add_argument("--check", action="store_true",
help="fail if generated pages or source checks are stale") help="fail if generated pages or source checks are stale")
parser.add_argument("--output", type=Path, default=DEFAULT_WIKI_ROOT, parser.add_argument(
help="Wiki output directory (default: repository wiki/)") "--output", type=Path, required=True, metavar="WIKI_CHECKOUT",
help="path to the checked-out openunifi.wiki repository",
)
arguments = parser.parse_args() arguments = parser.parse_args()
functions = discover_functions() functions = discover_functions()
@@ -568,8 +573,11 @@ def main() -> int:
for error in errors: for error in errors:
print(f"documentation error: {error}", file=sys.stderr) print(f"documentation error: {error}", file=sys.stderr)
if arguments.check: if arguments.check:
print("run ./scripts/docs/generate-wiki.py to refresh pages", print(
file=sys.stderr) "run ./scripts/docs/generate-wiki.py --output "
f"{output} to refresh pages",
file=sys.stderr,
)
return 1 return 1
action = "verified" if arguments.check else "generated" action = "verified" if arguments.check else "generated"
+13 -17
View File
@@ -17,10 +17,13 @@ if [ -z "$wiki_repository_url" ]; then
echo "no origin remote found; pass the Gitea Wiki repository URL" >&2 echo "no origin remote found; pass the Gitea Wiki repository URL" >&2
exit 2 exit 2
fi fi
case $origin_url in source_repository_url=${origin_url%.git}
*.git) wiki_repository_url=${origin_url%.git}.wiki.git ;; repository_parent=${source_repository_url%/*}
*) wiki_repository_url=${origin_url}.wiki.git ;; repository_name=${source_repository_url##*/}
esac wiki_repository_name=$(
printf '%s' "$repository_name" | tr '[:upper:]' '[:lower:]'
)
wiki_repository_url="$repository_parent/$wiki_repository_name.wiki.git"
fi fi
cleanup() { cleanup() {
@@ -28,20 +31,11 @@ cleanup() {
} }
trap cleanup EXIT HUP INT TERM trap cleanup EXIT HUP INT TERM
"$script_directory/generate-wiki.py"
"$script_directory/generate-wiki.py" --check
git clone -- "$wiki_repository_url" "$temporary_directory/wiki" git clone -- "$wiki_repository_url" "$temporary_directory/wiki"
for page in \ "$script_directory/generate-wiki.py" --output "$temporary_directory/wiki"
Home.md \ "$script_directory/generate-wiki.py" --check \
Developer-Guide.md \ --output "$temporary_directory/wiki"
Call-Graph.md \
Runtime-Flow.md \
_Sidebar.md
do
cp -- "$repository_root/wiki/$page" "$temporary_directory/wiki/$page"
done
cd "$temporary_directory/wiki" cd "$temporary_directory/wiki"
git add -- Home.md Developer-Guide.md Call-Graph.md Runtime-Flow.md _Sidebar.md git add -- Home.md Developer-Guide.md Call-Graph.md Runtime-Flow.md _Sidebar.md
@@ -51,5 +45,7 @@ if git diff --cached --quiet; then
exit 0 exit 0
fi fi
git commit -m "docs: update generated developer wiki" git -c user.name="openUF documentation bot" \
-c user.email="actions@openuf.invalid" \
commit -m "docs: update generated developer wiki"
git push origin HEAD git push origin HEAD
-1
View File
@@ -145,4 +145,3 @@ char *inform_packet_parse(const unsigned char *data, size_t data_len,
copy[body_len] = '\0'; copy[body_len] = '\0';
return copy; return copy;
} }
-1
View File
@@ -799,4 +799,3 @@ char *inform_build_payload(const openuf_state_t *st,
json_object_put(root); json_object_put(root);
return copy; return copy;
} }
-1
View File
@@ -358,4 +358,3 @@ void inform_handle_response(openuf_state_t *st,
snprintf(action_out, 64, "unknown:%s", type); snprintf(action_out, 64, "unknown:%s", type);
} }
-1
View File
@@ -268,4 +268,3 @@ int wlan_apply_system_cfg(const char *system_cfg,
json_object_put(root); json_object_put(root);
return result; return result;
} }
-1
View File
@@ -583,4 +583,3 @@ int wlan_apply_config(struct json_object *config_json,
system("/etc/init.d/usteer restart >/dev/null 2>&1"); system("/etc/init.d/usteer restart >/dev/null 2>&1");
return 0; return 0;
} }
-1
View File
@@ -315,4 +315,3 @@ void wlan_apply_radio(struct json_object *radio_json,
uci_unload(ctx, pkg); uci_unload(ctx, pkg);
uci_free_context(ctx); uci_free_context(ctx);
} }
-2
View File
@@ -306,5 +306,3 @@ void wlan_clear(void)
uci_unload(ctx, pkg); uci_unload(ctx, pkg);
uci_free_context(ctx); uci_free_context(ctx);
} }