Add PKG installer + Forgejo Release pipeline + Homebrew Cask integration #4
Loading…
Reference in a new issue
No description provided.
Delete branch "add-pkg-release-pipeline"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Wires
latvian-apostrofsinto the same release/distribution flow thatlatvian-spell-checkeralready uses, so users have three install paths instead of one (./install.shonly):LatvianApostrofs-<version>.pkgfrom a Forgejo Release, double-click, admin password, done.brew tap ojars/pareizrakstiba … && brew install --cask apostrofs(tap repo updated separately, commit4484e80)../install.sh— existing per-user path, unchanged.Files added
build-pkg.sh(170 lines) — assembles a flat.pkgviapkgbuild+productbuildwith welcome/conclusion/license panels and a postinstallxattr -rd com.apple.quarantinestep. Built locally and verified on macOS Tahoe 26.4.1 (sudo installer -pkg … -target /→ files at/Library/Keyboard Layouts/{latvian_apostrofs.keylayout,.icns},root:wheel 755, no quarantine, byte-identical SHA-256,pkgutil --pkg-info lv.kapteinis.latvian-apostrofsregistered)..forgejo/workflows/release.yml(95 lines) — tag-push (v*) triggers on the macmini Forgejo runner (instance scope since 2026-05-08): build PKG → SHA → create Forgejo Release with formatted body → upload asset → clone tap → sed-bumpCasks/apostrofs.rb(version + sha256) → push..gitignore— excludesbuild/.Mirrors spell-checker, differs in 3 ways
.zip); the cask uses thepkgstanza directly viapkgutilfor clean uninstall.Net: workflow is 95 lines vs spell-checker's 132.
Manual step required after merge
Set
FORGEJO_RELEASE_TOKENsecret on this repo (Settings → Secrets), with the same token value already present onojars/latvian-spell-checker. Without it the workflow can't create the Release or push to the tap.Test plan
VERSION=2026.05.0 bash build-pkg.sh) → 8.4K artifact produced, distribution.xml + welcome/conclusion/license rendered correctly.sudo installer -pkg build/LatvianApostrofs-2026.05.0.pkg -target /) → files placed correctly with right perms + no quarantine; receipt registered.#and Alt+4=€in TextEdit.v2026.05.0onmainafter this PR merges → CI runs on macmini → release surfaces at https://git.kapteinis.lv/ojars/latvian-apostrofs/releases → cask sha bumped on tap.brew install --cask apostrofssmoke test after release lands.Tap commit
Companion commit on
ojars/homebrew-pareizrakstibaalready pushed:4484e80addsCasks/apostrofs.rb(placeholder version+sha until first release) and restructures the tap README into a 2-cask layout with per-cask install/activate/uninstall sections.🤖 Generated with Claude Code
Two scope-of-token changes addressing minimum-permission feedback: 1. Release creation + asset upload now uses ${{ secrets.GITHUB_TOKEN }} (auto-provided by Forgejo, scoped to this repo, has release-write permission). No manual secret setup required. 2. Cross-repo cask auto-bump on homebrew-pareizrakstiba is dropped. That step would have required a personal token with write access to the tap repo, and apostrofs releases are infrequent enough (the underlying keyboard layout last changed in 2013) that a manual one-liner is proportional. The workflow's final step now prints the exact sed+commit+push command for the operator to copy-paste after each release surfaces. Net: zero secrets to configure. The workflow runs on `git push tag v*` with no prior repo-settings changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Updated per review: dropped
FORGEJO_RELEASE_TOKENdependency entirely.Two changes in commit
00fcf79:${{ secrets.GITHUB_TOKEN }}(Forgejo auto-provides this, scoped to the calling repo with release-write permission). No manual secret setup.homebrew-pareizrakstibaremoved. That was the only piece needing a personal token with broader scope. Apostrofs release cadence (the keyboard layout itself last changed in 2013) doesn't justify carrying a cross-repo write token; the workflow now prints the exactsed + commit + pushcommand for the operator to run after each release.Net: zero secrets to configure on this repo.
git push tag v*is sufficient.Self-review (operator-triggered, since auto-Teika isn't wired up here — tracked at infra-docs#120)
Reviewed: 4 commits (1 squashed), 290 lines added across 3 new files.
Verified live
bash build-pkg.shwithVERSION=2026.05.0produced an 8.4K PKG inbuild/.sudo installer -pkg build/LatvianApostrofs-2026.05.0.pkg -target /placed both files at/Library/Keyboard Layouts/withroot:wheel 755, nocom.apple.quarantine, byte-identical SHA-256 to the repo source.pkgutil --pkg-info lv.kapteinis.latvian-apostrofsreturns the receipt.#, Alt+4 →€. Layout works as installed.Diff coverage
.gitignore: trivially correct (build/).build-pkg.sh: standardpkgbuild+productbuildflow,set -euo pipefail, idempotent (rm -rf buildat start), usesditto --norsrc --noextattr --noqtnto stage payload (preserves byte-identity), postinstall script stripscom.apple.quarantine. Distribution.xml hashostArchitectures="x86_64,arm64"+os-version min="10.6"(matches the layout's pre-Lion compatibility). LICENSE + welcome + conclusion text accurate to attribution rules.release.yml: triggeron: push: tags: "v*", runs onmacosrunner. Uses${{ secrets.GITHUB_TOKEN }}(auto-provided by Forgejo, scoped to this repo, has release-write). Final step prints the manual tap-bump command instead of cross-repo pushing.Concerns / known limitations
build-pkg.shnot intest.ymlshellcheck list. test.yml only lintsinstall.sh uninstall.sh. Filing as a small follow-up — would extend the existingshellcheckstep to also coverbuild-pkg.sh. Not blocking — scriptset -euo pipefail+ tested locally.release.yml. No way to dry-run a Forgejo Release without actually creating one. Plan: tagv2026.05.0after merge, watch macmini runner; if it fails at the release-creation step, delete the failed Release + retry. Documented rollback path.0.0.0/ zero-sha.brew install --cask apostrofswould 404 until the first release lands. Correct/desired: cask isn't useful until the artifact exists.POST /releasesstep, and we'll need to fall back to settingFORGEJO_RELEASE_TOKENafter all (~30s of UI work). Acceptable risk — reversible.Verdict
APPROVED for merge. Will squash-merge to
mainand proceed to Phase 3 (tag-push test release) on operator approval. Items 1+2 are observable on first release run; item 4 is a known reversible risk.