What exists, in which repository, and why. Procedures live elsewhere: publishing-automation.md for releases, building-docs.md for documentation.
32 workflow files across 18 repositories.
Callers pin a tag, not a branch, so a change here does not alter a release
until the tag moves. publishing-v2 is current; publishing-v1 remains for
retrying a release cut before the consolidation.
| Workflow | Purpose |
|---|---|
reusable-publish-release-packages.yml |
The whole release chain: resolve the tag, build, publish to TestPyPI, request MIP publication |
reusable-build-pure-python-distribution.yml |
sdist + wheel for a pure-Python package |
reusable-build-native-and-wasm-wheels.yml |
cibuildwheel: Linux, Windows, Android (PEP 738), Pyodide wasm32 |
reusable-build-pydevices-distributions.yml |
The pydevices and pydevices-desktop distributions, derived from lib/ and utils/ |
reusable-request-mip-publication.yml |
Dispatch into mip's serialized publication queue |
reusable-synchronize-mip-package.yml |
Copy a package into mip and generate its manifests |
reusable-validate-pyscript-filesystem-toml.yml |
Check a *.toml filesystem map against the tree it claims to mirror |
The build workflows also check this repository out for its scripts, pinned by
publishing-tools-ref — which defaults to publishing-v2, so workflows and
scripts always come from the same tag.
publish-release-packages.yml in five repositories, each a ~26-line caller of
reusable-publish-release-packages.yml. All they supply is what differs:
| Repository | build-kind |
Distribution | MIP profile |
|---|---|---|---|
pydevices |
pydevices-multi |
pydevices |
pydevices |
palettes |
pure-python |
pydevices-palettes |
palettes |
pdwidgets |
pure-python |
pydevices-pdwidgets |
pdwidgets |
pygraphics |
native-and-wasm |
pydevices-pygraphics |
pygraphics |
lvgl-python |
native-and-wasm |
pydevices-lvgl |
— none |
Triggered by a published GitHub Release, or by workflow_dispatch with an exact
vX.Y.Z tag to retry one.
Cross-repository release plumbing:
| Repository | Workflow | Role |
|---|---|---|
lvgl-bindings |
trigger-lvgl-python-release.yml |
On a bindings change, dispatch lvgl-python's sync |
lvgl-bindings |
check-dispatch-token.yml |
Manual check that LVCPYTHON_MOD_DISPATCH_TOKEN still works |
lvgl-python |
sync-and-release.yml |
Sync generated bindings, commit, publish a Release |
mpftp |
publish-vsix.yml |
Build the VSIX and publish to VS Marketplace / Open VSX |
android-runner |
release_apk.yml |
Build the APK that pydevices/bin/android.py --install-apk downloads |
sync-and-release.ymluses a PAT to create its own repository's Release, which looks redundant and is not: a Release created withGITHUB_TOKENdoes not triggeron: releaseworkflows, sopublish-release-packages.ymlwould never fire and nothing would reach TestPyPI.
| Workflow | Role |
|---|---|
process-mip-publication-request.yml |
Serialized queue consumer: synchronize a package, rebuild the index, deploy |
deploy-mip-index-to-pages.yml |
Compile and publish the index. Triggers on the PyDevices branch, not main |
validate-mip-package-index.yml |
Check index integrity |
tests.yml, ruff.yml, commit-formatting.yml |
Inherited from micropython-lib upstream — leave them alone |
| Repository | Workflow | Notes |
|---|---|---|
pydevices |
tests.yml |
Also validates board MIP installers |
palettes, pdwidgets |
tests.yml |
Sparse-checkout of sibling repos onto PYTHONPATH (pdwidgets needs four) |
pygraphics |
tests.yml |
Runs the suite twice — pure Python, then the native extension via PYGRAPHICS_TEST_NATIVE=1 |
pydevices-examples |
tests.yml, manifests.yml |
Gallery and install-manifest freshness |
pydevices, pygraphics |
validate-pyscript-filesystem-toml.yml |
Standalone callers. pdwidgets and palettes call the same reusable as a job inside tests.yml |
Two repositories publish Pages, plus the portal:
| Repository | What it serves |
|---|---|
PyDevices.github.io |
The portal and every repository's landing page, at /<repo>/. Serves from main, no workflow |
pydevices-examples |
deploy.yml — the PyScript gallery: manifest audits and symlink replacement |
mip |
deploy-mip-index-to-pages.yml — the package index |
Every other landing page is generated by
scripts/generate_sites.py into the portal
repository from data/repos_db.json. Where a page goes
is the entry's page field: portal-root, portal-subdir, self, or none.
There are no per-repo deploy.yml files and no gh-pages branches; thirteen of
each were removed once the portal took over those paths.
A landing page is a single
index.htmlreferencing/assets/chrome/and/assets/img/logo.svgat the portal root.
No repository builds documentation in Actions. ReadTheDocs builds
palettes, pdwidgets, and pygraphics on push via the org GitHub App. A
duplicate mkdocs build used to run here too and was deleted: it passed while
two of the three sites were failing to publish, because mkdocs exits 0 and RTD
then fails the build on output checks mkdocs cannot see.
dependabot.yml watches pinned action versions in the ten repositories that
have workflows, grouped into one weekly PR each. mip is excluded — its
workflows come from upstream.
- Pin actions to a major version (
actions/checkout@v4). - Logic shared by more than one repository belongs in a
reusable-*.ymlhere, called at a pinned tag. - Path filters on
pushandpull_request;workflow_dispatchon anything you might need to re-run by hand. - A workflow that writes to another repository needs a token in
secrets;GITHUB_TOKENcannot reach across repositories, and cannot trigger another workflow even within one.