Add canonical Obsidian desktop package for aarch64
This commit is contained in:
8 files changed
+214
No files matched your search
@@ -50,6 +50,7 @@ jobs:
|
||||
pacman -Syu --noconfirm git jq python libarchive
|
||||
python tests/oma-service-removal.py
|
||||
python tests/upstream-watch.py
|
||||
python tests/obsidian-upstream.py
|
||||
./bin/sync-upstream self-test
|
||||
./bin/sync-rebuilds --self-test
|
||||
./bin/omarchy-pkgs self-test
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"source": "local"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/python3
|
||||
"""Report the newest stable ARM desktop installer, ignoring mobile-only tags."""
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
|
||||
def select(releases):
|
||||
if not isinstance(releases, list):
|
||||
raise ValueError('Expected a GitHub release list')
|
||||
candidates = []
|
||||
for release in releases:
|
||||
if release.get('draft') or release.get('prerelease'):
|
||||
continue
|
||||
match = re.fullmatch(r'v([0-9]+(?:\.[0-9]+)*)', release.get('tag_name', ''))
|
||||
if not match:
|
||||
continue
|
||||
version = match[1]
|
||||
assets = [a for a in release.get('assets', [])
|
||||
if a.get('name') == f'obsidian-{version}-arm64.tar.gz']
|
||||
if not assets:
|
||||
continue
|
||||
if len(assets) != 1:
|
||||
raise ValueError('Duplicate desktop installer')
|
||||
candidates.append((tuple(map(int, version.split('.'))), version, release, assets[0]))
|
||||
if not candidates:
|
||||
raise ValueError('No stable ARM desktop installer found')
|
||||
_, version, release, asset = max(candidates, key=lambda row: row[0])
|
||||
digest = asset.get('digest') or ''
|
||||
if not re.fullmatch(r'sha256:[0-9a-f]{64}', digest):
|
||||
raise ValueError('Selected desktop installer lacks its SHA256 digest')
|
||||
expected = f'https://github.com/obsidianmd/obsidian-releases/releases/download/v{version}/obsidian-{version}-arm64.tar.gz'
|
||||
if asset.get('browser_download_url') != expected:
|
||||
raise ValueError('Unexpected desktop installer URL')
|
||||
return {'pkgver': version, 'published_at': release['published_at'],
|
||||
'sha256sums': {'aarch64': [digest[7:]]}}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
response = subprocess.check_output([
|
||||
'curl', '--proto', '=https', '--proto-redir', '=https', '-fsSL',
|
||||
'--retry', '3', '--max-time', '60',
|
||||
'https://api.github.com/repos/obsidianmd/obsidian-releases/releases?per_page=100'
|
||||
], text=True)
|
||||
print(json.dumps(select(json.loads(response))))
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
python3 "$(dirname "$0")/upstream.py"
|
||||
@@ -0,0 +1,94 @@
|
||||
# Maintainer: Shun Li <riverscn@gmail.com>
|
||||
# Extracted from omacom/omarchy-pkgs PR #240, revision dcef132b2df11bb762e233ea8c6af3110f079b67.
|
||||
|
||||
pkgname=obsidian
|
||||
pkgver=1.13.7
|
||||
pkgrel=2
|
||||
pkgdesc='Knowledge base on top of a local folder of plain-text Markdown files'
|
||||
arch=('aarch64')
|
||||
url='https://obsidian.md/'
|
||||
license=('custom')
|
||||
depends=(
|
||||
'alsa-lib'
|
||||
'at-spi2-core'
|
||||
'cairo'
|
||||
'dbus'
|
||||
'expat'
|
||||
'fontconfig'
|
||||
'gcc-libs'
|
||||
'glib2'
|
||||
'glibc'
|
||||
'gtk3'
|
||||
'hicolor-icon-theme'
|
||||
'libcups'
|
||||
'libnotify'
|
||||
'libsecret'
|
||||
'libx11'
|
||||
'libxcb'
|
||||
'libxcomposite'
|
||||
'libxdamage'
|
||||
'libxext'
|
||||
'libxfixes'
|
||||
'libxkbcommon'
|
||||
'libxrandr'
|
||||
'mesa'
|
||||
'nspr'
|
||||
'nss'
|
||||
'pango'
|
||||
'systemd-libs'
|
||||
'xdg-utils'
|
||||
)
|
||||
provides=('obsidian')
|
||||
conflicts=('obsidian-appimage' 'obsidian-bin')
|
||||
options=('!debug' '!strip')
|
||||
source=('obsidian.desktop')
|
||||
source_aarch64=(
|
||||
"obsidian-${pkgver}-arm64.tar.gz::https://github.com/obsidianmd/obsidian-releases/releases/download/v${pkgver}/obsidian-${pkgver}-arm64.tar.gz"
|
||||
)
|
||||
sha256sums=('42ecb332c900a01b2a6db0a70b4cc8c0553e863aee72894b23ed20a6289b131c')
|
||||
sha256sums_aarch64=('98aac34d1f132a35cf506fc3fa196d595dcdeefdebd44b0cc5faaa7a1a210de2')
|
||||
|
||||
package() {
|
||||
local source_dir="$srcdir/obsidian-${pkgver}-arm64"
|
||||
local install_dir="$pkgdir/opt/obsidian"
|
||||
|
||||
install -d "$install_dir"
|
||||
cp -a --no-preserve=ownership "$source_dir/." "$install_dir/"
|
||||
|
||||
# The official ARM64 archive currently carries two x86_64-only addons.
|
||||
# Remove only an unusable x86_64 payload; retain it automatically if the
|
||||
# vendor starts shipping an AArch64 build in a later release.
|
||||
local addon machine
|
||||
for addon in \
|
||||
resources/app.asar.unpacked/node_modules/btime/binding.node \
|
||||
resources/app.asar.unpacked/node_modules/get-fonts/binding.node; do
|
||||
[[ -f "$install_dir/$addon" ]] || continue
|
||||
machine=$(readelf -h "$install_dir/$addon" |
|
||||
sed -n 's/^[[:space:]]*Machine:[[:space:]]*//p')
|
||||
case "$machine" in
|
||||
AArch64) ;;
|
||||
'Advanced Micro Devices X86-64') rm -f "$install_dir/$addon" ;;
|
||||
*) error "Unexpected Obsidian addon architecture: $addon ($machine)"; return 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
find "$install_dir" -type d -exec chmod 755 {} +
|
||||
find "$install_dir" -type f -exec chmod 644 {} +
|
||||
chmod 755 \
|
||||
"$install_dir/chrome_crashpad_handler" \
|
||||
"$install_dir/obsidian" \
|
||||
"$install_dir/obsidian-cli"
|
||||
chmod 4755 "$install_dir/chrome-sandbox"
|
||||
|
||||
install -d "$pkgdir/usr/bin"
|
||||
ln -s /opt/obsidian/obsidian "$pkgdir/usr/bin/obsidian"
|
||||
ln -s /opt/obsidian/obsidian-cli "$pkgdir/usr/bin/obsidian-cli"
|
||||
install -Dm644 "$srcdir/obsidian.desktop" \
|
||||
"$pkgdir/usr/share/applications/obsidian.desktop"
|
||||
install -Dm644 "$install_dir/resources/icon.png" \
|
||||
"$pkgdir/usr/share/icons/hicolor/512x512/apps/obsidian.png"
|
||||
install -Dm644 "$install_dir/LICENSE.electron.txt" \
|
||||
"$pkgdir/usr/share/licenses/$pkgname/LICENSE.electron.txt"
|
||||
install -Dm644 "$install_dir/LICENSES.chromium.html" \
|
||||
"$pkgdir/usr/share/licenses/$pkgname/LICENSES.chromium.html"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# Obsidian on ARM
|
||||
|
||||
This is the canonical `obsidian` package, extracted from omacom/omarchy-pkgs #240 at `dcef132b2df11bb762e233ea8c6af3110f079b67`. It repackages the official ARM64 desktop tarball and preserves the original contributor attribution and Electron/Chromium license files.
|
||||
|
||||
The package owns the installed application bundle and Electron runtime. Obsidian's user-controlled in-app updater may separately update application code; no updater-disabling patch is applied. See https://obsidian.md/help/updates.
|
||||
|
||||
The package-local upstream hook selects stable desktop releases containing the exact ARM64 tarball, ignoring mobile-only tags. Missing SHA256 metadata on the selected desktop release fails rather than silently selecting an older installer. Run `python tests/obsidian-upstream.py` for offline tests. Upstream's scheduled sync opens or updates its normal review PR; maintainers need GitHub PR notifications enabled and should monitor failed sync runs too.
|
||||
|
||||
This package conflicts with `obsidian-appimage` and `obsidian-bin`. It does not automatically remove them or migrate users. Adoption in Omarchy Mac requires a separate change to the existing ARM preinstall/removal mappings. Do not modify vaults or user configuration as part of the package transaction.
|
||||
|
||||
Before this draft is ready, validate clean ARM installation, desktop/CLI paths, native payload architecture and opening/editing a disposable vault in a disposable GUI session. Existing AppImage operation does not validate this tarball package. The two named vendor x86-only addons are removed; any newly introduced foreign executable requires review.
|
||||
@@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Name=Obsidian
|
||||
Comment=Knowledge base on top of a local folder of Markdown files
|
||||
Exec=obsidian %U
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=obsidian
|
||||
StartupWMClass=obsidian
|
||||
MimeType=x-scheme-handler/obsidian;
|
||||
Categories=Office;
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
|
||||
path = Path(__file__).resolve().parents[1] / 'pkgbuilds/obsidian/.omarchy/upstream.py'
|
||||
spec = importlib.util.spec_from_file_location('obsidian_upstream', path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
|
||||
def release(version, **extra):
|
||||
return dict(tag_name='v' + version, draft=False, prerelease=False,
|
||||
published_at='2026-09-23T00:00:00Z', assets=[{
|
||||
'name': f'obsidian-{version}-arm64.tar.gz',
|
||||
'digest': 'sha256:' + 'a' * 64,
|
||||
'browser_download_url': f'https://github.com/obsidianmd/obsidian-releases/releases/download/v{version}/obsidian-{version}-arm64.tar.gz'
|
||||
}], **extra)
|
||||
|
||||
|
||||
class DesktopReleaseTests(unittest.TestCase):
|
||||
def test_mobile_only_and_preview_ignored(self):
|
||||
mobile = release('2.0.0'); mobile['assets'] = [{'name': 'Obsidian.apk'}]
|
||||
preview = release('3.0.0'); preview['prerelease'] = True
|
||||
draft = release('4.0.0'); draft['draft'] = True
|
||||
self.assertEqual(module.select([mobile, preview, draft, release('1.13.7')])['pkgver'], '1.13.7')
|
||||
|
||||
def test_numeric_version_order(self):
|
||||
self.assertEqual(module.select([release('1.9.0'), release('1.13.7')])['pkgver'], '1.13.7')
|
||||
|
||||
def test_bad_newest_digest_fails_without_falling_back(self):
|
||||
newest = release('2.0.0'); newest['assets'][0]['digest'] = None
|
||||
with self.assertRaises(ValueError):
|
||||
module.select([release('1.13.7'), newest])
|
||||
|
||||
def test_changed_url_rejected(self):
|
||||
row = release('1.13.7'); row['assets'][0]['browser_download_url'] = 'https://example.org/foreign'
|
||||
with self.assertRaises(ValueError): module.select([row])
|
||||
|
||||
def test_missing_or_duplicate_installer_rejected(self):
|
||||
with self.assertRaises(ValueError): module.select([])
|
||||
row = release('1.13.7'); row['assets'] *= 2
|
||||
with self.assertRaises(ValueError): module.select([row])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user