===================== App manifest CLI flow ===================== Use this flow to generate a manifest and a registration form from the command line, then exchange the return code for credentials. You need a GitHub account allowed to register the app, a browser, and a checkout with ``uv`` installed. For the recommended submission form or manual creation, return to :doc:`github-app`. The steps below configure a local site at ``http://localhost:5000``. The manifest workflow consists of generating JSON, submitting it to GitHub in a browser and exchanging GitHub's return code. **Printing the manifest alone does not register or configure the app.** 1. Prepare the site and its URLs ================================ From the checkout: .. code-block:: shell make dev test -f .env || cp .env.development.example .env mkdir -p data Edit ``.env`` to choose a distinct app name and the address of this site: .. code-block:: shell SITE_NAME=your-unique-development-app-name SITE_URL=http://localhost:5000 Choose an app name of at most 34 characters that is available on GitHub; you can also adjust it on GitHub's confirmation page. ``make app-manifest`` and ``make run`` both read these values. Without an explicit ``SITE_URL``, they use ``http://localhost:5000``. If you use ``PORT=5001``, use that port in both commands and in an explicitly configured ``SITE_URL``. For a deployed site, set ``SITE_URL`` to its public HTTPS address before creating the manifest. See :doc:`run-docker` for deployment. GitHub cannot deliver webhooks to localhost. To test them locally, make the site public with Tailscale Funnel as in :doc:`github-app-tunnel` and set ``SITE_URL`` to that address; every URL of the manifest points to it, the webhook always to ``SITE_URL`` plus ``/github/webhook/``. 2. Generate the manifest ======================== .. code-block:: shell make app-manifest > data/github-app-manifest.json The file contains the required permissions and events. Its default URLs are: .. list-table:: Local URLs :header-rows: 1 * - Purpose - URL * - Homepage and manifest registration return - ``http://localhost:5000/`` * - OAuth sign-in callback - ``http://localhost:5000/accounts/github/login/callback/`` * - Installation setup - ``http://localhost:5000/setup/installed/`` * - Webhook delivery - ``http://localhost:5000/github/webhook/`` For a running container, generate the deployment JSON with ``docker compose exec ai-pycal python manage.py app_manifest`` and save its output to ``data/github-app-manifest.json`` in the checkout used for the next step. The running container must already have the intended ``SITE_URL``. 3. Submit the manifest in your browser ====================================== Create a local registration form with the following command. Change ``organization`` to your organization's GitHub login to register the app there, or leave it empty for your personal account. .. code-block:: shell uv run python - <<'PY' import html import json import secrets from pathlib import Path from urllib.parse import quote, urlencode organization = "" manifest = json.loads(Path("data/github-app-manifest.json").read_text()) for filename in ("data/github-app-state.txt", "data/github-app-register.html"): if Path(filename).exists(): raise SystemExit("Registration files already exist; choose fresh filenames.") registration_url = ( "https://github.com/organizations/" + quote(organization, safe="") + "/settings/apps/new" if organization else "https://github.com/settings/apps/new" ) state = secrets.token_urlsafe(32) action = registration_url + "?" + urlencode({"state": state}) form = ( '