Repository navigation
CI and Releases
The workflows were removed on 2026-09-27 (they consumed minutes and money); on 2026-09-28 the owner asked for build and release on GitHub again, and fast. That earlier decision is reverted and dated here.
There are two workflows:
-
.github/workflows/ci.ymlβ CI: on every push tomaster/feat/**and on every PR (ignoring.mdandupdates/), it compiles, runs the connector tests and uploads the packed editor as an artifact.cancel-in-progressper branch: consecutive pushes do not pile up runs. -
.github/workflows/release.ymlβ Release: triggered by av*tag or by hand (workflow_dispatch). It builds, creates the GitHub release with the zip and its SHA-256, generates the update feed, lands it onmaster, and verifies the feed live.
-
Caches:
node_modules+ the npm cache (the pi runtime's cache too) and the electron binary, keyed onpackage-lock.json. With a warm tree,dev/deps-current.mjsskips the wholenpm ciβ the step that cost 5β8 minutes cold. -
The esbuild route: the product compile uses Microsoft's factory route, re-enabled
(compiling
src/in seconds, not minutes), withtsgostitched into the prepack as the type-check gate. -
A single job, 4 cores: the realistic target is ~10β15 minutes warm and under the
40-minute timeout. Cold (first run or a moved lockfile) takes longer: that is
npm ci, not a failure.
The release procedure and its rules are also documented in the repository's release guide; the workflow carries them inside so they cannot be executed wrong:
- The version lives only in
distribution/product-delta.json. The tag matchesset.picodeVersionβ PiCode's number, the one a release is named after. The release workflow readsset.version(the editor's number) from that file before tagging. - The new version must be strictly greater than the last published release (numeric comparison per segment).
- The feed's commit is read from the built
product.json, not from HEAD. - The feed is generated with
dev/update-feed.mjs --target archive --platform win32 --arch x64and--installed <previous version>;--forceis never passed β if the generator refuses, the release stops. - The feed is landed on the channel branch through a pull request: the
workflow pushes a throwaway
feed-ship-v<picodeVersion>branch built from that branch, opens the PR and merges it at once (branch rules require a PR on every branch, and the GitHub Actions app cannot be a bypass actor here). Then it verifies the feed againstraw.githubusercontent.comuntil seen live (10 tries of 20 s, with CDN cache busting), and the job summary warns if the repository is still private β the feed only reaches users while the repository is public.
The zip is made with 7-Zip, excluding data/ (the portable profile is not product).
The zip is also uploaded as a run artifact for debugging without downloading the release.
- Bump the version in
distribution/product-delta.json β set.version(strictly greater than the last one). - Land it: commit on a branch, open a pull request and merge it. Direct pushes to branches are disabled for contributors; repository admins keep a bypass.
- Tag and push the tag:
git tag v<version> && git push origin v<version>. Tags are not branches, so the tag goes straight up. The workflow does the rest: release + zip + SHA-256 + feed on the channel branch. - The run summary (Actions β Release β summary) carries the version, the commit, the SHA-256, the release and feed URLs, and the visibility warning if applicable.
The manual path (running the same steps by hand) stays valid as a fallback β for example if Actions is unavailable; the rules are the same.
-
Runner/machine RAM: packing asks for more than 6 GB of heap. On an 8 GB machine,
NODE_OPTIONS="--max-old-space-size=5632"; on 16 GB,12288is plenty. Ubuntu 24.04 also shipssystemd-oomd, which kills the whole cgroup under memory pressure without printing "Killed" β stop it before building (sudo systemctl stop systemd-oomd). -
GitHub asset downloads during the build (
js-debugetc.): anonymous requests run out (403 rate limit); withGITHUB_TOKENin the environment,fetch.tsauthenticates itself. -
Debian renames the arch:
.debfiles are generated underamd64, notx64;.rpmfiles underx86_64. -
Installers in sequence: the
prepareandbuildof each format are two invocations β in parallel,buildruns beforepreparecreated the directory (spawn /bin/sh ENOENT). - npm 11 blocks install scripts without explicit per-package approval: the prepare stage writes the approvals for the native packages.
-
Windows looks for Visual Studio in fixed paths: if the tree lives elsewhere,
vs2022_install=<path>is the override it honours. -
zipdoes not exist on Windows runners: the release zip is made with 7-Zip (7z a -tzip, preinstalled there); the local release binary follows the same rule of excludingdata/.
The VS Code pin (upstream/stable.json) is moved by hand (the steps are in
Building PiCode); the watchdog workflow that used to open the pin PR
is gone with the retired build machinery.
Related: Building PiCode Β· Getting PiCode