make-cloudflare
Cloudflare Pages direct upload for mkrun, in
Python: publish a built directory with no Node on the machine and no wrangler
in the pipeline.
# Makefile.py in a consuming repo
# /// script
# requires-python = ">=3.11"
# dependencies = ["mkrun>=0.4", "make-cloudflare>=0.1"]
# ///
from make_cloudflare import cloudflare # importing is what registers the group
$ mk cloudflare.deploy site/dist --project mkrun # production (branch main)
$ mk cloudflare.deploy site/dist --branch try # a preview, on its own URL
$ mk cloudflare.projects # what the account has
$ mk cloudflare.deployments --limit 5 # one project's recent ones
$ mk -n cloudflare.deploy site/dist # the plan; nothing is sent
Credentials are the two variables wrangler already reads, so a repository that
deploys from CI needs no new secret: CLOUDFLARE_ACCOUNT_ID and
CLOUDFLARE_API_TOKEN (a token with Cloudflare Pages: Edit). The token's
name ends in TOKEN, so mkrun treats it as a credential — it is withheld from
the environment until a task asks for it, redacted in everything printed, and
readable from the encrypted store. The project can come from --project or from
CLOUDFLARE_PAGES_PROJECT in the repo's env layer.
Why this exists
wrangler pages deploy is four HTTPS calls and a hash. Reaching them through
npx costs a Node toolchain in repositories that otherwise have none — a Rust
one, a frontage one — and a
node_modules in the deploy image of every one of them.
POST /accounts/<acct>/pages/projects/<p>/upload-token -> a short-lived JWT
POST /pages/assets/check-missing -> what is not stored yet
POST /pages/assets/upload -> the files, batched
POST /pages/assets/upsert-hashes
POST /accounts/<acct>/pages/projects/<p>/deployments -> the manifest
Three things make a naive port wrong, and all three fail silently — every call returns 200 and the site serves the old bytes, or none:
- The hash is BLAKE3 of a strange input: the base64 text of the contents
with the extension (no dot) appended, first 32 hex characters. Not of the
bytes, and not SHA-256.
tests/test_pages.pylocks it with a golden value. _headers,_redirectsand_routes.jsonare not assets. They are fields on the deployment. Walk them in as ordinary files and the deploy reports success while the site's CSP stops applying.check-missing,uploadandupsert-hashestake the JWT, not the account token, and carry no/accounts/<id>prefix — the JWT already names the account.
What it does not do
Pages Functions. A directory holding _worker.js or functions/ is
refused by name rather than half-deployed: bundling a Worker is a build step,
not an upload, and wrangler should keep doing it.
Steps 2 and 3 are undocumented. They exist because wrangler uses them, and
Cloudflare can change them without a changelog; the documented deployments
endpoint alone cannot upload a file. That is the real cost of dropping
wrangler, and it is the reason this is a small module with a golden test rather
than a wrapper nobody reads.
Nothing here is specific to any owner or account. The group name is
cloudflare, and it merges with a repo's own cloudflare.* tasks — groups are
namespaces — so only a same-named task collides; this package claims deploy,
projects and deployments, nothing else. blake3 is the one dependency, and
it lives here rather than in the runner so mkrun itself stays dependency-free.
Metadata
Release files for make-cloudflare 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| make_cloudflare-0.1.0.tar.gz | 12.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| make_cloudflare-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.4 kB
Release files / make_cloudflare-0.1.0.tar.gz
| Download URL | make_cloudflare-0.1.0.tar.gz |
|---|---|
| Size | 12.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
459debbfebcf2c3404ec3ee3f724ec4ff7bde69040ceba3c8051d6c8a824326d
|
|
BLAKE2b-256 checksum How to use checksums |
cc25064b4a3a2501a1fb12e8cc799248d1b52ec13a3c15abce4e57d8beced22c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / make_cloudflare-0.1.0-py3-none-any.whl
| Download URL | make_cloudflare-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1cf9df07c6ebb74f1041ef255a3a0d1d6838fd2917db9cbb0b8ea5664cb98136
|
|
BLAKE2b-256 checksum How to use checksums |
e838dc93ce7873fe2527a97c42dbcb6336fbdf988d572a6abcfcd2724de5b047
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|