Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
403f3a3
initial check-endpoints refactor and output comparison
nstillman-te Feb 26, 2026
f7c7ada
format
nstillman-te Feb 26, 2026
ab32835
fix example script usage filename
nstillman-te Feb 26, 2026
c9c1637
initial check-endpoints workflow
nstillman-te Feb 26, 2026
a14a8fb
add push trigger for testing on branch
nstillman-te Feb 26, 2026
ac01c9e
update exit code handling
nstillman-te Feb 26, 2026
1eb4f10
whitespace trigger
nstillman-te Feb 26, 2026
e0e7002
use bullets not checklist
nstillman-te Feb 26, 2026
6ac0df2
change checklist wording
nstillman-te Feb 26, 2026
cd9cc83
update issue title
nstillman-te Feb 26, 2026
bcdff3d
add daily cron for testing
nstillman-te Feb 26, 2026
e5d566f
remove test cron
nstillman-te Feb 26, 2026
f88440a
cleanup
nstillman-te Feb 26, 2026
2952c56
delete sample output
nstillman-te Feb 26, 2026
5ccb198
commet in cron
nstillman-te Feb 26, 2026
5ef5b37
fix close-issue logic
nstillman-te Feb 27, 2026
f38f14a
fix exit code handling
nstillman-te Feb 27, 2026
b891c93
add initial check-endpoint script tests
nstillman-te Feb 27, 2026
ec33e59
add missing-params tests, allow client-dir option for check-endpoints.py
nstillman-te Feb 27, 2026
c4eb681
working missing-params tests
nstillman-te Feb 27, 2026
4b8c098
add tests for clients-dir, missing-endpoints, matching spec/client, f…
nstillman-te Feb 27, 2026
f0cb64d
add tests for other code paths
nstillman-te Feb 27, 2026
4a96eb1
formatted
nstillman-te Feb 27, 2026
f38455c
update CONTRIBUTING
nstillman-te Feb 27, 2026
2d4176b
show human-readable output in CI logs
nstillman-te Feb 27, 2026
cd79850
add test trigger
nstillman-te Feb 27, 2026
9ce233b
log issue body not duplicate script-run output
nstillman-te Feb 27, 2026
4a9b1b4
remove push trigger
nstillman-te Feb 27, 2026
4f1f72d
fix comment
nstillman-te Feb 27, 2026
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
122 changes: 122 additions & 0 deletions .github/workflows/check-endpoints.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Spec vs implementation: run check-endpoints.py against the latest Lichess API spec,
# and create or update a single issue with a list of missing endpoints/params.
# See also: issue #6 (historical umbrella).

# When enabling schedule: uncomment the schedule block below.
# Duration: weekly. Cron "0 3 * * 1" = Monday 03:00 UTC (avoids overlap with 02:00 cassette refresh if present).
# GitHub does not support variables in cron; change the cron string if you want a different interval (e.g. "0 3 * * 1" weekly, "0 3 1 * *" monthly).
name: Check endpoints (spec vs implementation)

on:
workflow_dispatch: {}
# Weekly (e.g. for production): "0 3 * * 1" = Monday 03:00 UTC
schedule:
- cron: "0 3 * * 1"

jobs:
check-endpoints:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install PyYAML
run: pip install pyyaml

- name: Fetch API spec
run: |
mkdir -p spec
curl -fsSL -o spec/openapi.yaml "https://lichess.org/api/openapi.yaml"

- name: Run check-endpoints
run: |
python check-endpoints.py --json spec/openapi.yaml > output.json 2>stderr.txt || { cat stderr.txt; exit 1; }

- name: Update issue from check result
env:
GH_TOKEN: ${{ github.token }}
run: |
HAS_MISSING=$(python3 -c "
import json
with open('output.json') as f:
data = json.load(f)
me = data.get('missing_endpoints') or []
mp = data.get('missing_params') or []
print('true' if (me or mp) else 'false')
")
if [ "$HAS_MISSING" = "true" ]; then
BODY=$(python3 - << 'PY'
import json
import sys
with open("output.json") as f:
data = json.load(f)
intro = """This issue is automatically updated by the [check-endpoints](.github/workflows/check-endpoints.yml) workflow. Manual edits to the list below will be overwritten. For historical context and implementation notes, see issue 6.

*Note: The text above and the list below are for testing only (e.g. when this workflow runs on a fork).*

"""
parts = [intro]
if data.get("missing_endpoints"):
parts.append("## Missing endpoints (path, operation)\n\n")
for e in data["missing_endpoints"]:
path, op = e["path"], e["operation"]
parts.append(f"- `{op}` `{path}`\n")
parts.append("\n")
if data.get("missing_params"):
parts.append("## Missing query params (implemented endpoints)\n\n")
for p in data["missing_params"]:
path, op = p["path"], p["operation"]
params = ", ".join(f"`{x}`" for x in p["params"])
method = p.get("method", "")
parts.append(f"- `{op}` `{path}` — missing: {params} — {method}\n")
sys.stdout.write("".join(parts))
PY
)
echo "----- check-endpoints issue body -----"
printf '%s\n' "$BODY"
echo "--------------------------------------"
echo "$BODY" > body.md
ISSUE_NUM=$(gh issue list --repo "${{ github.repository }}" --state open --limit 1 --json number --jq '.[0].number' --search 'in:title "Spec vs implementation: missing endpoints or params (auto-updated)"' 2>/dev/null || true)
if [ -n "$ISSUE_NUM" ]; then
gh issue edit "$ISSUE_NUM" --body-file body.md
echo "Updated issue #$ISSUE_NUM"
else
OLD_NUM=$(gh issue list --repo "${{ github.repository }}" --state all --limit 1 --json number --jq '.[0].number' --search 'in:title "Spec vs implementation: missing endpoints or params (auto-updated)"' 2>/dev/null || true)
if [ -n "$OLD_NUM" ]; then
gh issue reopen "$OLD_NUM"
gh issue edit "$OLD_NUM" --body-file body.md
echo "Reopened and updated issue #$OLD_NUM"
else
gh issue create --title "Spec vs implementation: missing endpoints or params (auto-updated)" --body-file body.md
echo "Created new issue"
fi
fi
else
python3 - << 'PY'
intro = """This issue is automatically updated by the [check-endpoints](.github/workflows/check-endpoints.yml) workflow. Manual edits to the list below will be overwritten. For historical context and implementation notes, see issue 6.

*Note: The text above and the list below are for testing only (e.g. when this workflow runs on a fork).*

---

No missing endpoints or params as of this run. This issue will be reopened when the spec gains new endpoints or params we don't implement.
"""
with open("body.md", "w") as f:
f.write(intro)
PY
ISSUE_NUM=$(gh issue list --repo "${{ github.repository }}" --state open --limit 1 --json number --jq '.[0].number' --search 'in:title "Spec vs implementation: missing endpoints or params (auto-updated)"' 2>/dev/null || true)
if [ -n "$ISSUE_NUM" ]; then
gh issue edit "$ISSUE_NUM" --body-file body.md
gh issue close "$ISSUE_NUM" --comment "No missing endpoints or params as of this run. This issue will be reopened when the spec gains new endpoints or params we don't implement."
echo "Closed issue #$ISSUE_NUM"
fi
fi
14 changes: 13 additions & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,19 @@ Look through the GitHub issues for bugs.
Implement Missing Endpoints
~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can run the ``check-endpoints.py`` script (requires yaml to be installed, ``pip3 install pyyaml``) in the root of the project to get a list of endpoints that are still missing.
The ``check-endpoints.py`` script (in the project root) compares the client code in ``berserk/clients/`` to the Lichess API spec and reports missing endpoints and missing query parameters. It requires PyYAML (``pip install pyyaml`` or use the project env via ``uv run``).

Run from the repo root with a path to the spec (e.g. a local OpenAPI YAML or the deployed spec)::

uv run python check-endpoints.py path/to/openapi.yaml

Use ``--json`` for machine-readable output (e.g. for CI). Use ``--clients-dir DIR`` to point at a different client tree (default is ``berserk/clients``). Exit 0 on success; non-zero on error (bad args, spec not found). When nothing is missing, both ``missing_endpoints`` and ``missing_params`` in the JSON are empty lists.

**CI and auto-generated issue:** The workflow in ``.github/workflows/check-endpoints.yml`` runs on a schedule (and manually via workflow_dispatch). It fetches the latest spec from the Lichess API, runs the script, and creates or updates a single issue titled "Spec vs implementation: missing endpoints or params (auto-updated)" with the current list. When there are no missing items, it closes that issue (after updating its body). This issue is the live checklist; see the historical umbrella issue in the repo for context.

**Tests for check-endpoints.py:** The script has its own tests in ``dev_tests/test_check_endpoints.py``. These are **not** run by ``make test`` (which only runs ``tests/``). To run them manually::

uv run pytest dev_tests/test_check_endpoints.py -v

Write Documentation
~~~~~~~~~~~~~~~~~~~
Expand Down
Loading