Files
learnharness/docs/gitea-release.md
T

293 lines
13 KiB
Markdown

# Gitea releases for this fork
The release destination is
https://git.sorokin-oleg-edu.xyz/sorokin.oleg.edu/learnharness.
Version **0.6.2 targets Linux x64 AppImage and Windows x64 NSIS**; follow the
dedicated procedure below. Version 0.6.1 was Linux x64 AppImage-only.
The historical **0.6.0 release targets Linux x64 and Windows x64**, with each platform built
and verified on its native operating system. The upstream GitHub workflow and three-platform packaging
configuration remain available as reference in `.github/workflows/release.yml`
and `electron-builder.yml`.
Official fork packages use `electron-builder.gitea.yml`, which inherits the
upstream packaging and replaces its update origin with:
```
https://git.sorokin-oleg-edu.xyz/sorokin.oleg.edu/learnharness/releases/download/latest
```
Gitea's `latest` alias resolves the most recent published, non-prerelease release.
Drafts do not become updates. The repository and published downloads must be
public; no API credential is embedded in the application.
## 0.6.2: Linux AppImage and Windows installer
Build both platforms from the same release commit with Node 26. Use a clean
checkout on each native operating system so local credentials, environment
files, application data, and older packages cannot enter the standalone payload.
The Windows installer retains the existing unsigned per-user NSIS configuration.
After dependency installation, run the typecheck, deterministic tests, lint,
native renderer tests, and standalone runtime smoke checks. Include
`tests/desktop-logger.test.ts` under each platform's bundled Electron Node to
exercise the broken-pipe and retention regressions in the shipped runtime.
Curate the standalone payload with `node scripts/build-server.mjs`, then package:
```sh
# Native Linux checkout
npx electron-builder --config electron-builder.gitea.yml --linux AppImage --x64 --publish never
# Native Windows checkout
npx electron-builder --config electron-builder.gitea.yml --win --x64 --publish never
```
Verify each packaged updater with `scripts/gitea-release.mjs verify-package` and
run the provider, server, and browser-helper smoke checks against that package's
own standalone tree and executable. Copy only these six assets into a staging
directory (the checksum command creates the final file):
- `LearnHarness-0.6.2-x86_64.AppImage`
- `LearnHarness-0.6.2-x64-setup.exe`
- `LearnHarness-0.6.2-x64-setup.exe.blockmap`
- `latest-linux.yml`
- `latest.yml`
- `SHA256SUMS`
```sh
node scripts/gitea-release.mjs checksums /path/to/staging --appimage-windows
node scripts/gitea-release.mjs verify /path/to/staging --appimage-windows
```
This explicit scope preserves the historical Linux defaults and AppImage-only
mode. It rejects extra staged files, checks both installer headers and updater
feeds against the actual bytes, regenerates the Windows blockmap with the pinned
packager to verify every chunk and full installer coverage, and verifies the
combined SHA-256 manifest. It includes no Debian, RPM, or macOS packages.
Commit and push the release source and its matching annotated `v0.6.2` tag.
Supply the Gitea API token privately, then prepare and verify the draft:
```sh
node scripts/gitea-release.mjs upload /path/to/staging --appimage-windows
node scripts/gitea-release.mjs verify-remote /path/to/staging --appimage-windows
```
The uploader reads notes from `docs/release-0.6.2.md`, requires the remote tag,
keeps the release a stable draft, and downloads all six attachments to compare
their SHA-256 hashes with the validated local files. It refuses published or
ambiguous releases and mismatched existing attachments. Publication follows
human review of the completed draft.
## Historical 0.6.1: Linux x64 AppImage-only upload and verification
This release has exactly three attachments:
- `LearnHarness-0.6.1-x86_64.AppImage`
- `latest-linux.yml`
- `SHA256SUMS`
No Windows, macOS, Debian (`.deb`), or RPM packages belong in this release.
Use `docs/release-0.6.1.md` for the release notes. The procedures below this
section retain the historical 0.6.0/full-release instructions; do not use their
Debian/Windows asset inventory for 0.6.1.
Stage only the three listed files for upload. Before upload, generate and verify
checksums using the existing helper's explicit offline AppImage-only mode:
```sh
node scripts/gitea-release.mjs checksums dist --appimage-only
node scripts/gitea-release.mjs verify dist --appimage-only
```
Run these commands from the 0.6.1 source checkout. They validate the AppImage,
feed version, filename, size, SHA-512, and SHA-256 manifest. `SHA256SUMS` must
cover only the AppImage and `latest-linux.yml`. The offline verifier checks the
expected files, not the absence of unrelated files: separately check that the
upload selection contains exactly the three names above. Confirm the packaged
`resources/app-update.yml` has the generic provider and the current update URL
shown above before uploading.
The unchanged `desktop:release:linux` script still builds AppImage and Debian
packages, so do not use it or the historical manual Actions workflow for this
AppImage-only release. Package explicitly with:
```sh
electron-builder --config electron-builder.gitea.yml --linux AppImage --x64 --publish never
```
After building and verifying the copied server/runtime, verify the embedded
updater with `node scripts/gitea-release.mjs verify-package dist/linux-unpacked`.
The helper uses the current host and accepts `--appimage-only` for `checksums`,
`verify`, `upload`, and `verify-remote`; omitting this flag retains the historical
AppImage-plus-Debian inventory. Supply `GITEA_TOKEN` privately for API operations:
```sh
node scripts/gitea-release.mjs upload dist --appimage-only
node scripts/gitea-release.mjs verify-remote dist --appimage-only
```
The uploader creates or reuses a draft and verifies downloaded attachment bytes;
it does not publish the release. Publication is a separate explicitly authorized
API action after these checks pass.
After the release tag `v0.6.1` exists at the intended source commit in the current
Gitea repository, create or review a draft for that tag on
`git.sorokin-oleg-edu.xyz`. Set its notes from `docs/release-0.6.1.md` and explicitly
upload only the three listed files. Before publication:
1. Confirm the draft tag is `v0.6.1` and its attachment inventory is exactly the
three names above, with sizes matching the locally verified files.
2. Download those three draft attachments into a separate directory and run
`node scripts/gitea-release.mjs verify /path/to/downloaded-assets --appimage-only`
from the 0.6.1 source checkout. Compare the downloaded `SHA256SUMS` byte-for-byte
with the locally verified manifest; stop on any mismatch.
3. Review the notes and asset exclusions. Publication is a separate,
explicitly authorized action; a draft does not update installed clients.
After authorized publication, confirm the current host's public
`releases/download/latest/latest-linux.yml` resolves to version `0.6.1` and
references `LearnHarness-0.6.1-x86_64.AppImage` with the verified size and SHA-512.
## Historical 0.6.0 / full-release instructions
The following commands and asset inventories are retained for reference. Their
upload tooling still defaults to the old host; they are not the current 0.6.1
upload procedure.
## Preparing Linux packages
Use Node **26**, matching upstream's release gates. Build from a clean checkout
of the intended release commit. Keep `.env*`, local keys, and application data out
of the build directory. Next can copy loaded environment files after tracing;
`build-server.mjs` refuses a payload containing them. A clean worktree avoids
loading these files in the first place.
```sh
npm ci
npm run typecheck
npm test
npm run lint
ELECTRON_RUN_AS_NODE=1 npx electron --import tsx --test tests/pdf-native-render.test.ts tests/pdf-ops.test.ts tests/svg-native-render.test.ts tests/browser-service.test.ts
npm run desktop:release:linux
```
The release script builds the standalone server, initializes providers offline,
curates the payload, boots it under Electron's bundled Node, packages AppImage
and Debian installers, checks the packaged Gitea updater configuration, creates SHA-256 checksums, and verifies update metadata
against the actual installer bytes.
Run the packaged-runtime gates too:
```sh
node scripts/smoke-provider-runtime.mjs --standalone dist/linux-unpacked/resources/server/standalone
node scripts/smoke-provider-runtime.mjs --standalone dist/linux-unpacked/resources/server/standalone --runtime dist/linux-unpacked/learnharness
xvfb-run -a node scripts/smoke-demo-runtime.mjs --standalone dist/linux-unpacked/resources/server/standalone --runtime dist/linux-unpacked/learnharness --browser
```
The Linux portion of 0.6.0 has these attachments:
- `LearnHarness-0.6.0-x86_64.AppImage`
- `LearnHarness-0.6.0-amd64.deb`
- `latest-linux.yml`
- `SHA256SUMS`
## Preparing Windows packages
Use a clean checkout of the same `v0.6.0` tag on Windows x64 with Node 26 and Git
for Windows. Keep build tools and logs outside the checkout. The Windows
release checkout is `~/Documents/Gitea/learnharness-release-0.6.0`, linked to the
existing repository in `~/Documents/Gitea/learnharness`.
In PowerShell, stop after any failed command:
```powershell
npm.cmd ci
$env:NODE_ENV = 'test'
$env:ELECTRON_RUN_AS_NODE = '1'
node node_modules/electron/cli.js --import tsx --test tests/pdf-native-render.test.ts tests/pdf-ops.test.ts tests/svg-native-render.test.ts tests/browser-service.test.ts
Remove-Item Env:ELECTRON_RUN_AS_NODE
node --import tsx --test tests/i18n.test.tsx
Remove-Item Env:NODE_ENV
node node_modules/next/dist/bin/next build
node scripts/smoke-provider-runtime.mjs
node scripts/build-server.mjs
node scripts/smoke-server.mjs --electron
node node_modules/electron-builder/out/cli/cli.js --config electron-builder.gitea.yml --win --x64 --publish never
node scripts/gitea-release.mjs verify-package dist/win-unpacked
node scripts/smoke-provider-runtime.mjs --standalone dist/win-unpacked/resources/server/standalone
node scripts/smoke-provider-runtime.mjs --standalone dist/win-unpacked/resources/server/standalone --runtime dist/win-unpacked/LearnHarness.exe
node scripts/smoke-demo-runtime.mjs --standalone dist/win-unpacked/resources/server/standalone --runtime dist/win-unpacked/LearnHarness.exe --browser
```
Windows contributes three attachments:
- `LearnHarness-0.6.0-x64-setup.exe`
- `LearnHarness-0.6.0-x64-setup.exe.blockmap`
- `latest.yml`
The combined release has **seven attachments**, including one `SHA256SUMS`
covering all six other files. Verify that `latest.yml` names the Windows
installer exactly, reports version `0.6.0`, and matches the installer's actual
size and SHA-512. Its gzip blockmap must cover the installer and match every
block checksum. Confirm the packaged `resources/app-update.yml` uses the Gitea
generic provider. Windows builds follow upstream's unsigned, per-user installer
configuration.
## Preparing a Linux-only Gitea draft
Commit and push the release source, then push its exact annotated tag:
```sh
git tag -a v0.6.0 -m 'LearnHarness 0.6.0'
git push gitea main v0.6.0
```
Supply `GITEA_TOKEN` only to the upload command. A token file may remain outside
the clean build checkout:
```sh
node --env-file=/path/to/private/release.env scripts/gitea-release.mjs upload dist
```
The tool requires the tag to exist in Gitea, creates or reuses one draft at that
tag, uploads missing assets, and downloads every attachment to verify its actual
SHA-256 against the local verified build. Existing mismatched attachments and
published releases are refused. It never publishes or changes repository
visibility. Release notes come from `docs/release-0.6.0.md`.
This uploader and its remote verifier enforce a **Linux-only** inventory. They
will refuse a combined Linux/Windows draft. For the combined 0.6.0 release, add
the verified Windows attachments to the existing draft and replace `SHA256SUMS`
with the combined manifest. Keep the Linux installers and feed unchanged. Check
all seven attachment names and sizes against the verified local builds. For
the owner-approved 0.6.0 release, local installer/feed/blockmap validation and
the combined checksum manifest are completed before upload. Confirm successful
upload responses and publish immediately afterward; do not download attachments
again or run post-upload hash checks. Do not publish until both platforms'
local checks pass.
A separate verification can be repeated without changing the draft:
```sh
node --env-file=/path/to/private/release.env scripts/gitea-release.mjs verify-remote dist
```
Review the verified draft before publication. Only after publication will the
public `latest` feed and in-app automatic updates expose this version.
## Gitea Actions
`.gitea/workflows/release.yml` provides the same Linux gates through a manual
workflow with an existing release tag as input. It requires a native Linux x64
runner labeled `ubuntu-24.04`, the label used by upstream's Linux release job,
plus the native Electron dependencies and `xvfb-run`. There were no runners
registered when 0.6.0 was prepared, so its packages are built locally. A tag push
does not queue a job that cannot run.
The workflow uses the repository's ephemeral `GITEA_TOKEN` with release-write
permission only in the final upload step. It checks out the requested tag without
persisting credentials and leaves the result as a verified draft. Public pull
requests cannot trigger this publishing workflow. This workflow remains
Linux-only; the combined 0.6.0 draft was assembled from local native builds.
Windows has its own standalone payload and smoke checks, as described above.