Aplikasi Wails dengan Self-Update
Dalam tutorial ini Anda akan menambahkan updater dalam aplikasi ke aplikasi Wails v3 baru. Di akhir, aplikasi akan:
- Mengecek GitHub Releases sesuai permintaan (dan opsional dengan timer).
- Mengunduh asset yang tepat untuk OS + arsitektur yang sedang berjalan.
- Memverifikasi digest SHA-256 (dan opsional tanda tangan Ed25519) terhadap byte yang diunduh.
- Menampilkan release notes di jendela update default framework.
- Menukar biner yang sedang berjalan dan meluncurkan ulang — semua tanpa mengirim executable helper terpisah.
Kita akan menggunakan GitHub Releases sebagai sumber update karena gratis dan tidak memerlukan infrastruktur. Pola yang sama bekerja dengan keygen.sh dan Sparkle AppCast — lihat panduan Updater setelah selesai.
-
Mulai dengan aplikasi Wails baru
Section titled “Mulai dengan aplikasi Wails baru”Buat proyek baru dengan template vanilla:
Terminal window wails3 init --template vanilla --name updater-tutorialcd updater-tutorialAnda sekarang seharusnya memiliki direktori dengan
main.go,frontend/, danTaskfile.yml. Konfirmasi dapat di-build dan diluncurkan:Terminal window wails3 task devJendela Wails kosong seharusnya terbuka. Keluar dan lanjutkan.
-
Tambahkan import updater
Section titled “Tambahkan import updater”Buka
main.godan tambahkan dua paket updater ke import Anda:main.go package mainimport (_ "embed""github.com/wailsapp/wails/v3/pkg/application""github.com/wailsapp/wails/v3/pkg/updater""github.com/wailsapp/wails/v3/pkg/updater/providers/github")Ini menarik Updater itu sendiri dan provider GitHub Releases.
-
Konfigurasi Updater
Section titled “Konfigurasi Updater”app.Updatersudah terhubung ke setiap*application.App— Anda hanya perlu memanggilInit:main.go const currentVersion = "1.0.0"gh, err := github.New(github.Config{Repository: "yourorg/your-repo", // ← change thisChecksumAsset: "SHA256SUMS", // sibling file with sha256 digests})if err != nil {log.Fatalf("github.New: %v", err)}if err := app.Updater.Init(updater.Config{CurrentVersion: currentVersion,Providers: []updater.Provider{gh},}); err != nil {log.Fatalf("Updater.Init: %v", err)}Tempatkan ini setelah
application.Newdan sebelumapp.Run(). -
Tambahkan item menu yang memicu update
Section titled “Tambahkan item menu yang memicu update”Di
main.goyang sama, tambahkan entri menu “Check for Updates…”:main.go menu := app.Menu.New()app.Menu.SetApplicationMenu(menu)appMenu := menu.AddSubmenu("App")appMenu.Add("Check for Updates…").OnClick(func(*application.Context) {go func() {if err := app.Updater.CheckAndInstall(context.Background()); err != nil {app.Logger.Error("update", "error", err)}}()})CheckAndInstallmembuka jendela update framework, menjalankanCheck, dan jika rilis ditemukan, menjalankanDownloadAndInstallotomatis. Jendela tetap terbuka dalam state “Up to Date” saat tidak ada yang baru — pengguna menutupnya dengan tombol Close. -
Jalankan sekali tanpa rilis
Section titled “Jalankan sekali tanpa rilis”Terminal window wails3 task devKlik App → Check for Updates…. Anda seharusnya melihat jendela update terbuka sebentar, mengakses API GitHub, tidak menemukan rilis lebih baru dari
1.0.0, dan menetap pada state Up to Date dengan ✓ hijau.Jika Anda mendapat error di sini, biasanya salah satu dari:
Gejala Perbaikan 404 Not FoundField Repositorysalah — harusowner/repo403 rate-limitedTambahkan Token: "ghp_…"ke github.Config (gunakan PAT dengan scopepublic_repo)Network errors Konfirmasi aplikasi yang berjalan dapat mengakses api.github.com -
Terbitkan rilis uji
Section titled “Terbitkan rilis uji”Naikkan
currentVersiondimain.goke1.0.0(atau biarkan). Build untuk satu platform untuk mendapatkan biner yang dapat dilampirkan ke rilis:Terminal window wails3 task build:darwin# produces bin/updater-tutorial.app# zip it for the release asset:cd bin && zip -r updater-tutorial-darwin-arm64.zip updater-tutorial.app && cd ..Terminal window wails3 task build:linux# produces bin/updater-tutorialmv bin/updater-tutorial bin/updater-tutorial-linux-amd64Terminal window wails3 task build:windows# produces bin/updater-tutorial.exemv bin/updater-tutorial.exe bin/updater-tutorial-windows-amd64.exeBuat file
SHA256SUMSdi samping biner:Terminal window cd binshasum -a 256 updater-tutorial-* > SHA256SUMScat SHA256SUMSAnda seharusnya melihat satu atau lebih baris seperti:
abc123… updater-tutorial-darwin-arm64.zipSekarang terbitkan ini sebagai v2.0.0 di repositori GitHub Anda:
Terminal window gh release create v2.0.0 \--title "v2.0.0" \--notes "First update for the self-update tutorial.- **Bold** Markdown renders in the update window- \`Code spans\` too- Lists work- GFM tables work" \bin/SHA256SUMS bin/updater-tutorial-* -
Jalankan aplikasi dan verifikasi update
Section titled “Jalankan aplikasi dan verifikasi update”Dengan
currentVersionmasih1.0.0, jalankan aplikasi lagi:Terminal window wails3 task devKlik App → Check for Updates…. Kali ini Anda seharusnya melihat sesuatu seperti:

- Ikon hero berubah dari biru ↓ (“Update Available”) ke hijau ✓ (“Update Ready”).
- Subtitle menampilkan
v1.0.0 → v2.0.0 · <size>. - Panel release notes merender Markdown Anda dengan bold, code span, dan tabel.
- Progress bar terisi selama unduhan (cepat — biner kecil).
Updater men-stage biner baru di direktori temp. Untuk menyelesaikan update:
- Klik Restart & Apply.
- Aplikasi Anda keluar, helper menukar biner, biner baru diluncurkan ulang.
- Aplikasi yang diluncurkan ulang melaporkan
currentVersion = "1.0.0"(karena kita hardcode), tetapi byte di disk sesuai build v2.0.0.
Di aplikasi nyata,
currentVersionakan diset saat build via-ldflagsagar biner baru tahu sekarang v2.0.0 dan pengecekan berikutnya tidak menemukan update. -
Hubungkan
Section titled “Hubungkan currentVersion ke build”currentVersionke buildGanti konstanta dengan variabel build-time:
main.go var (currentVersion = "dev" // overridden by -ldflags at release time)Lalu di perintah build Anda:
Terminal window wails3 task build:darwin -- -ldflags "-X main.currentVersion=2.0.0"Atau tambahkan
-ldflagskeTaskfile.ymlagar mengambil darigit describe --tags. -
Tambahkan penandatanganan kriptografis (disarankan untuk produksi)
Section titled “Tambahkan penandatanganan kriptografis (disarankan untuk produksi)”Path SHA256SUMS memverifikasi integritas (byte sesuai yang disimpan GitHub) tetapi bukan autentisitas (byte tersebut diproduksi pipeline rilis Anda, bukan akun maintainer yang dikompromikan). Untuk ketahanan terhadap perubahan, tandatangani setiap rilis dengan kunci Ed25519:
Terminal window # One-time: generate the keypairssh-keygen -t ed25519 -f updater-key -N "" -C "wails-updater"# updater-key — keep secret (build server, HSM, password manager)# updater-key.pub — bundle in your appUntuk setiap rilis, tandatangani digest SHA-256 setiap asset dengan kunci privat Anda. Helper Go kecil:
cmd/sign-release/main.go package mainimport ("crypto/ed25519""crypto/sha256""encoding/base64""fmt""io""os")func main() {priv, _ := os.ReadFile("updater-key")key := ed25519.PrivateKey(priv) // raw 64-byte private keyf, _ := os.Open(os.Args[1])defer f.Close()h := sha256.New()_, _ = io.Copy(h, f)sig := ed25519.Sign(key, h.Sum(nil))fmt.Println(base64.StdEncoding.EncodeToString(sig))}Provider GitHub default saat ini tidak mengambil file tanda tangan terpisah — Anda dapat menulis provider kustom yang melakukannya, atau beralih ke keygen.sh yang menandatangani setiap artifact di sisi server dan mengekspos digest dan tanda tangan via API-nya.
Embed kunci publik di aplikasi Anda:
main.go //go:embed updater-key.pubvar updaterPublicKey []byteapp.Updater.Init(updater.Config{CurrentVersion: currentVersion,PublicKey: updaterPublicKey,Providers: []updater.Provider{gh},})Dengan
PublicKeydiset, rilis apa pun yang mengirimSignatureharus diverifikasi terhadap kunci ini. Sumber rilis tidak dapat mengganti kuncinya sendiri — itulah tujuan pinning out-of-band saat build time. -
Sesuaikan jendela
Section titled “Sesuaikan jendela”Jendela default mencakup kasus umum. Tiga jalan keluar jika Anda butuh kontrol lebih — pilih satu berdasarkan seberapa banyak yang ingin disesuaikan:
app.Updater.Init(updater.Config{// …Window: &updater.BuiltinWindow{CSS: `:root { --accent: #ff6f00; --radius: 16px; }`,},})Lihat bagian Tema via variabel CSS untuk daftar variabel lengkap.
//go:embed updater-window.htmlvar updaterHTML stringapp.Updater.Init(updater.Config{// …Window: &updater.BuiltinWindow{HTML: updaterHTML},})HTML Anda harus subscribe ke event
updater:*dan emit aksiupdater:user:*via channel event Wails. Lihat Ganti template untuk shim JS.myWin := app.Window.NewWithOptions(application.WebviewWindowOptions{Title: "My App Updater",Width: 520, Height: 460,HTML: updaterHTML,AllowSimpleEventEmit: true, // required — see security note})app.Updater.Init(updater.Config{// …Window: updater.BYOWindow(myWin.AsUpdaterWindow()),})Berguna saat Anda sudah punya infrastruktur jendela sendiri dan ingin updater mengendalikannya alih-alih membuka jendela lain. Template HTML sepenuhnya kustom — didorong oleh event updater yang sama dengan default — terlihat seperti ini:

-
Jalankan pengecekan otomatis di latar belakang
Section titled “Jalankan pengecekan otomatis di latar belakang”Untuk mengecek dengan timer alih-alih (atau selain) klik menu:
app.Updater.Init(updater.Config{CurrentVersion: currentVersion,Providers: []updater.Provider{gh},PublicKey: updaterPublicKey,CheckInterval: 6 * time.Hour,})Setiap tick menjalankan alur
CheckAndInstallyang sama seperti klik manual. SetWindow: updater.WindowNonejika Anda ingin pengecekan berkala diam sampai sesuatu benar-benar ditemukan — lalu subscribe keEventUpdateAvailablesendiri untuk memutuskan UX apa yang ditampilkan.
Selesai
Section titled “Selesai”Anda sekarang memiliki aplikasi Wails yang:
- Mengecek GitHub Releases untuk update sesuai permintaan dan dengan timer.
- Merender release notes sebagai Markdown di jendela default yang rapi.
- Memverifikasi unduhan terhadap digest SHA-256 yang Anda terbitkan.
- Opsional memverifikasi tanda tangan Ed25519 terhadap kunci publik yang Anda embed saat build time.
- Menukar biner yang sedang berjalan in-place dan meluncurkan ulang otomatis.
Langkah selanjutnya
Section titled “Langkah selanjutnya”- Panduan Updater memiliki referensi API lengkap, setiap event, setiap opsi konfigurasi, dan mekanisme swap mode helper.
- Lihat
v3/examples/updateruntuk contoh lengkap yang dapat Anda clone. - Repo target uji
wailsapp/updater-demomenunjukkan tata letak release-asset yang disarankan.
Hal yang perlu diperhatikan di produksi
Section titled “Hal yang perlu diperhatikan di produksi”- Code signing di macOS — Gatekeeper memerlukan biner yang ditukar ditandatangani dan dinotarisasi. Tandatangani bundle
.appAnda sebelum zip untuk rilis. Updater mempertahankan byte verbatim; tidak menandatangani ulang apa pun. - Antivirus di Windows — file
.exeunsigned yang diunduh dari internet dapat memicu peringatan SmartScreen. Tandatangani biner dengan sertifikat Authenticode, atau terima bahwa pengguna di mesin terkunci mungkin perlu whitelist aplikasi Anda. - Rilis atomik — terbitkan
SHA256SUMS(dan biner Anda) bersama, bukan di commit terpisah. Updater mengambil sidecar terpisah dari biner; jika keduanya drift, pemeriksaan digest gagal closed. - Versi yang dilewati — tombol “Skip This Version” jendela default mencatat skip secara lokal. Jika Anda mengirim update keamanan kritis, beri nomor versi baru agar tidak otomatis dilewati pengguna yang menolak rilis sebelumnya.