Add built-in updater, bump to 1.2.0
- predatord checks the Gitea releases every 6 hours, downloads the newest pacman package, verifies its SHA-256 from the release notes and installs it with `pacman -U` in a separate systemd unit - Update notice and install button on the System page, in the sidebar and in the panel widget; `predatorctl update [--check] [--yes]` - Optional API token for private repositories - packaging/release.py builds and publishes releases in the format the updater expects Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
# sudo pacman -U predator-control-*.pkg.tar.zst
|
||||
|
||||
pkgname=predator-control
|
||||
pkgver=1.1.0
|
||||
pkgver=1.2.0
|
||||
pkgrel=1
|
||||
pkgdesc="PredatorSense replacement for Acer Predator laptops: performance modes, fans, keyboard RGB, lightbar, battery (Qt app + Plasma widget)"
|
||||
arch=('any')
|
||||
@@ -22,7 +22,7 @@ install=predator-control.install
|
||||
source=()
|
||||
|
||||
_src="$(realpath "$startdir/../..")"
|
||||
_modver=1.1.0
|
||||
_modver=1.2.0
|
||||
|
||||
package() {
|
||||
cd "$_src"
|
||||
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build the pacman package and publish a Gitea release for the current version.
|
||||
|
||||
Usage: GITEA_TOKEN=... packaging/release.py
|
||||
Requires a clean working tree and the tag v<version> already pushed.
|
||||
The release notes are taken from CHANGELOG.md and contain the package's SHA-256,
|
||||
which the built-in updater uses to verify downloads.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.request
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
API = "https://git.mrblake.cc/api/v1/repos/MrBlake/Cachy-Predator-Keyboard"
|
||||
|
||||
|
||||
def api(method, path, data=None, ctype="application/json"):
|
||||
headers = {"Authorization": "token " + os.environ["GITEA_TOKEN"]}
|
||||
if data is not None:
|
||||
headers["Content-Type"] = ctype
|
||||
req = urllib.request.Request(API + path, data=data, method=method, headers=headers)
|
||||
return json.load(urllib.request.urlopen(req))
|
||||
|
||||
|
||||
def main():
|
||||
if "GITEA_TOKEN" not in os.environ:
|
||||
sys.exit("set GITEA_TOKEN")
|
||||
version = re.search(r'__version__ = "([^"]+)"', open(os.path.join(ROOT, "predator_control/__init__.py")).read())[1]
|
||||
pkgbuild = open(os.path.join(ROOT, "packaging/arch/PKGBUILD")).read()
|
||||
if "pkgver=%s\n" % version not in pkgbuild:
|
||||
sys.exit("PKGBUILD pkgver does not match version %s" % version)
|
||||
pkgrel = re.search(r"^pkgrel=(\d+)", pkgbuild, re.M)[1]
|
||||
|
||||
arch_dir = os.path.join(ROOT, "packaging/arch")
|
||||
subprocess.run(["makepkg", "-f", "--cleanbuild"], cwd=arch_dir, check=True)
|
||||
pkg = "predator-control-%s-%s-any.pkg.tar.zst" % (version, pkgrel)
|
||||
data = open(os.path.join(arch_dir, pkg), "rb").read()
|
||||
sha = hashlib.sha256(data).hexdigest()
|
||||
|
||||
changelog = open(os.path.join(ROOT, "CHANGELOG.md")).read()
|
||||
notes = changelog.split("## %s" % version, 1)[1].split("\n## ", 1)[0].split("\n", 1)[1].strip()
|
||||
body = notes + f"""
|
||||
|
||||
### Install (Arch / CachyOS / Manjaro)
|
||||
```bash
|
||||
sudo pacman -S --needed linux-cachyos-headers clang lld llvm # stock Arch kernel: linux-headers
|
||||
sudo pacman -U {pkg}
|
||||
```
|
||||
Already installed via pacman? Use the built-in updater (System page, panel widget or `predatorctl update`).
|
||||
|
||||
SHA-256 `{pkg}`: `{sha}`
|
||||
|
||||
Not affiliated with Acer Inc."""
|
||||
|
||||
rel = api("POST", "/releases", json.dumps({
|
||||
"tag_name": "v" + version, "name": "Predator Control " + version,
|
||||
"body": body, "draft": False, "prerelease": False}).encode())
|
||||
boundary = "----predator" + sha[:16]
|
||||
mp = (f'--{boundary}\r\nContent-Disposition: form-data; name="attachment"; filename="{pkg}"\r\n'
|
||||
f"Content-Type: application/octet-stream\r\n\r\n").encode() + data + f"\r\n--{boundary}--\r\n".encode()
|
||||
api("POST", "/releases/%d/assets?name=%s" % (rel["id"], pkg), mp, "multipart/form-data; boundary=" + boundary)
|
||||
print("Released", rel["html_url"])
|
||||
print("SHA-256", sha)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user