fixing wiki generation (#38)
Build and publish release / metadata (push) Canceled after 0s
Build and publish release / create-release (push) Canceled after 0s
Build and publish release / build (push) Canceled after 0s
Build and publish release / publish-release (push) Canceled after 0s
Generate and publish developer Wiki / generated-wiki (push) Failing after 43s
Build and publish release / metadata (push) Canceled after 0s
Build and publish release / create-release (push) Canceled after 0s
Build and publish release / build (push) Canceled after 0s
Build and publish release / publish-release (push) Canceled after 0s
Generate and publish developer Wiki / generated-wiki (push) Failing after 43s
Reviewed-on: #38 Co-authored-by: Koda YeenBean <n122330@gmail.com>
This commit was merged in pull request #38.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -306,5 +306,3 @@ void wlan_clear(void)
|
|||||||
uci_unload(ctx, pkg);
|
uci_unload(ctx, pkg);
|
||||||
uci_free_context(ctx);
|
uci_free_context(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user