From ca99c24b011c58843854b3a94a8336da21fba20b Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Sat, 5 Sep 2026 01:09:11 -0400 Subject: [PATCH] Add ARM builds for 1Password and Voxtype --- .gitignore | 1 + README.md | 58 ++++++- bin/sync-upstream | 141 +++++++++++++++- helpers/package-metadata.sh | 30 +++- helpers/upstream-github.sh | 174 ++++++++++++++++---- pkgbuilds/1password/.omarchy/package.json | 17 +- pkgbuilds/1password/PKGBUILD | 34 ++-- pkgbuilds/voxtype-bin/.omarchy/package.json | 81 ++++++++- pkgbuilds/voxtype-bin/PKGBUILD | 89 +++++++--- 9 files changed, 538 insertions(+), 87 deletions(-) diff --git a/.gitignore b/.gitignore index d5f201f4..3f0c128d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.firecrawl/ src/ logs/ build-output/ diff --git a/README.md b/README.md index c34f0047..d57fcb1a 100644 --- a/README.md +++ b/README.md @@ -339,7 +339,8 @@ bin/sync-upstream openai-codex-desktop # Update specific packages Some vendors publish a release feed of their own that is faster and more precise than the AUR packaging of it. Those packages are `source: local` — Omarchy owns -the PKGBUILD — and declare where releases come from in one of two ways. +the PKGBUILD — and declare where releases come from either as data or, for an +unusual feed, a small hook. A vendor shipping tagged GitHub releases is pure data, declared as `upstream` in `.omarchy/package.json` with no code at all: @@ -361,6 +362,32 @@ digest GitHub's release API reports for every asset — see `pkgbuilds/schist-bin/.omarchy/package.json`. Either way the artifacts themselves are never downloaded. +An architecture may map to an ordered array when its PKGBUILD downloads more +than one release asset. Small versioned files outside the release assets can be +listed under `sources` and are downloaded and hashed when a new version appears: + +```json +"upstream": { + "github": "owner/project", + "digests": true, + "assets": { + "x86_64": ["tool-{pkgver}-x86_64", "tool-{pkgver}-x86_64.asc"], + "aarch64": ["tool-{pkgver}-aarch64", "tool-{pkgver}-aarch64.asc"] + }, + "sources": { + "any": ["https://raw.githubusercontent.com/owner/project/{tag}/LICENSE"] + } +} +``` + +Asset and source keys must be disjoint because each key maps to one PKGBUILD +checksum array (`any` means the unsuffixed `sha256sums`). + +Repositories whose historical releases use incompatible tag schemes may set +`"latest_only": true`. The provider then considers only the newest stable +GitHub release, while retaining all validation for that release. A quarantine +will wait for that release to age instead of falling back to an older one. + `{tag}` and `{pkgver}` interpolate into asset names; a leading `v` on the tag is stripped for `pkgver`; drafts and prereleases are ignored. Only the 100 most recent releases are considered. The provider fails closed on anything it cannot @@ -403,14 +430,33 @@ the tarball named by the selected dist-tag: `dist_tag` defaults to `latest`. The registry's publication timestamp is carried into the provider result, so `min_release_age` works for npm packages. -Exactly one of `github`, `git_tags`, or `npm` may appear in a declaration. + +A vendor with a plain-text Debian `Packages` index can use it to discover the +newest exact package version, then hash immutable source URLs: + +```json +"upstream": { + "debian": "https://example.com/debian/dists/stable/main/binary-amd64/Packages", + "package": "example-app", + "sources": { + "x86_64": ["https://example.com/tool-{pkgver}-x64.tar.gz"], + "aarch64": ["https://example.com/tool-{pkgver}-arm64.tar.gz"] + } +} +``` + +This deliberately accepts only Debian versions that are already valid Arch +`pkgver` values. Feeds needing epoch, revision, or filename translation retain +a hook. Exactly one of `github`, `git_tags`, `npm`, or `debian` may appear in a +declaration. A timestamped provider may also declare `"min_release_age": "24h"` (`s`/`m`/`h`/`d` suffix or bare seconds) to quarantine fresh releases until maintainers have had time to pull a bad or compromised one. GitHub Releases and -npm provide publication times; raw git tags do not, so combining `git_tags` -with this policy fails closed. The newest release that has cleared the window -ships, so a fast release cadence cannot starve updates. The window is enforced +npm provide publication times; raw git tags and Debian Packages indexes do not, +so combining either with this policy fails closed. The newest release that has +cleared the window ships, so a fast release cadence cannot starve updates. The +window is enforced centrally: whatever reports the release must prove its age via `published_at`, or the sync fails. A maintainer deliberately shipping inside the window runs `BYPASS_MIN_RELEASE_AGE=1 bin/sync-upstream ` locally and merges the @@ -679,7 +725,7 @@ Minimal examples: Fields: - `source`: `aur` or `local`. A `local` package can still follow an upstream release, either declaratively via `upstream` or with an `.omarchy/upstream.sh` hook. -- `upstream`: optional for `local` packages whose vendor ships tagged GitHub releases. `{ "github": "owner/repo", "checksums": "SHASUMS256.txt", "assets": { "": "name-{tag}.tar.xz" } }`, or `"digests": true` in place of `checksums` to use the release API's per-asset digests — see [Sync Upstream Releases](#sync-upstream-releases). Mutually exclusive with `.omarchy/upstream.sh`. +- `upstream`: optional for `local` packages following GitHub releases, git tags, npm dist-tags, or a Debian `Packages` index. GitHub architecture assets may be a string or an ordered array, and can be combined with disjoint versioned `sources` — see [Sync Upstream Releases](#sync-upstream-releases). Mutually exclusive with `.omarchy/upstream.sh`. - `min_release_age`: optional quarantine for upstream releases (`"24h"`, `"2d"`, or bare seconds). The newest release older than the window ships; anything younger waits, and a release whose age cannot be proven fails the sync. Bypass deliberately with `BYPASS_MIN_RELEASE_AGE=1 bin/sync-upstream `. - `sync`: optional for AUR packages; defaults to `true`. Set `false` for AUR-origin packages that Omarchy maintains manually. - `aur`: optional AUR package name when it differs from the local package directory, usually for split packages. diff --git a/bin/sync-upstream b/bin/sync-upstream index 04c7ac62..8b2864d2 100755 --- a/bin/sync-upstream +++ b/bin/sync-upstream @@ -20,8 +20,8 @@ Update packages that track an upstream vendor release feed instead of the AUR. Packages opt in declaratively through "upstream" in .omarchy/package.json. Providers cover GitHub Releases with checksum manifests or API asset digests, -semver-shaped git tags whose source URLs can be hashed, and npm dist-tags. See README.md for the -schemas. Anything outside those conventions may provide +semver-shaped git tags, npm dist-tags, and plain Debian Packages indexes. See +README.md for the schemas. Anything outside those conventions may provide pkgbuilds//.omarchy/upstream.sh, a hook that reports JSON on stdout: { @@ -378,6 +378,7 @@ sync_package() { github) release=$(github_upstream_release "$package_dir" "$min_age") || release_status=$? ;; git_tags) release=$(git_tags_upstream_release "$package_dir") || release_status=$? ;; npm) release=$(npm_upstream_release "$package_dir") || release_status=$? ;; + debian) release=$(debian_upstream_release "$package_dir") || release_status=$? ;; esac if [[ ${release_status:-0} -ne 0 ]]; then print_error "$provider upstream provider failed for $package" @@ -544,6 +545,31 @@ EOF check "bypass lifts the quarantine" "2.0.0" "$(jq -r '.pkgver // ""' <<<"$out")" check "x86_64 checksum via * binary-mode prefix" "$sum_x20" "$(jq -r '.sha256sums.x86_64[0] // ""' <<<"$out")" + cp "$pkg/.omarchy/package.json" "$pkg/normal.json" + jq '.upstream.latest_only = true' "$pkg/normal.json" > "$pkg/.omarchy/package.json" + FIXTURE_RELEASES=$(jq -n --arg old "$old2d" '[ + {tag_name: "v1.9.0", published_at: $old, draft: false, prerelease: false}, + {tag_name: "v0.4.1-8", published_at: $old, draft: false, prerelease: false} + ]') + FIXTURE_CHECKSUMS=$(printf '%s\n' \ + "$sum_x19 ./tool-v1.9.0-x64.tar.xz" \ + "$sum_a19 ./tool-v1.9.0-arm64.tar.xz") + out=$(github_upstream_release "$pkg" 0 2>/dev/null) || out="" + check "latest_only ignores incompatible historical tags" "1.9.0" "$(jq -r '.pkgver // ""' <<<"$out")" + cp "$pkg/normal.json" "$pkg/.omarchy/package.json" + FIXTURE_RELEASES=$(jq -n --arg young "$young" --arg old2 "$old2d" --arg old3 "$old3d" '[ + {tag_name: "v2.0.0", published_at: $young, draft: false, prerelease: false}, + {tag_name: "v1.9.9", published_at: $old2, draft: false, prerelease: true}, + {tag_name: "v1.9.8", published_at: $old2, draft: true, prerelease: false}, + {tag_name: "v1.9.0", published_at: $old2, draft: false, prerelease: false}, + {tag_name: "v1.8.0", published_at: $old3, draft: false, prerelease: false} + ]') + FIXTURE_CHECKSUMS=$(printf '%s\n' \ + "$sum_x19 ./tool-v1.9.0-x64.tar.xz" \ + "$sum_a19 tool-v1.9.0-arm64.tar.xz" \ + "$sum_x20 *tool-v2.0.0-x64.tar.xz" \ + "$sum_a20 tool-v2.0.0-arm64.tar.xz") + out=$(github_upstream_release "$pkg" 8640000 2>/dev/null) || out="" check "everything quarantined reports no update" "{}" "$(jq -c . <<<"$out")" @@ -637,6 +663,117 @@ EOF check "provider rejects a non-boolean digests" "1" "$rc" cp "$digpkg/good.json" "$digpkg/.omarchy/package.json" + echo "Ordered GitHub assets with supplemental sources:" + local multipkg="$TEMP_DIR/selftest-multi-assets" multi_sum support_sum multi_vst + mkdir -p "$multipkg/.omarchy" + printf 'pkgver=1.0.0\npkgrel=1\n' > "$multipkg/PKGBUILD" + cat > "$multipkg/.omarchy/package.json" <<'EOF' +{ + "source": "local", + "upstream": { + "github": "example/tool", + "digests": true, + "assets": { + "x86_64": ["tool-{pkgver}-x86_64", "tool-{pkgver}-x86_64.asc"], + "aarch64": ["tool-{pkgver}-aarch64", "tool-{pkgver}-aarch64.asc"] + }, + "sources": { + "any": ["https://example.test/tool/{tag}/support.txt"] + } + } +} +EOF + local sum_x19_sig sum_a19_sig + sum_x19_sig=$(printf '1%.0s' {1..64}) + sum_a19_sig=$(printf '2%.0s' {1..64}) + FIXTURE_RELEASES=$(jq -n --arg old "$old2d" --arg x "$sum_x19" --arg xs "$sum_x19_sig" \ + --arg a "$sum_a19" --arg as "$sum_a19_sig" '[ + {tag_name: "v1.9.0", published_at: $old, draft: false, prerelease: false, assets: [ + {name: "tool-1.9.0-x86_64", digest: ("sha256:" + $x)}, + {name: "tool-1.9.0-x86_64.asc", digest: ("sha256:" + $xs)}, + {name: "tool-1.9.0-aarch64", digest: ("sha256:" + $a)}, + {name: "tool-1.9.0-aarch64.asc", digest: ("sha256:" + $as)} + ]} + ]') + upstream_fetch_source() { printf 'remote fixture for %s\n' "$1" > "$2"; } + multi_sum=$(github_upstream_release "$multipkg" 0 2>/dev/null) || multi_sum="" + support_sum=$(printf 'remote fixture for %s\n' 'https://example.test/tool/v1.9.0/support.txt' | sha256sum | cut -d' ' -f1) + check "ordered GitHub assets produce an ordered checksum array" "$sum_x19 $sum_x19_sig" \ + "$(jq -r '.sha256sums.x86_64 | join(" ")' <<<"$multi_sum")" + check "GitHub supplemental source is downloaded and hashed" "$support_sum" \ + "$(jq -r '.sha256sums.any[0]' <<<"$multi_sum")" + multi_vst=0; validate_package_metadata "$multipkg" >/dev/null || multi_vst=$? + check "GitHub asset lists and disjoint sources validate" "0" "$multi_vst" + jq '.upstream.sources.x86_64 = ["https://example.test/duplicate"]' \ + "$multipkg/.omarchy/package.json" > "$multipkg/overlap.json" + cp "$multipkg/.omarchy/package.json" "$multipkg/good.json" + cp "$multipkg/overlap.json" "$multipkg/.omarchy/package.json" + multi_vst=0; validate_package_metadata "$multipkg" >/dev/null || multi_vst=$? + check "GitHub assets and sources cannot target the same checksum array" "1" "$multi_vst" + cp "$multipkg/good.json" "$multipkg/.omarchy/package.json" + + echo "Debian Packages provider:" + local debpkg="$TEMP_DIR/selftest-debian" deb_sum deb_x_sum deb_a_sum deb_vst + mkdir -p "$debpkg/.omarchy" + printf 'pkgver=1.0.0\npkgrel=1\nsha256sums_x86_64=("old")\nsha256sums_aarch64=("old")\n' > "$debpkg/PKGBUILD" + cat > "$debpkg/.omarchy/package.json" <<'EOF' +{ + "source": "local", + "upstream": { + "debian": "https://packages.example.test/dists/stable/main/binary-amd64/Packages", + "package": "example-app", + "sources": { + "x86_64": ["https://downloads.example.test/app-{pkgver}-x64.tar.gz"], + "aarch64": ["https://downloads.example.test/app-{pkgver}-arm64.tar.gz"] + } + } +} +EOF + debian_fetch_packages() { + cat <<'EOF' +Package: unrelated +Version: 99.0.0 + +Package: example-app +Version: 1.9.0 + +Package: example-app +Version: 1.10.0 +EOF + } + deb_sum=$(debian_upstream_release "$debpkg") + deb_x_sum=$(printf 'remote fixture for %s\n' 'https://downloads.example.test/app-1.10.0-x64.tar.gz' | sha256sum | cut -d' ' -f1) + deb_a_sum=$(printf 'remote fixture for %s\n' 'https://downloads.example.test/app-1.10.0-arm64.tar.gz' | sha256sum | cut -d' ' -f1) + check "Debian provider selects the newest exact package stanza" "1.10.0" "$(jq -r '.pkgver' <<<"$deb_sum")" + check "Debian x86_64 source is hashed" "$deb_x_sum" "$(jq -r '.sha256sums.x86_64[0]' <<<"$deb_sum")" + check "Debian aarch64 source is hashed" "$deb_a_sum" "$(jq -r '.sha256sums.aarch64[0]' <<<"$deb_sum")" + deb_vst=0; validate_package_metadata "$debpkg" >/dev/null || deb_vst=$? + check "Debian declaration validates" "0" "$deb_vst" + printf 'pkgver=1.10.0\npkgrel=1\nsha256sums_x86_64=("old")\nsha256sums_aarch64=("old")\n' > "$debpkg/PKGBUILD" + check "checked-in Debian version avoids source downloads" "{}" "$(debian_upstream_release "$debpkg" | jq -c .)" + + echo "End-to-end Debian sync with the checked-in 1password recipe:" + local one_root="$TEMP_DIR/e2e-1password" one_dir one_version=8.12.35 + mkdir -p "$one_root" + cp -a "$BUILD_ROOT/pkgbuilds/1password" "$one_root/1password" + one_dir="$one_root/1password" + debian_fetch_packages() { + printf 'Package: 1password\nVersion: %s\n' "$one_version" + } + upstream_fetch_source() { printf 'remote fixture for %s\n' "$1" > "$2"; } + local one_prev_updated=$UPDATED one_prev_failed=$FAILED + PKGBUILDS_DIR="$one_root" sync_package 1password >/dev/null 2>&1 || true + check "1password sync updates without failures" "updated=1 failed=0" \ + "updated=$((UPDATED - one_prev_updated)) failed=$((FAILED - one_prev_failed))" + check "1password pkgver is the single download version source" "$one_version" \ + "$(grep -m1 '^pkgver=' "$one_dir/PKGBUILD" | cut -d= -f2-)" + check "1password pkgrel resets to 1" "1" \ + "$(grep -m1 '^pkgrel=' "$one_dir/PKGBUILD" | cut -d= -f2-)" + check "1password x86 URL follows the rewritten pkgver" "1password-${one_version}.x64.tar.gz" \ + "$(CARCH=x86_64 bash -c 'source "$1"; basename "${source_x86_64[0]}"' _ "$one_dir/PKGBUILD")" + check "1password ARM URL follows the rewritten pkgver" "1password-${one_version}.arm64.tar.gz" \ + "$(CARCH=aarch64 bash -c 'source "$1"; basename "${source_aarch64[0]}"' _ "$one_dir/PKGBUILD")" + echo "Quarantine backstop:" local rel st rel=$(jq -n --arg p "$old2d" '{pkgver: "1.9.0", published_at: $p, sha256sums: {}}') diff --git a/helpers/package-metadata.sh b/helpers/package-metadata.sh index 7382bbf2..043e2fc5 100644 --- a/helpers/package-metadata.sh +++ b/helpers/package-metadata.sh @@ -15,10 +15,11 @@ # { "source": "local", "channels": ["edge"] } # { "source": "local", "channels": ["edge", "rc", "stable"] } # { "source": "local", "min_release_age": "24h" } -# { "source": "local", "upstream": { "github": "owner/repo", "checksums": "SHASUMS256.txt", "assets": { "x86_64": "name-{tag}-x64.tar.xz" } } } +# { "source": "local", "upstream": { "github": "owner/repo", "checksums": "SHASUMS256.txt", "assets": { "x86_64": ["name-{tag}-x64.tar.xz"] } } } # { "source": "local", "upstream": { "github": "owner/repo", "digests": true, "assets": { "x86_64": "name-{tag}-x64.tar.xz" } } } # { "source": "local", "upstream": { "git_tags": "https://example/repo.git", "tag_pattern": "v{pkgver}", "sources": { "any": ["https://example/archive/{tag}.tar.gz"] } } } # { "source": "local", "upstream": { "npm": "@scope/package", "sources": { "any": ["{npm_tarball}"] } } } +# { "source": "local", "upstream": { "debian": "https://example/debian/dists/stable/main/binary-amd64/Packages", "package": "example", "sources": { "any": ["https://example/releases/{pkgver}.tar.gz"] } } } # # bin/sync-aur also writes upstream_commit for AUR-backed packages, and # bin/sync-rebuilds writes rebuilt_against for packages declaring rebuild_on. @@ -482,30 +483,45 @@ validate_package_metadata() { (.key | test("\\A[a-z0-9_]+\\z")) and (.value | type == "array" and length > 0 and all(type == "string" and length > 0)) )); + def valid_assets: + type == "object" and length > 0 and (to_entries | all( + (.key | test("\\A[a-z0-9_]+\\z")) + and (.value | + (type == "string" and length > 0) + or (type == "array" and length > 0 and all(type == "string" and length > 0) and (unique | length) == length) + ) + )); if has("upstream") | not then true elif (.upstream | type) != "object" then false else .upstream | - ([has("github"), has("git_tags"), has("npm")] | map(select(.)) | length) == 1 + ([has("github"), has("git_tags"), has("npm"), has("debian")] | map(select(.)) | length) == 1 and if has("github") then (.github | type == "string" and test("\\A[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+\\z")) and (if has("checksums") then (.checksums | type == "string" and length > 0) else true end) and (if has("digests") then (.digests | type == "boolean") else true end) + and (if has("latest_only") then (.latest_only | type == "boolean") else true end) and (has("checksums") != (has("digests") and .digests == true)) - and (.assets | type == "object" and length > 0 and (to_entries | all( - (.key | test("\\A[a-z0-9_]+\\z")) and (.value | type == "string" and length > 0) - ))) + and (.assets | valid_assets) + and (if has("sources") then + (.sources | valid_sources) + and ((.assets | keys) as $assets | (.sources | keys) as $sources | ($assets - $sources | length) == ($assets | length)) + else true end) elif has("git_tags") then (.git_tags | type == "string" and test("\\Ahttps://[^[:space:]]+\\.git\\z")) and (.tag_pattern | type == "string" and (split("{pkgver}") | length) == 2) and (.sources | valid_sources) - else + elif has("npm") then (.npm | type == "string" and test("\\A(@[a-z0-9_.-]+/)?[a-z0-9_.-]+\\z")) and ((.dist_tag // "latest") | type == "string" and test("\\A[a-z0-9_.-]+\\z")) and (.sources | valid_sources) + else + (.debian | type == "string" and test("\\Ahttps://[^[:space:]]+\\z")) + and (.package | type == "string" and test("\\A[a-z0-9][a-z0-9+.-]*\\z")) + and (.sources | valid_sources) end end ' "$metadata" >/dev/null; then - echo "invalid upstream for $(basename "$pkgdir"): configure exactly one valid github, git_tags, or npm provider" + echo "invalid upstream for $(basename "$pkgdir"): configure exactly one valid github, git_tags, npm, or debian provider" return 1 fi diff --git a/helpers/upstream-github.sh b/helpers/upstream-github.sh index 1b6e64ce..6c7e1ba4 100644 --- a/helpers/upstream-github.sh +++ b/helpers/upstream-github.sh @@ -20,8 +20,8 @@ # "v", which is stripped for pkgver. Drafts and prereleases are ignored. The # provider emits the same JSON contract as an upstream.sh hook, so # bin/sync-upstream's validation and min_release_age backstop apply -# unchanged. Git-tag and npm providers below cover projects without GitHub -# releases; a feed that fits no convention keeps a bespoke hook. +# unchanged. Git-tag, npm, and Debian Packages providers below cover projects +# without GitHub releases; a feed that fits no convention keeps a bespoke hook. # Return the single declarative provider selected by a package. An empty # result means either no provider or an invalid/ambiguous declaration; the @@ -31,7 +31,7 @@ package_upstream_provider() { metadata=$(metadata_file_for_dir "$pkgdir") jq -r ' (.upstream? | objects) as $u - | [$u | keys[] | select(. == "github" or . == "git_tags" or . == "npm")] + | [$u | keys[] | select(. == "github" or . == "git_tags" or . == "npm" or . == "debian")] | if length == 1 then .[0] else "" end ' "$metadata" } @@ -64,6 +64,11 @@ npm_fetch_metadata() { curl -fsSL "https://registry.npmjs.org/$encoded" } +debian_fetch_packages() { + local url="$1" + curl --proto '=https' --proto-redir '=https' -fsSL "$url" +} + upstream_fetch_source() { local url="$1" output="$2" curl --proto '=https' --proto-redir '=https' -fsSL -o "$output" "$url" @@ -198,6 +203,71 @@ npm_upstream_release() { printf '%s\n' "$release" } +# Discover a package version from a plain-text Debian Packages index, then +# hash the declared immutable sources. This intentionally supports only +# versions that are already valid Arch pkgver values; feeds needing Debian +# epoch/revision translation keep a package-specific hook. +debian_upstream_release() { + local package_dir="$1" metadata index_url package packages + metadata=$(metadata_file_for_dir "$package_dir") + index_url=$(jq -r '.upstream.debian // ""' "$metadata") + package=$(jq -r '.upstream.package // ""' "$metadata") + + if [[ ! "$index_url" =~ ^https://[^[:space:]]+$ || ! "$package" =~ ^[a-z0-9][a-z0-9+.-]*$ ]]; then + echo "invalid Debian Packages provider configuration" >&2 + return 1 + fi + if ! jq -e ' + .upstream.sources | type == "object" and length > 0 and (to_entries | all( + (.key | test("\\A[a-z0-9_]+\\z")) + and (.value | type == "array" and length > 0 and all(type == "string" and length > 0)) + )) + ' "$metadata" >/dev/null; then + echo "invalid Debian Packages source mapping" >&2 + return 1 + fi + if ! packages=$(debian_fetch_packages "$index_url"); then + echo "could not fetch Debian Packages index: $index_url" >&2 + return 1 + fi + packages=${packages//$'\r'/} + + local best_pkgver="" candidate + while IFS= read -r candidate; do + if [[ ! "$candidate" =~ ^[A-Za-z0-9][A-Za-z0-9._+]*$ ]]; then + echo "$package has an unusable Debian version: ${candidate:-}" >&2 + return 1 + fi + if [[ -z "$best_pkgver" || $(vercmp "$candidate" "$best_pkgver") -gt 0 ]]; then + best_pkgver="$candidate" + fi + done < <(awk -v target="$package" ' + BEGIN { RS = ""; FS = "\n" } + { + name = version = "" + for (i = 1; i <= NF; i++) { + if ($i ~ /^Package: /) name = substr($i, 10) + if ($i ~ /^Version: /) version = substr($i, 10) + } + if (name == target) print version + } + ' <<<"$packages") + + [[ -n "$best_pkgver" ]] || { + echo "no usable $package release found in $index_url" >&2 + return 1 + } + + local current_pkgver + current_pkgver=$(grep -m1 '^pkgver=' "$package_dir/PKGBUILD" | cut -d= -f2- | tr -d "\"'") + if [[ $(vercmp "$best_pkgver" "$current_pkgver") -le 0 ]]; then + echo '{}' + return 0 + fi + + upstream_hash_sources "$package_dir" "$best_pkgver" "$best_pkgver" +} + # Emits the newest qualifying release as hook-contract JSON. min_release_age # is honored during selection (newest release older than the window wins, # even when a younger one exists) and BYPASS_MIN_RELEASE_AGE=1 lifts it. @@ -206,7 +276,7 @@ npm_upstream_release() { # not silently choose from. github_upstream_release() { local package_dir="$1" min_age="${2:-0}" - local metadata repo checksums_name use_digests + local metadata repo checksums_name use_digests latest_only metadata=$(metadata_file_for_dir "$package_dir") repo=$(jq -r '(.upstream? | objects | .github) // ""' "$metadata") @@ -218,10 +288,15 @@ github_upstream_release() { # reaches this provider without running the validator first. checksums_name=$(jq -r '(.upstream? | objects | .checksums) | strings' "$metadata") use_digests=$(jq -r '(.upstream? | objects | .digests) | if . == null then "false" elif type == "boolean" then tostring else "invalid" end' "$metadata") + latest_only=$(jq -r '(.upstream? | objects | .latest_only) | if . == null then "false" elif type == "boolean" then tostring else "invalid" end' "$metadata") if [[ "$use_digests" == "invalid" ]]; then echo "upstream.digests must be true or false" >&2 return 1 fi + if [[ "$latest_only" == "invalid" ]]; then + echo "upstream.latest_only must be true or false" >&2 + return 1 + fi if [[ -n "$checksums_name" && "$use_digests" == "true" ]]; then echo "upstream sets both checksums and digests; keep exactly one" >&2 return 1 @@ -230,6 +305,27 @@ github_upstream_release() { echo "upstream needs either checksums (a manifest asset name) or digests: true" >&2 return 1 fi + if ! jq -e ' + def valid_sources: + type == "object" and length > 0 and (to_entries | all( + (.key | test("\\A[a-z0-9_]+\\z")) + and (.value | type == "array" and length > 0 and all(type == "string" and length > 0)) + )); + (.upstream.assets | type == "object" and length > 0 and (to_entries | all( + (.key | test("\\A[a-z0-9_]+\\z")) + and (.value | + (type == "string" and length > 0) + or (type == "array" and length > 0 and all(type == "string" and length > 0) and (unique | length) == length) + ) + ))) + and (if .upstream | has("sources") then + (.upstream.sources | valid_sources) + and ((.upstream.assets | keys) as $assets | (.upstream.sources | keys) as $sources | ($assets - $sources | length) == ($assets | length)) + else true end) + ' "$metadata" >/dev/null; then + echo "invalid upstream.assets or upstream.sources mapping" >&2 + return 1 + fi local arches mapfile -t arches < <(jq -r '(.upstream? | objects | .assets) // {} | keys[]' "$metadata") if [[ ${#arches[@]} -eq 0 ]]; then @@ -243,6 +339,9 @@ github_upstream_release() { echo "could not fetch the release feed for $repo" >&2 return 1 fi + if [[ "$latest_only" == "true" ]]; then + releases=$(jq '[.[] | select((.draft or .prerelease) | not)][0:1]' <<<"$releases") + fi local candidates=0 best_tag="" best_pkgver="" best_published_at="" local tag published_at pkgver published_epoch @@ -302,39 +401,50 @@ github_upstream_release() { return 1 fi - local jq_args=(--arg pkgver "$best_pkgver" --arg published_at "$best_published_at") - local jq_filter='{pkgver: $pkgver, published_at: $published_at, sha256sums: {}}' - local arch template filename checksum checksum_source + local result + result=$(jq -n --arg pkgver "$best_pkgver" --arg published_at "$best_published_at" \ + '{pkgver: $pkgver, published_at: $published_at, sha256sums: {}}') + local arch template filename checksum checksum_source sums for arch in "${arches[@]}"; do if [[ ! "$arch" =~ ^[a-z0-9_]+$ ]]; then echo "invalid architecture key in upstream.assets: '$arch'" >&2 return 1 fi - template=$(jq -r --arg arch "$arch" '.upstream.assets[$arch]' "$metadata") - filename=${template//\{pkgver\}/$best_pkgver} - filename=${filename//\{tag\}/$best_tag} - if [[ "$use_digests" == "true" ]]; then - # Only a "sha256:" digest is stripped to its hex; any other shape - # falls through empty and fails the check below. - checksum=$(jq -r --arg tag "$best_tag" --arg name "$filename" ' - first(.[] | select(.tag_name == $tag)) | (.assets // [])[] - | select(.name == $name) | (.digest // "") - | if type == "string" and test("\\Asha256:[0-9a-f]{64}\\z") then ltrimstr("sha256:") else "" end - ' <<<"$releases") - checksum_source="the release API digest" - else - # Manifest lines are " ", with the name sometimes prefixed - # "./" (sha256sum of a local path) or "*" (binary-mode marker). - checksum=$(awk -v f="$filename" '$2 == f || $2 == "./" f || $2 == "*" f { print $1; exit }' <<<"$checksums") - checksum_source="$checksums_name" - fi - if [[ ! "$checksum" =~ ^[0-9a-f]{64}$ ]]; then - echo "no valid checksum for $filename in $repo $best_tag $checksum_source" >&2 - return 1 - fi - jq_args+=(--arg "sum_$arch" "$checksum") - jq_filter+=" | .sha256sums[\"$arch\"] = [\$sum_$arch]" + sums='[]' + while IFS= read -r template; do + filename=${template//\{pkgver\}/$best_pkgver} + filename=${filename//\{tag\}/$best_tag} + if [[ "$use_digests" == "true" ]]; then + # Only a "sha256:" digest is stripped to its hex; any other shape + # falls through empty and fails the check below. + checksum=$(jq -r --arg tag "$best_tag" --arg name "$filename" ' + first(.[] | select(.tag_name == $tag)) | (.assets // [])[] + | select(.name == $name) | (.digest // "") + | if type == "string" and test("\\Asha256:[0-9a-f]{64}\\z") then ltrimstr("sha256:") else "" end + ' <<<"$releases") + checksum_source="the release API digest" + else + # Manifest lines are " ", with the name sometimes prefixed + # "./" (sha256sum of a local path) or "*" (binary-mode marker). + checksum=$(awk -v f="$filename" '$2 == f || $2 == "./" f || $2 == "*" f { print $1; exit }' <<<"$checksums") + checksum_source="$checksums_name" + fi + if [[ ! "$checksum" =~ ^[0-9a-f]{64}$ ]]; then + echo "no valid checksum for $filename in $repo $best_tag $checksum_source" >&2 + return 1 + fi + sums=$(jq -c --arg checksum "$checksum" '. + [$checksum]' <<<"$sums") + done < <(jq -r --arg arch "$arch" ' + .upstream.assets[$arch] | if type == "array" then .[] else . end + ' "$metadata") + result=$(jq -c --arg arch "$arch" --argjson sums "$sums" '.sha256sums[$arch] = $sums' <<<"$result") done - jq -n "${jq_args[@]}" "$jq_filter" + if jq -e '.upstream | has("sources")' "$metadata" >/dev/null; then + local source_release + source_release=$(upstream_hash_sources "$package_dir" "$best_pkgver" "$best_tag") || return 1 + result=$(jq -c --argjson source "$source_release" '.sha256sums += $source.sha256sums' <<<"$result") + fi + + printf '%s\n' "$result" } diff --git a/pkgbuilds/1password/.omarchy/package.json b/pkgbuilds/1password/.omarchy/package.json index b3137453..663db8e5 100644 --- a/pkgbuilds/1password/.omarchy/package.json +++ b/pkgbuilds/1password/.omarchy/package.json @@ -1,5 +1,18 @@ { - "source": "aur", + "source": "local", "release_ring": "fast", - "upstream_commit": "e323d0d1f8dea6b75bb651ce14acc73904cd0326" + "upstream": { + "debian": "https://downloads.1password.com/linux/debian/amd64/dists/stable/main/binary-amd64/Packages", + "package": "1password", + "sources": { + "x86_64": [ + "https://downloads.1password.com/linux/tar/stable/x86_64/1password-{pkgver}.x64.tar.gz", + "https://downloads.1password.com/linux/tar/stable/x86_64/1password-{pkgver}.x64.tar.gz.sig" + ], + "aarch64": [ + "https://downloads.1password.com/linux/tar/stable/aarch64/1password-{pkgver}.arm64.tar.gz", + "https://downloads.1password.com/linux/tar/stable/aarch64/1password-{pkgver}.arm64.tar.gz.sig" + ] + } + } } diff --git a/pkgbuilds/1password/PKGBUILD b/pkgbuilds/1password/PKGBUILD index 80d90d80..4e91196d 100644 --- a/pkgbuilds/1password/PKGBUILD +++ b/pkgbuilds/1password/PKGBUILD @@ -1,19 +1,33 @@ pkgname=1password -_tarver=8.12.34 -_tar="1password-${_tarver}.x64.tar.gz" -pkgver=${_tarver//-/_} -pkgrel=34 +case "$CARCH" in + x86_64) _tararch=x64 ;; + aarch64) _tararch=arm64 ;; + *) return 1 ;; +esac + +pkgver=8.12.34 +pkgrel=35 conflicts=('1password-beta' '1password-beta-bin') pkgdesc="Password manager and secure wallet" -arch=('x86_64') +arch=('x86_64' 'aarch64') url='https://1password.com' license=('LicenseRef-1Password-Proprietary') options=(!strip) install="1password.install" -source=(https://downloads.1password.com/linux/tar/stable/${CARCH}/${_tar}{,.sig}) -sha256sums=('297784aa66770b645607a7f04c9ba2c4aebed4f46d21202487f521ba572b7b13' - 'ec085bef60de748895d3c51a8208301ba2ac8fb47db99334539ba4bd1d3260d7' +source_x86_64=( + "https://downloads.1password.com/linux/tar/stable/x86_64/1password-${pkgver}.x64.tar.gz" + "https://downloads.1password.com/linux/tar/stable/x86_64/1password-${pkgver}.x64.tar.gz.sig" +) +source_aarch64=( + "https://downloads.1password.com/linux/tar/stable/aarch64/1password-${pkgver}.arm64.tar.gz" + "https://downloads.1password.com/linux/tar/stable/aarch64/1password-${pkgver}.arm64.tar.gz.sig" +) +sha256sums_x86_64=('297784aa66770b645607a7f04c9ba2c4aebed4f46d21202487f521ba572b7b13' + 'ec085bef60de748895d3c51a8208301ba2ac8fb47db99334539ba4bd1d3260d7' +) +sha256sums_aarch64=('ea5102363d6cf3442b96a7abd6743da8c1d261f56a628e1a3c183d84fa65fdcb' + 'f44db73fa44c3f68c3ab78a9cce140be9355de1dd9be4ce731c9d6597960c907' ) validpgpkeys=('3FEF9748469ADBE15DA7CA80AC2D62742012EA22') @@ -21,7 +35,7 @@ package() { depends=('hicolor-icon-theme' 'libgtk-3.so=0' 'nss' 'xdg-utils') # Go to source directory - cd "1password-${_tarver}.x64" + cd "1password-${pkgver}.${_tararch}" # Install icons resolutions=(32x32 64x64 256x256 512x512) @@ -49,7 +63,7 @@ EOF" > ./com.1password.1Password.policy # Move package contents to /opt/1Password cd "${srcdir}" install -dm0755 "${pkgdir}"/opt - mv "1password-${_tarver}.x64" "${pkgdir}/opt/1Password" + mv "1password-${pkgver}.${_tararch}" "${pkgdir}/opt/1Password" # Cleanup un-needed files rm "${pkgdir}"/opt/1Password/com.1password.1Password.policy "${pkgdir}"/opt/1Password/com.1password.1Password.policy.tpl "${pkgdir}"/opt/1Password/install_biometrics_policy.sh diff --git a/pkgbuilds/voxtype-bin/.omarchy/package.json b/pkgbuilds/voxtype-bin/.omarchy/package.json index 0e2fc7fa..778fbb52 100644 --- a/pkgbuilds/voxtype-bin/.omarchy/package.json +++ b/pkgbuilds/voxtype-bin/.omarchy/package.json @@ -1,5 +1,82 @@ { - "source": "aur", + "source": "local", "release_ring": "fast", - "upstream_commit": "6dbf4bedbba0a2f90d8e813becfa5ba289653562" + "min_release_age": "24h", + "upstream": { + "github": "peteonrails/voxtype", + "digests": true, + "latest_only": true, + "assets": { + "x86_64": [ + "voxtype-{pkgver}-linux-x86_64-avx2", + "voxtype-{pkgver}-linux-x86_64-avx2.asc", + "voxtype-{pkgver}-linux-x86_64-avx512", + "voxtype-{pkgver}-linux-x86_64-avx512.asc", + "voxtype-{pkgver}-linux-x86_64-vulkan", + "voxtype-{pkgver}-linux-x86_64-vulkan.asc", + "voxtype-{pkgver}-linux-x86_64-onnx-avx2", + "voxtype-{pkgver}-linux-x86_64-onnx-avx2.asc", + "voxtype-{pkgver}-linux-x86_64-onnx-avx512", + "voxtype-{pkgver}-linux-x86_64-onnx-avx512.asc", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-12", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-12.asc", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-12.libonnxruntime_providers_cuda.so", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-12.libonnxruntime_providers_shared.so", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-13", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-13.asc", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-13.libonnxruntime_providers_cuda.so", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-13.libonnxruntime_providers_shared.so", + "voxtype-{pkgver}-linux-x86_64-onnx-cuda-13.libonnxruntime.so.1.24.4", + "voxtype-{pkgver}-linux-x86_64-onnx-migraphx", + "voxtype-{pkgver}-linux-x86_64-onnx-migraphx.asc", + "voxtype-{pkgver}-linux-x86_64-onnx-migraphx.libonnxruntime_providers_migraphx.so", + "voxtype-{pkgver}-linux-x86_64-onnx-migraphx.libonnxruntime_providers_shared.so", + "voxtype-{pkgver}-linux-x86_64-osd", + "voxtype-{pkgver}-linux-x86_64-osd.asc", + "voxtype-{pkgver}-linux-x86_64-osd-gtk4", + "voxtype-{pkgver}-linux-x86_64-osd-gtk4.asc", + "voxtype-{pkgver}-linux-x86_64-osd-quickshell", + "voxtype-{pkgver}-linux-x86_64-osd-quickshell.asc", + "voxtype-{pkgver}-linux-x86_64-audio-bridge", + "voxtype-{pkgver}-linux-x86_64-audio-bridge.asc" + ], + "aarch64": [ + "voxtype-{pkgver}-linux-aarch64-cpu", + "voxtype-{pkgver}-linux-aarch64-cpu.asc", + "voxtype-{pkgver}-linux-aarch64-onnx", + "voxtype-{pkgver}-linux-aarch64-onnx.asc", + "voxtype-{pkgver}-linux-aarch64-osd", + "voxtype-{pkgver}-linux-aarch64-osd.asc", + "voxtype-{pkgver}-linux-aarch64-osd-gtk4", + "voxtype-{pkgver}-linux-aarch64-osd-gtk4.asc", + "voxtype-{pkgver}-linux-aarch64-osd-quickshell", + "voxtype-{pkgver}-linux-aarch64-osd-quickshell.asc", + "voxtype-{pkgver}-linux-aarch64-audio-bridge", + "voxtype-{pkgver}-linux-aarch64-audio-bridge.asc" + ] + }, + "sources": { + "any": [ + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/config/default.toml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/packaging/systemd/voxtype.service", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/packaging/completions/voxtype.bash", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/packaging/completions/voxtype.zsh", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/packaging/completions/voxtype.fish", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/LICENSE", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/README.md", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/packaging/voxtype-configure.desktop", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/packaging/scripts/voxtype-configure-launcher", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/shell.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/OsdSurface.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/EnginePicker.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/MeetingControls.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/voxtype-shared/Theme.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/voxtype-shared/StateReader.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/voxtype-shared/AudioBridge.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/voxtype-shared/StyleLoader.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/voxtype-shared/RecipeRenderer.qml", + "https://raw.githubusercontent.com/peteonrails/voxtype/{tag}/quickshell/voxtype-shared/qmldir" + ] + } + } } diff --git a/pkgbuilds/voxtype-bin/PKGBUILD b/pkgbuilds/voxtype-bin/PKGBUILD index 62ad9b9f..5333cd28 100644 --- a/pkgbuilds/voxtype-bin/PKGBUILD +++ b/pkgbuilds/voxtype-bin/PKGBUILD @@ -3,7 +3,7 @@ pkgname=voxtype-bin pkgver=1.0.1 pkgrel=1 pkgdesc="Push-to-talk voice-to-text for Linux (pre-built binaries)" -arch=('x86_64') +arch=('x86_64' 'aarch64') url="https://voxtype.io" license=('MIT') depends=( @@ -47,7 +47,7 @@ validpgpkeys=( '9CCF7915B750CAE8B095ED1AA3FC9F33FD209279' ) _github="https://github.com/peteonrails/voxtype/releases/download/v$pkgver" -source=( +source_x86_64=( # Whisper binaries "voxtype-$pkgver-avx2::$_github/voxtype-$pkgver-linux-x86_64-avx2" "voxtype-$pkgver-avx2.asc::$_github/voxtype-$pkgver-linux-x86_64-avx2.asc" @@ -97,7 +97,23 @@ source=( "voxtype-$pkgver-osd-quickshell.asc::$_github/voxtype-$pkgver-linux-x86_64-osd-quickshell.asc" "voxtype-$pkgver-audio-bridge::$_github/voxtype-$pkgver-linux-x86_64-audio-bridge" "voxtype-$pkgver-audio-bridge.asc::$_github/voxtype-$pkgver-linux-x86_64-audio-bridge.asc" - # Config and support files +) +source_aarch64=( + "voxtype-$pkgver-cpu::$_github/voxtype-$pkgver-linux-aarch64-cpu" + "voxtype-$pkgver-cpu.asc::$_github/voxtype-$pkgver-linux-aarch64-cpu.asc" + "voxtype-$pkgver-onnx::$_github/voxtype-$pkgver-linux-aarch64-onnx" + "voxtype-$pkgver-onnx.asc::$_github/voxtype-$pkgver-linux-aarch64-onnx.asc" + "voxtype-$pkgver-osd::$_github/voxtype-$pkgver-linux-aarch64-osd" + "voxtype-$pkgver-osd.asc::$_github/voxtype-$pkgver-linux-aarch64-osd.asc" + "voxtype-$pkgver-osd-gtk4::$_github/voxtype-$pkgver-linux-aarch64-osd-gtk4" + "voxtype-$pkgver-osd-gtk4.asc::$_github/voxtype-$pkgver-linux-aarch64-osd-gtk4.asc" + "voxtype-$pkgver-osd-quickshell::$_github/voxtype-$pkgver-linux-aarch64-osd-quickshell" + "voxtype-$pkgver-osd-quickshell.asc::$_github/voxtype-$pkgver-linux-aarch64-osd-quickshell.asc" + "voxtype-$pkgver-audio-bridge::$_github/voxtype-$pkgver-linux-aarch64-audio-bridge" + "voxtype-$pkgver-audio-bridge.asc::$_github/voxtype-$pkgver-linux-aarch64-audio-bridge.asc" +) +source=( + # Architecture-independent config and support files "config-$pkgver.toml::https://raw.githubusercontent.com/peteonrails/voxtype/v$pkgver/config/default.toml" "voxtype-$pkgver.service::https://raw.githubusercontent.com/peteonrails/voxtype/v$pkgver/packaging/systemd/voxtype.service" "voxtype-$pkgver.bash::https://raw.githubusercontent.com/peteonrails/voxtype/v$pkgver/packaging/completions/voxtype.bash" @@ -125,46 +141,62 @@ source=( "quickshell-voxtype-shared-RecipeRenderer-$pkgver.qml::https://raw.githubusercontent.com/peteonrails/voxtype/v$pkgver/quickshell/voxtype-shared/RecipeRenderer.qml" "quickshell-voxtype-shared-qmldir-$pkgver::https://raw.githubusercontent.com/peteonrails/voxtype/v$pkgver/quickshell/voxtype-shared/qmldir" ) -sha256sums=( +sha256sums_x86_64=( # Whisper binaries 'cb3843a894ef47aca230b30bb1c45c2ef8e0d015adf2fa754d60e55123165fd0' # voxtype-avx2 - 'SKIP' # voxtype-avx2.asc + '21357d39412619e8a3fc473153e6e2a28b219aa02007682737afedd73a08bdbe' # voxtype-avx2.asc '77d49275ae4c3a6d93671014278b0dabd69ba52e65d2ee6ab3ec1bff0af34d55' # voxtype-avx512 - 'SKIP' # voxtype-avx512.asc + 'e3421641b4b5fa5d42ee0698eb43552e177f8b095a1acea32445693404b4fd54' # voxtype-avx512.asc 'c569d038057464aa60290296794bcbd79b928ee0efd038e33062a4c015558ed8' # voxtype-vulkan - 'SKIP' # voxtype-vulkan.asc + 'a82bd4108dc70d7d2b6e25a83a6744170502f5110780d4a2e97a3e76047ea60d' # voxtype-vulkan.asc # ONNX CPU binaries '19b8716ff7bd388ffb18843fc0ee5e614faa84544d22918ecf72a7c3d6c02929' # voxtype-onnx-avx2 - 'SKIP' # voxtype-onnx-avx2.asc + '3021aa3a13555bdab0ecccfb522db8391d7e05810d218608a6372477f11cb2af' # voxtype-onnx-avx2.asc '69a6e6fc1c04a55eeb62cf1eaa5fe81873c70eabffff120ce1a4ff7ef62fd559' # voxtype-onnx-avx512 - 'SKIP' # voxtype-onnx-avx512.asc + '305d33b6f4dc8ac7a38a5f522c1af95b462355fa057b2eb39d3add59303145e1' # voxtype-onnx-avx512.asc # ONNX CUDA 12 binary + companion .so 'e7180f17add10bb441368d8495fc99bde0ba1a1978ea5f7a52d7e626779eca16' # voxtype-onnx-cuda-12 - 'SKIP' # voxtype-onnx-cuda-12.asc + '34f7242fe16867ab029af9ed4854d3930aa2ed91bc37e062962edbfc65522af5' # voxtype-onnx-cuda-12.asc 'a8584727d51ba646ac63fc991c2f36ad6cd5b8cc8b1141896e46938700b888d0' # cuda-12.libonnxruntime_providers_cuda.so '1b028afc079628d76a28d7eb09700a4baead4a27f9634ba82c35398486134114' # cuda-12.libonnxruntime_providers_shared.so # ONNX CUDA 13 binary + companion .so + dlopen-target libonnxruntime '4de2aac42b67a05c34ac0b23f771fc83968670fd77d14781cbf4483524304cd1' # voxtype-onnx-cuda-13 - 'SKIP' # voxtype-onnx-cuda-13.asc + 'adb768be0b115f38bc28ea35614ae59e1c1adfb6e11ae08a252c45d52932fab2' # voxtype-onnx-cuda-13.asc 'b6cb7744d0efd2faced5c83ead374c13e7f2630b5a249ffaf393cdb1e092c92b' # cuda-13.libonnxruntime_providers_cuda.so 'c6a12593396095f5670160e284c35d1700b7708cf3037b7042e2a5200ccae772' # cuda-13.libonnxruntime_providers_shared.so '1aacefdf0b4afa145d410b2381bbc3db3d978c485fb182c42a2b0b09f91f5310' # cuda-13.libonnxruntime.so.1.24.4 # ONNX MIGraphX binary + companion .so 'f7a4cc0deaf35110b5106f1fc1f83dded41c0b1780f9fb5aa9cccc3c62e5eb6a' # voxtype-onnx-migraphx - 'SKIP' # voxtype-onnx-migraphx.asc + '9e9c767605923c084c97659326cb0f03ad4e5db0aded4da052fa208b4de9cf45' # voxtype-onnx-migraphx.asc 'ddd67e6193ade819ee21f1706d1b03b9151f1d2d2843701e2d19d8b183631707' # migraphx.libonnxruntime_providers_migraphx.so '17f7cf47ad0d7b5ac895ae588fd62c7f85a13842588161b6a24c7d480f062be4' # migraphx.libonnxruntime_providers_shared.so # OSD launcher + GTK4 frontend '7250027b1672507a6d584f795731c87e1d3b5c1de891438bd55e34b136a2d5cc' # voxtype-osd - 'SKIP' # voxtype-osd.asc + '1a944200fbac1e773c70d036075745b0e868885443e29c30797f262d44928cc1' # voxtype-osd.asc '74fb0f6ad87feb0c1c9e06a8b28a7f7ecee101caef4248f77dcf613b5271238e' # voxtype-osd-gtk4 - 'SKIP' # voxtype-osd-gtk4.asc + '60224685717fea0582d570160282e9e215cd4713b3bdb695edc7bae8b6860cac' # voxtype-osd-gtk4.asc # Quickshell OSD launcher + audio-bridge sidecar (new in v0.7.5) 'b809c5140e844a6add801d7e592775cd89af8cce73fa399b6a3aec15dfd09533' # voxtype-osd-quickshell - 'SKIP' # voxtype-osd-quickshell.asc + '39412691ab1f8ffe4fa6bf1eb9763c29f94b8892d1ba59fd49dc65dd0d80297a' # voxtype-osd-quickshell.asc '45776290e364194d83a8b89445166406c278e890507bf07ec52a5f0e8fa57720' # voxtype-audio-bridge - 'SKIP' # voxtype-audio-bridge.asc - # Config and support files + '5be1174a78d70b78fd8d923c88e3406962443b39a1c452eb985b1e2484ef5668' # voxtype-audio-bridge.asc +) +sha256sums_aarch64=( + 'b5e31a85aaa952d1a78c12b8a16ba5cbdcd92eb31adc7d1a908f3c9d06edd4f1' # voxtype-cpu + '3cd2f3fafca40e394a42b90dac031c67160256898a7f4a52893585b99f8f74bb' # voxtype-cpu.asc + 'c3771f3e568629178201990976520f88da6d7599ec2d9e404a137570d6c1e108' # voxtype-onnx + 'cd58773349eac0108cdad0efcc78d13f5d7c21623117381afa99b912c397b94a' # voxtype-onnx.asc + 'ea910d4fd1fe331d38dbed1c3a639cb7e0c04542919192ff6f74be2139afe3c6' # voxtype-osd + 'e079ebdd567e318502b710af95e4987fe13623d65673e21877afe88fe18bda55' # voxtype-osd.asc + '0d2148e0cd32bac538692470edc06aa9a2f5c6a891aaa373f59fbe78c247fae3' # voxtype-osd-gtk4 + '0ce841f2caa9a1a7e8294a521bef0bab8823dddacd36fff66012b1127e0c1957' # voxtype-osd-gtk4.asc + '097bd518d5e2eac2c3cbad714b65dd8058c818dcb4d900b9a16e442af7d65b8a' # voxtype-osd-quickshell + 'f48b8071f78fde0b2d20072e875a8b8e0d8fab4caf6c8ec91cd8e2aa0b031063' # voxtype-osd-quickshell.asc + '35170ad89fea2874fce0f08758ccc2164892ed643aacae632bcfbc6f10433976' # voxtype-audio-bridge + '787965900647ee9b04c8b65123d04b63e38636bfc671fa3b53360823f886b42c' # voxtype-audio-bridge.asc +) +sha256sums=( + # Architecture-independent config and support files 'f4b2bccd56b31a6a50e1c0a8b6b72383dc1e636f9ccb8cb070442d58b7314579' # config/default.toml '531c3658e229619e56bb01659fb81f401767b85e1d6e2acd1ac67ee3414a168c' # voxtype.service '65c95805d9b03ccc2fadb9d63a03ab79974b00091df8457ee8ef290ec6bd5b12' # voxtype.bash @@ -189,16 +221,20 @@ sha256sums=( ) package() { - # Install Whisper CPU binaries to /usr/lib/voxtype/ - install -Dm755 "$srcdir/voxtype-$pkgver-avx2" "$pkgdir/usr/lib/voxtype/voxtype-avx2" - install -Dm755 "$srcdir/voxtype-$pkgver-avx512" "$pkgdir/usr/lib/voxtype/voxtype-avx512" + if [[ "$CARCH" == aarch64 ]]; then + install -Dm755 "$srcdir/voxtype-$pkgver-cpu" "$pkgdir/usr/lib/voxtype/voxtype-cpu" + install -Dm755 "$srcdir/voxtype-$pkgver-onnx" "$pkgdir/usr/lib/voxtype/voxtype-onnx" + else + # Install Whisper CPU binaries to /usr/lib/voxtype/ + install -Dm755 "$srcdir/voxtype-$pkgver-avx2" "$pkgdir/usr/lib/voxtype/voxtype-avx2" + install -Dm755 "$srcdir/voxtype-$pkgver-avx512" "$pkgdir/usr/lib/voxtype/voxtype-avx512" - # Install Whisper Vulkan GPU binary - install -Dm755 "$srcdir/voxtype-$pkgver-vulkan" "$pkgdir/usr/lib/voxtype/voxtype-vulkan" + # Install Whisper Vulkan GPU binary + install -Dm755 "$srcdir/voxtype-$pkgver-vulkan" "$pkgdir/usr/lib/voxtype/voxtype-vulkan" - # Install ONNX CPU binaries (no GPU EP, no companion .so files) - install -Dm755 "$srcdir/voxtype-$pkgver-onnx-avx2" "$pkgdir/usr/lib/voxtype/voxtype-onnx-avx2" - install -Dm755 "$srcdir/voxtype-$pkgver-onnx-avx512" "$pkgdir/usr/lib/voxtype/voxtype-onnx-avx512" + # Install ONNX CPU binaries (no GPU EP, no companion .so files) + install -Dm755 "$srcdir/voxtype-$pkgver-onnx-avx2" "$pkgdir/usr/lib/voxtype/voxtype-onnx-avx2" + install -Dm755 "$srcdir/voxtype-$pkgver-onnx-avx512" "$pkgdir/usr/lib/voxtype/voxtype-onnx-avx512" # GPU-using ONNX binaries each live in their own subdirectory alongside # the EP companion shared libs they dlopen at runtime. ort 2.0.0-rc.12's @@ -248,7 +284,8 @@ package() { # voxtype-onnx-rocm name. The AMD GPU EP changed from ROCm to MIGraphX # in v0.7.0; ship one release with both names to soften the transition. # Drop in v0.8.0. - ln -sf "voxtype-onnx-migraphx" "$pkgdir/usr/lib/voxtype/voxtype-onnx-rocm" + ln -sf "voxtype-onnx-migraphx" "$pkgdir/usr/lib/voxtype/voxtype-onnx-rocm" + fi # /usr/bin/voxtype symlink and the unversioned voxtype-onnx-cuda symlink # are created by the .install script's post_install/post_upgrade hooks