Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
24bf49e
Merge pull request #2 from lyj404/main
jeff141 Jun 5, 2026
fe9e749
feat:优化私钥登录
jeff141 Jun 5, 2026
d6e75c3
feat:版本号
jeff141 Jun 5, 2026
38a7786
feat: 安全修复(#12/#10/#8) + 完整 i18n(#9) + Linux 桌面集成
jeff141 Jun 5, 2026
0136913
fix(i18n): 英文下 "New session" 前的全角+显示为豆腐块
jeff141 Jun 5, 2026
40e17f5
feat(#1): 从 ~/.ssh/config 导入主机为会话
jeff141 Jun 5, 2026
c3ba3a9
refactor(#1): 把"导入 ~/.ssh/config"从新建会话旁移到设置菜单
jeff141 Jun 5, 2026
3688f1c
ci: GitHub Actions 三平台构建 + 发布工作流
jeff141 Jun 5, 2026
dc8efdf
Revert "ci: GitHub Actions 三平台构建 + 发布工作流"
jeff141 Jun 5, 2026
c77f459
fix(linux): install-linux.sh 无参数即可用 + README 补充下载安装
jeff141 Jun 5, 2026
a032459
fix(ci): workflow 移回 .github/workflows/(之前误放在 .github/ 根目录)
jeff141 Jun 5, 2026
1c6f5c9
fix(#5): 提高次要/弱化文字对比度(对话框等部分文字看不清)
jeff141 Jun 5, 2026
fc1d989
feat(#7): SSH/SFTP 代理支持(SOCKS5 / HTTP CONNECT)
jeff141 Jun 5, 2026
60bf6e7
fix: #16 上传流水线提速 + #18 上拉面板清空输出 + #15 日志泄露按键
jeff141 Jun 6, 2026
30630ae
fix: 内存/交换显示文字被截断
Jun 6, 2026
dcdcda5
fix(#15): redact keystroke text in send_key & KEY_DIAG logs
jeff141 Jun 6, 2026
906ee6a
feat: serial port (#14) and telnet (#17) session types
jeff141 Jun 6, 2026
2431368
fix(#18): only scroll off rows needed to keep cursor visible on shrink
jeff141 Jun 6, 2026
0b99deb
fix(#18): store drag-selection in absolute scrollback coordinates
jeff141 Jun 6, 2026
4ca2cbb
feat(#28): confirm before deleting a remote SFTP file
jeff141 Jun 6, 2026
27b0a66
fix(#26): sanitize remote file names before saving SFTP downloads
jeff141 Jun 6, 2026
52319e6
fix(#27): harden remote resource monitor against a hostile server
jeff141 Jun 7, 2026
751a65a
ci: add AppImage build for Linux x86_64
jeff141 Jun 7, 2026
cec5233
ci: fix AppImage build (remove redundant --plugin flag, add continue-…
jeff141 Jun 7, 2026
38a6eda
feat(linux): embed PNG icon in binary for dock/taskbar display
jeff141 Jun 7, 2026
80b79bd
fix(linux): use winit set_window_icon instead of nonexistent Slint API
jeff141 Jun 7, 2026
d86af98
feat: encrypt passwords at rest with ChaCha20-Poly1305
jeff141 Jun 7, 2026
8332fe3
Merge branch 'jeff141:main' into main
lyj404 Jun 7, 2026
4a38b7e
feat: add light/dark theme with adaptive TUI color rendering
jeff141 Jun 7, 2026
6aaf80e
feat:版本号
jeff141 Jun 7, 2026
bf6003b
fix(macos): 将 macOS 构建打包为 .app bundle 并附带图标
jeff141 Jun 7, 2026
8e763b9
fix(macos): 对 .app bundle 进行 ad-hoc 签名,修复"已损坏"无法打开
jeff141 Jun 7, 2026
f7d767d
Merge pull request #22 from lyj404/main
jeff141 Jun 7, 2026
0c3ee26
security: harden proxy credentials (#32) and ssh_config import (#33)
jeff141 Jun 7, 2026
ec98192
docs: add CONTRIBUTING.md (no external PRs, issues welcome)
jeff141 Jun 7, 2026
a42fc75
feat: export / import connections to a portable file (#46)
jeff141 Jun 8, 2026
6935501
fix(terminal): don't forward bare modifier keys to the PTY (#43)
jeff141 Jun 8, 2026
5634a88
fix(terminal): normalise pasted line endings to CR (multi-line paste)
jeff141 Jun 8, 2026
332dae1
feat(proxy): pick SOCKS5 or HTTP proxy type in the session dialog
jeff141 Jun 8, 2026
acdba17
fix(ui): session dialog height follows content (no layout stretch)
jeff141 Jun 8, 2026
cd1079f
fix(clipboard): native Wayland copy/paste + persist selection (#47)
jeff141 Jun 8, 2026
a986313
chore(release): 0.2.8
jeff141 Jun 8, 2026
52415c3
feat(terminal): hide the injected OSC 7 shell-integration command
jeff141 Jun 9, 2026
3c16115
fix(ui): rename underscore-prefixed Slint props; read version from Cargo
jeff141 Jun 9, 2026
5cf348d
fix(ui): parenthesize if-conditions in Slint callback bodies
jeff141 Jun 9, 2026
9b5f825
fix(terminal): drag-select no longer auto-scrolls; minimizable SFTP p…
jeff141 Jun 9, 2026
dbe25e0
feat(sftp): recursive folder download (#50)
jeff141 Jun 9, 2026
7e6044b
feat(sftp): recursive folder upload (#50)
jeff141 Jun 9, 2026
36b8ee2
fix(sftp): delete non-empty directories recursively (#50 follow-up)
jeff141 Jun 9, 2026
e021b6b
feat: duplicate a session from the context menu (#41.3)
jeff141 Jun 9, 2026
27d27ee
feat: organize sessions into folders/groups (#41.3)
jeff141 Jun 9, 2026
c014f37
fix(ui): left-align group headers; ungrouped sessions fall under "def…
jeff141 Jun 9, 2026
16178bd
feat: move a session to another group via right-click (#41.3)
jeff141 Jun 10, 2026
27c400a
feat: collapse / expand session groups (#41.3)
jeff141 Jun 10, 2026
402cb89
feat(welcome): translate Duplicate; right-click a group header for "N…
jeff141 Jun 10, 2026
4b06253
fix(welcome): left-align right-click context menu items
jeff141 Jun 10, 2026
6b2d460
feat(font): make the terminal font family and size configurable (mech…
jeff141 Jun 10, 2026
a9d74b6
feat(interface): Interface settings dialog to pick terminal font & size
jeff141 Jun 10, 2026
d7b2241
feat(ui): collapsible left sidebar
jeff141 Jun 10, 2026
b3e80d2
chore(release): 0.3.0
jeff141 Jun 10, 2026
51bcf18
ci: build macos-x86_64 by cross-compiling on Apple Silicon runners
jeff141 Jun 10, 2026
1e45121
chore(release): 0.3.1 — restrict sessions.json perms (#34)
jeff141 Jun 10, 2026
21bec0d
fix: clear two build warnings
jeff141 Jun 10, 2026
4b3236f
fix: disk tooltip clears on leave; no extra prompt line on connect
jeff141 Jun 10, 2026
14871a4
feat: explicit session groups — create / rename / delete, empty folde…
jeff141 Jun 10, 2026
09e8b3d
feat(welcome): reorder session context menu — actions above, groups b…
jeff141 Jun 10, 2026
f2766d7
feat(interface): draggable + truly-modal settings dialog, narrower co…
jeff141 Jun 10, 2026
8431f91
fix(terminal): wide (CJK) chars no longer misalign the cursor (#60)
jeff141 Jun 10, 2026
5d727b0
fix(ui): click outside to close the download & settings popups; repai…
jeff141 Jun 10, 2026
e13571e
ci: best-effort MSI installer with a "choose install location" wizard
jeff141 Jun 10, 2026
bd30de6
chore(release): 0.3.2
jeff141 Jun 10, 2026
2711ba2
fix(sftp): cd follows correctly after manual navigation; no more stuc…
jeff141 Jun 10, 2026
5acda76
feat(sftp): editable path bar with copy & paste-to-jump (#54)
jeff141 Jun 11, 2026
f5ebfa9
fix(sftp): path bar renders Chinese instead of tofu (#54)
jeff141 Jun 11, 2026
8fee746
feat(update): in-app new-version notification (#48)
jeff141 Jun 11, 2026
a9f23a9
chore(release): 0.3.3
jeff141 Jun 11, 2026
ed9ba8a
feat(sftp): built-in text viewer/editor + file-list selection highlig…
jeff141 Jun 11, 2026
9f9f6a3
fix(terminal): auto-cancel unsupported sz/rz (ZMODEM) so the session …
jeff141 Jun 11, 2026
670fb6b
feat(terminal): real ZMODEM receive — sz downloads straight to the lo…
jeff141 Jun 11, 2026
d58c93d
fix(zmodem): keep leading dots in filenames; tolerate a silent ZFIN (…
jeff141 Jun 11, 2026
93237dc
fix(zmodem): don't block ~1 min draining the trailing "OO" after ZFIN…
jeff141 Jun 11, 2026
68c06b6
fix(zmodem): always send our ZFIN on close so `sz` exits immediately …
jeff141 Jun 11, 2026
2b1dd83
fix(zmodem): finish immediately on ZEOF so the shell prompt isn't swa…
jeff141 Jun 11, 2026
4082b8c
fix(zmodem): complete the close handshake inside receive; return the …
jeff141 Jun 11, 2026
cac61ab
fix(zmodem): send our ZFIN proactively so sz exits at once (was hangi…
jeff141 Jun 11, 2026
087b730
feat(terminal): press Enter on a disconnected tab to reconnect in pla…
jeff141 Jun 11, 2026
6093152
feat(sftp): context-menu rename / permissions / copy path / refresh /…
jeff141 Jun 11, 2026
d05fdb0
fix(editor): scrollbar, wheel containment, and title-bar padding (#70)
jeff141 Jun 11, 2026
fa8af7f
fix(editor): reject control-character files; draggable + resizable ca…
jeff141 Jun 11, 2026
9a6465c
fix(editor): print the open-rejection reason into the terminal (#70)
jeff141 Jun 11, 2026
5be0e03
feat(sftp): Interface setting "SFTP follows terminal cd" (persisted, …
jeff141 Jun 11, 2026
dcd0ea8
fix(ui): SFTP gets its own page in the Interface dialog
jeff141 Jun 11, 2026
7f4b136
fix(sftp): manual navigation no longer makes cd-follow go stale
jeff141 Jun 11, 2026
a531c3d
style(ui): enlarge the Interface dialog by 15%
jeff141 Jun 11, 2026
ba27554
摆烂会,不想写更新日志
jeff141 Jun 11, 2026
8cdb4d7
feat(sftp): right-click anywhere in the file list; visual chmod dialo…
jeff141 Jun 12, 2026
e5d6915
ci: Linux ARM64 release build (#82) + AUR packaging (#61)
jeff141 Jun 12, 2026
77baa75
fix(ssh): don't error under fish; guard the OSC 7 prompt injection (#71)
jeff141 Jun 12, 2026
c5db6a4
feat(sftp): "Open/Edit externally" menu items + editor line numbers (…
jeff141 Jun 12, 2026
66b3d9b
feat(sftp): upload-button folder support; default download dir to ~/D…
jeff141 Jun 12, 2026
6505311
chore(release): 0.3.7
jeff141 Jun 12, 2026
3f561d8
feat(download): "always ask where to save" option in Settings → Inter…
jeff141 Jun 12, 2026
a38d1b1
feat(window): confirm before closing when there are active sessions (…
jeff141 Jun 12, 2026
b8c7ec5
fix(ui): settings checkboxes stay in sync after reopening the dialog …
jeff141 Jun 12, 2026
2d2a7a1
feat(sftp): open the transfers popup automatically when a download st…
jeff141 Jun 12, 2026
ab8e267
feat(log): capped error.log file + log session disconnects (for #86 d…
jeff141 Jun 12, 2026
4cccd79
## meatshell v0.3.8
jeff141 Jun 12, 2026
d94e4bf
feat(ssh): support encrypted private keys via passphrase (#90)
jeff141 Jun 13, 2026
9fdfe0f
feat(monitor): remote process monitor (#23)
jeff141 Jun 13, 2026
5a0132b
fix(ui): CJK-capable font on all editable inputs (#54)
jeff141 Jun 13, 2026
368f3c3
fix(terminal): render CJK spans with the CJK-capable font (#54)
jeff141 Jun 13, 2026
7b24d55
fix(sftp): make cd-follow work under zsh, not just bash (#91)
jeff141 Jun 13, 2026
b26ef6a
feat(terminal): quick commands, command box & history (#55)
jeff141 Jun 13, 2026
ceb1325
fix(terminal): center command-bar button labels (#55)
jeff141 Jun 13, 2026
055436b
feat(ssh): port forwarding / tunnels — local, remote, dynamic (#56)
jeff141 Jun 13, 2026
02e374b
fix(ui): global CJK font + compact, scrollable session dialog (#56)
jeff141 Jun 13, 2026
fd53717
chore(release): v0.4.0
jeff141 Jun 13, 2026
e4a1a79
feat(terminal): run / copy / delete actions on command history (#96)
jeff141 Jun 14, 2026
c19673f
feat(ui): default-collapse settings for the resource & SFTP sidebars …
jeff141 Jun 14, 2026
a6847c9
chore(release): v0.4.1
jeff141 Jun 14, 2026
11024b1
fix(terminal): grid-align wide CJK glyphs (no overlap / drift)
jeff141 Jun 14, 2026
4a1f22e
chore(release): v0.4.3
jeff141 Jun 14, 2026
0c7ddab
fix(ui): sync Slint std-widget palette with the app theme (light mode)
jeff141 Jun 14, 2026
c812908
fix(ui): show collapse chevron on empty session groups too
jeff141 Jun 14, 2026
4b0e2ce
feat(ui): top-bar tooltips + session-sync (broadcast input) toggle
jeff141 Jun 14, 2026
6008047
feat(sftp): mirror uploads to all sessions during session sync
jeff141 Jun 14, 2026
0e34ea2
chore(release): v0.4.4
jeff141 Jun 14, 2026
88ce3e7
fix(sftp): sync-upload to each session's own current dir
jeff141 Jun 14, 2026
75ebb55
chore(release): v0.4.5 — sync-upload per-session dir + diagnostics
jeff141 Jun 14, 2026
ec134a8
fix(sftp): session-sync upload for drag-and-drop; v0.4.6
jeff141 Jun 14, 2026
d1d261f
fix(forward): bracket IPv6 bind addresses (#109)
jeff141 Jun 16, 2026
7bb62b7
feat(zmodem): receive multiple files in one sz session (#109)
jeff141 Jun 16, 2026
a7c4bd1
feat(ssh): host-key verification with first-connect confirmation (#10…
jeff141 Jun 16, 2026
05ae912
feat(history): de-duplicate command history, most-recent last (#113)
jeff141 Jun 16, 2026
00dde59
feat(history): record terminal-typed commands via shell hook (#113)
jeff141 Jun 16, 2026
f017bf3
fix(sftp): graceful handling when a directory listing is denied (#112)
jeff141 Jun 16, 2026
09e358e
feat(session): require host, smarter naming, prompt for missing creds…
jeff141 Jun 16, 2026
661819d
fix(ssh): reliably hide the injected prompt-setup line (#98)
jeff141 Jun 16, 2026
482be70
chore(release): v0.4.7
jeff141 Jun 16, 2026
ab5cd2b
refactor(sidebar): reimplement memory-size formatting in our own style
jeff141 Jun 16, 2026
eef0fcc
refactor(ssh,sftp): re-author the publickey hash-algorithm selection
jeff141 Jun 16, 2026
10bf6ec
fix(font): embed the terminal mono font under a unique family name (#…
jeff141 Jun 17, 2026
1b680d3
feat(ui): immersive frameless title bar (#119)
jeff141 Jun 17, 2026
fde5bd3
fix(ui): address title-bar feedback — frameless, alignment, layout (#…
jeff141 Jun 17, 2026
300ff9d
fix(terminal): smooth scrollback across the live/scrolled boundary (#…
jeff141 Jun 17, 2026
0f0504c
fix(ssh): hide the injected setup line even when it wraps (#98)
jeff141 Jun 17, 2026
486f41c
fix(terminal): fast drag-selection no longer stolen by the Flickable …
jeff141 Jun 17, 2026
d946e97
fix(ui): keep the Interface dialog's close button on-screen (#119)
jeff141 Jun 18, 2026
d4f7280
chore(release): v0.4.8
jeff141 Jun 18, 2026
459f84b
feat(history): searchable command-history dropdown (#101)
jeff141 Jun 18, 2026
4f15902
fix(tabs): reserve space for toolbar icons + scroll overflowing tabs …
jeff141 Jun 18, 2026
4ed3b61
fix(ssh): preserve the MOTD/banner when hiding the injected setup lin…
jeff141 Jun 18, 2026
1b3fcad
feat(tabs): scroll arrows when tabs overflow (#122)
jeff141 Jun 18, 2026
1c685e4
feat(input): readline keys in the command box + a shortcuts reference…
jeff141 Jun 19, 2026
ccd1346
feat(terminal): slim scrollbar for the output area (#103)
jeff141 Jun 19, 2026
0b18428
## meatshell v0.4.9
jeff141 Jun 19, 2026
e629be5
fix(welcome): 连接过多时会话列表可滚动 / scroll the session list when it overflow…
jeff141 Jun 19, 2026
dd889e3
fix(sftp): 传输时仍可切换目录 / allow switching directories during transfers
jeff141 Jun 19, 2026
17a6d42
feat(forward): 端口转发规则可命名 / name port-forward rules (#100)
jeff141 Jun 19, 2026
7da4d2c
feat(ui): 界面整体缩放设置 / global UI scale setting (#100 #117 #118)
jeff141 Jun 19, 2026
08649a1
feat(sftp): 文件多选 + 批量下载/删除 / multi-select with batch download & delet…
jeff141 Jun 19, 2026
ab4ad0a
feat(sftp): 多选打包下载 + 空文件夹提示 / archive multi-download & empty-folder n…
jeff141 Jun 19, 2026
7d34c95
fix(sftp): 勾选多项时任意下载都打包 + 纯tar按首文件命名 / pack on any download when mult…
jeff141 Jun 19, 2026
8262388
feat(sftp): 打包时显示「文件准备中」 / show "Preparing" while archiving (#100)
jeff141 Jun 19, 2026
7c70f3b
perf(sftp): 下载流水线提速 + 可取消下载并清理残留 / pipelined download speedup + cance…
jeff141 Jun 19, 2026
cc7e691
fix(macos): 用 Skia 渲染器修复 macOS 26 文本全部消失 / use Skia renderer to fix a…
jeff141 Jun 19, 2026
b0cd8ad
chore(release): 0.4.10
jeff141 Jun 19, 2026
2a164aa
新改动:网络乞丐,乞讨专用,各位爷 行行好(开玩笑的有空可以捐赠一两块,让我去买点token吧哈哈哈)
jeff141 Jun 19, 2026
11ca4df
chore: 屏蔽 ICU4X 段落数据噪音日志 / silence ICU4X segmentation-data log spam
jeff141 Jun 19, 2026
296a76e
feat(sftp): 上传也支持取消并清理远端半成品 / cancellable upload with remote cleanup …
jeff141 Jun 19, 2026
5694548
fix(macos): 不再强制 Skia 渲染器,修复 macOS 文本全部消失 / stop forcing Skia rendere…
jeff141 Jun 19, 2026
d20f022
fix(macos): 默认中文字体改用 Heiti SC,修复 macOS 26 文字全白;发布 0.4.12 / default CJ…
jeff141 Jun 20, 2026
dc19874
feat(quick-cmd): 快捷命令支持分组与收起 / group quick commands with collapsible …
jeff141 Jun 20, 2026
c00981a
feat(quick-cmd): 快捷命令右键编辑/移动/复制 + 分组增删改,对齐会话面板 / right-click manage q…
jeff141 Jun 20, 2026
779bcbd
fix(quick-cmd): 弹窗内支持右键菜单 + 分组默认收起 / right-click menu in the popup + …
jeff141 Jun 20, 2026
e6d36d2
chore(log): 消除启动期 fontdb/字体选择告警噪音 / silence fontdb + routine font-pic…
jeff141 Jun 20, 2026
ea05fa0
fix(sftp): 加密私钥的 SFTP 连接复用口令 + ssh_config 导入显示结果 / pass passphrase fo…
jeff141 Jun 20, 2026
31751cb
feat(ui): 侧栏拖动调宽 + 进程监视独立窗口 + 设置界面简约重做 / drag-resize sidebar, detacha…
jeff141 Jun 21, 2026
918432e
fix(ssh): 密码认证失败时回退 keyboard-interactive(修复 JumpServer 等堡垒机登录) / fall…
jeff141 Jun 21, 2026
3f2bef2
fix(ssh): 密码认证失败时回退 keyboard-interactive(修复 JumpServer 等堡垒机登录) / fall…
jeff141 Jun 21, 2026
3da8bc4
feat(ui): 面板拖动吸附停靠(资源面板 + SFTP)+ 布局持久化 / drag-to-dock panels (resourc…
jeff141 Jun 21, 2026
dfe069b
feat(ui): 界面上的一些优化(Some interface optimizations)
jeff141 Jun 22, 2026
9ce0792
fix(terminal): 修复含中文行的选区复制/查找列错位(宽字符) / fix copy & find column drift …
jeff141 Jun 22, 2026
5e5e0ec
### Added / 新增
jeff141 Jun 22, 2026
880e73e
feat(config): 配置/日志改为便携优先,存到程序同目录 config/(向下兼容)/ portable-first data …
jeff141 Jun 22, 2026
76ad56e
feat(theme): 沉浸式壁纸主题——可换壁纸 + 全局沉浸配色 + 3 张内置 / immersive wallpaper the…
jeff141 Jun 22, 2026
394ee01
chore(release): 发布 0.4.16 / release 0.4.16
jeff141 Jun 22, 2026
8889d6a
feat(ssh): 支持 MFA / 验证码登录(JumpServer 等强制开启 MFA 的堡垒机)(#86)
jeff141 Jun 23, 2026
d840723
perf(ui): 空闲降耗——失焦停光标闪烁 + 后台暂停/降频系统采样 (#127)
jeff141 Jun 23, 2026
8ce7f07
docs: 修正 macOS 安装说明——产物是 .zip + meatshell.app,而非 .tar.gz + 裸二进制 (#135)
jeff141 Jun 23, 2026
56decfe
feat(ssh,ui): 修复 Windows/pwsh 服务端 shell + 关窗/Esc 交互 + 纯键盘历史检索 (#140)
jeff141 Jun 23, 2026
87d0f11
chore(release): 发布 0.4.17 / release 0.4.17
jeff141 Jun 23, 2026
8492828
fix(ssh,sftp): 给连接加 keepalive,修复 SFTP 闲置一段时间后失效 (#160)
jeff141 Jun 25, 2026
c529509
fix(terminal): 防抖 PTY resize,修复 git clone/curl 输出在 ~10 列乱折行 (#163)
jeff141 Jun 25, 2026
c9bde7a
feat(ui): Win11 无边框窗口加圆角 + 投影 (#162/#166)
jeff141 Jun 25, 2026
54fe6ac
feat(ui): macOS 上 app 快捷键改用 Cmd(⌘),释放 Ctrl 给终端 (#158)
jeff141 Jun 25, 2026
fac95d4
fix(ui): 设置/下载下拉跟随按钮位移,避免停靠资源面板时盖到面板上
jeff141 Jun 25, 2026
3e85114
fix(ui): 浅色模式加深次要/弱化文字,提升磨砂白底上的可读性
jeff141 Jun 25, 2026
e60184b
CVE问题
jeff141 Jun 25, 2026
a45d3d3
chore(release): 发布 0.4.18 / release 0.4.18
jeff141 Jun 25, 2026
c544c1c
add custom font setting
zenaurora Jun 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/aur-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Publish to AUR

# Pushes the meatshell-bin package to the AUR after a GitHub Release is
# published. Requires three repository secrets (see packaging/aur/README.md):
# AUR_USERNAME, AUR_EMAIL, AUR_SSH_PRIVATE_KEY
# Without them the job is skipped, so this is harmless until you set AUR up.
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "Version to publish (e.g. 0.3.6); blank = latest release"
required: false

jobs:
aur:
runs-on: ubuntu-latest
# Only run once the AUR SSH key is configured.
if: ${{ github.event_name == 'workflow_dispatch' || github.event.release != null }}
steps:
- uses: actions/checkout@v4

- name: Resolve version + set pkgver
run: |
set -eu
VER="${{ github.event.inputs.version }}"
if [ -z "$VER" ] && [ -n "${{ github.event.release.tag_name }}" ]; then
VER="${{ github.event.release.tag_name }}"
fi
if [ -z "$VER" ]; then
VER=$(curl -fsSL https://api.github.com/repos/${{ github.repository }}/releases/latest \
| grep -oP '"tag_name":\s*"\K[^"]+')
fi
VER="${VER#v}" # strip leading v
echo "Publishing meatshell-bin $VER"
sed -i "s/^pkgver=.*/pkgver=${VER}/" packaging/aur/PKGBUILD
sed -i "s/^pkgrel=.*/pkgrel=1/" packaging/aur/PKGBUILD
echo "VER=$VER" >> "$GITHUB_ENV"

- name: Publish meatshell-bin to the AUR
# Skips cleanly until the AUR SSH key secret is configured.
if: ${{ secrets.AUR_SSH_PRIVATE_KEY != '' }}
uses: KSXGitHub/github-actions-deploy-aur@v2.7.2
with:
pkgname: meatshell-bin
pkgbuild: packaging/aur/PKGBUILD
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: "Update to ${{ env.VER }}"
updpkgsums: true
ssh_keyscan_types: rsa,ed25519
225 changes: 225 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
name: Release

# Build native binaries for Windows / Linux / macOS.
# - Push a tag like `v0.2.3` -> builds all platforms and attaches the archives
# to a GitHub Release.
# - Run manually (workflow_dispatch) -> builds all platforms and uploads them as
# downloadable workflow artifacts (no release created).

on:
push:
tags: ["v*"]
workflow_dispatch:

permissions:
contents: write # needed to create / update the GitHub Release

jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
name: windows-x86_64
bin: meatshell.exe
- os: ubuntu-22.04 # build on the oldest supported runner for
target: x86_64-unknown-linux-gnu # broader glibc compatibility
name: linux-x86_64
bin: meatshell
- os: ubuntu-22.04-arm # free native arm64 runner (public repos)
target: aarch64-unknown-linux-gnu # builds the Linux ARM64 .tar.gz (#82)
name: linux-aarch64
bin: meatshell
- os: macos-14 # Apple Silicon
target: aarch64-apple-darwin
name: macos-aarch64
bin: meatshell
- os: macos-14 # Apple Silicon runner — cross-compiles the
target: x86_64-apple-darwin # x86_64 Mac binary. (Dedicated Intel
name: macos-x86_64 # macos-13 runners queue for ages / time out.)
bin: meatshell

steps:
- uses: actions/checkout@v4

# Slint (winit + femtovg) + rfd (GTK) + arboard need these system libs.
# Build-time only — no GPU/display required to compile.
- name: Install Linux GUI dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential pkg-config cmake \
libfontconfig1-dev libfreetype6-dev \
libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev libxkbcommon-x11-dev libwayland-dev \
libgl1-mesa-dev libegl1-mesa-dev libgtk-3-dev \
libudev-dev

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Cache cargo build
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}

- name: Build (release)
run: cargo build --release --target ${{ matrix.target }}

- name: Build AppImage
if: matrix.name == 'linux-x86_64'
continue-on-error: true # don't block the .tar.gz if AppImage fails
env:
APPIMAGE_EXTRACT_AND_RUN: "1" # no FUSE needed in CI
run: |
set -eu
VERSION="${GITHUB_REF_NAME:-dev}"
wget -q -O linuxdeploy \
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
wget -q -O linuxdeploy-plugin-appimage \
https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage
chmod +x linuxdeploy linuxdeploy-plugin-appimage

install -Dm755 target/${{ matrix.target }}/release/meatshell AppDir/usr/bin/meatshell
install -Dm644 assets/meatshell.desktop AppDir/usr/share/applications/meatshell.desktop
install -Dm644 assets/icon@512.png AppDir/usr/share/icons/hicolor/512x512/apps/meatshell.png

# --output appimage already invokes the plugin; --plugin appimage is redundant and causes an error
./linuxdeploy --appdir AppDir --output appimage

mv meatshell*.AppImage "meatshell-${VERSION}-linux-x86_64.AppImage"
echo "APPIMAGE=meatshell-${VERSION}-linux-x86_64.AppImage" >> "$GITHUB_ENV"

- name: Package
shell: bash
run: |
set -eu
VERSION="${GITHUB_REF_NAME:-dev}"
STAGE="meatshell-${VERSION}-${{ matrix.name }}"

if [ "${{ runner.os }}" = "macOS" ]; then
# ── Build a proper .app bundle ────────────────────────────────────
# Without a bundle macOS opens raw binaries in Terminal.app, which
# stays alive after the app exits and never shows a Dock icon.
APP="meatshell.app"
CONTENTS="$APP/Contents"
mkdir -p "$CONTENTS/MacOS" "$CONTENTS/Resources"

cp "target/${{ matrix.target }}/release/meatshell" "$CONTENTS/MacOS/"

# Generate .icns from the 512×512 PNG using sips + iconutil (both
# ship with every macOS, no extra tooling needed in CI).
mkdir -p meatshell.iconset
sips -z 16 16 "assets/icon@512.png" --out meatshell.iconset/icon_16x16.png >/dev/null
sips -z 32 32 "assets/icon@512.png" --out meatshell.iconset/icon_16x16@2x.png >/dev/null
sips -z 32 32 "assets/icon@512.png" --out meatshell.iconset/icon_32x32.png >/dev/null
sips -z 64 64 "assets/icon@512.png" --out meatshell.iconset/icon_32x32@2x.png >/dev/null
sips -z 128 128 "assets/icon@512.png" --out meatshell.iconset/icon_128x128.png >/dev/null
sips -z 256 256 "assets/icon@512.png" --out meatshell.iconset/icon_128x128@2x.png >/dev/null
sips -z 256 256 "assets/icon@512.png" --out meatshell.iconset/icon_256x256.png >/dev/null
sips -z 512 512 "assets/icon@512.png" --out meatshell.iconset/icon_256x256@2x.png >/dev/null
sips -z 512 512 "assets/icon@512.png" --out meatshell.iconset/icon_512x512.png >/dev/null
iconutil -c icns meatshell.iconset -o "$CONTENTS/Resources/meatshell.icns"

# Substitute __VERSION__ placeholder (strip leading 'v' from tag)
VERSION_NUM="${VERSION#v}"
sed "s/__VERSION__/${VERSION_NUM}/g" assets/Info.plist > "$CONTENTS/Info.plist"

# Ad-hoc code-sign the assembled bundle.
# The release profile strips the binary (Cargo.toml: strip = "symbols"),
# which invalidates the linker's automatic ad-hoc signature — on Apple
# Silicon that makes the OS refuse to launch it ("app is damaged").
# Re-signing the whole bundle here restores a valid (ad-hoc) signature,
# turning the fatal "damaged" error into the normal "unidentified
# developer" prompt that users can bypass via Open Anyway / xattr.
codesign --force --deep --sign - "$APP"
codesign --verify --verbose "$APP"

# Package with ditto (Apple's tool) — it preserves the bundle's
# signature and metadata. Plain `zip` mangles them and re-breaks the
# signature, which would reintroduce the "damaged" error.
ditto -c -k --keepParent "$APP" "${STAGE}.zip"
echo "ASSET=${STAGE}.zip" >> "$GITHUB_ENV"

elif [ "${{ runner.os }}" = "Windows" ]; then
mkdir "$STAGE"
cp "target/${{ matrix.target }}/release/${{ matrix.bin }}" "$STAGE/"
cp README.md README.en.md CHANGELOG.md "$STAGE/" 2>/dev/null || true
7z a "${STAGE}.zip" "$STAGE" >/dev/null
echo "ASSET=${STAGE}.zip" >> "$GITHUB_ENV"

else
# Linux
mkdir "$STAGE"
cp "target/${{ matrix.target }}/release/${{ matrix.bin }}" "$STAGE/"
cp README.md README.en.md CHANGELOG.md "$STAGE/" 2>/dev/null || true
# Ship the desktop entry + installer + icon so the dock shows the icon.
cp assets/meatshell.desktop assets/install-linux.sh "assets/icon@512.png" "$STAGE/" 2>/dev/null || true
tar -czf "${STAGE}.tar.gz" "$STAGE"
echo "ASSET=${STAGE}.tar.gz" >> "$GITHUB_ENV"
fi

# MSI installer with a "choose install location" wizard (WixUI_InstallDir).
# Best-effort: if the WiX/cargo-wix tooling hiccups it must not block the
# .zip release, hence continue-on-error.
- name: Build MSI installer (Windows)
if: matrix.name == 'windows-x86_64'
continue-on-error: true
shell: pwsh
run: |
$VERSION = "$env:GITHUB_REF_NAME"; if (-not $VERSION) { $VERSION = "dev" }
# WiX 3 toolset (candle/light) that cargo-wix drives.
choco install wixtoolset -y --no-progress
$candle = Get-ChildItem "C:\Program Files (x86)\WiX Toolset*\bin\candle.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($candle) { $env:PATH = "$($candle.DirectoryName);$env:PATH" }
cargo install cargo-wix --locked
cargo wix --no-build --nocapture --target ${{ matrix.target }} --output "meatshell-$VERSION-windows-x86_64.msi"
echo "MSI=meatshell-$VERSION-windows-x86_64.msi" >> $env:GITHUB_ENV

- name: Upload workflow artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}
path: ${{ env.ASSET }}

- name: Upload AppImage artifact
if: matrix.name == 'linux-x86_64'
uses: actions/upload-artifact@v4
with:
name: linux-x86_64-appimage
path: ${{ env.APPIMAGE }}

- name: Upload MSI artifact
if: matrix.name == 'windows-x86_64' && env.MSI != ''
uses: actions/upload-artifact@v4
with:
name: windows-x86_64-msi
path: ${{ env.MSI }}

- name: Attach to GitHub Release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ env.ASSET }}
fail_on_unmatched_files: true

- name: Attach AppImage to GitHub Release
if: matrix.name == 'linux-x86_64' && startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ env.APPIMAGE }}
fail_on_unmatched_files: true

- name: Attach MSI to GitHub Release
if: matrix.name == 'windows-x86_64' && env.MSI != '' && startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ env.MSI }}
fail_on_unmatched_files: false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ Cargo.lock
.DS_Store
/.vscode
/.idea
/.claude
Loading