|
| 1 | +# DevStack Updater Setup |
| 2 | + |
| 3 | +Tài liệu này ghi rõ cách tạo lại updater key, setup GitHub Secrets, build release, và cách updater native trong app đang được cấu hình. |
| 4 | + |
| 5 | +## Tổng quan |
| 6 | + |
| 7 | +App hiện đang có 2 chế độ: |
| 8 | + |
| 9 | +- Native auto-update của Tauri: chỉ hoạt động khi lúc build có `TAURI_UPDATER_PUBKEY` và `TAURI_UPDATER_ENDPOINT`. |
| 10 | +- Manual update fallback: nếu build không có 2 biến trên, app vẫn check GitHub Releases và mở trang tải bản mới. |
| 11 | + |
| 12 | +Code hiện đang đọc 2 biến này bằng `option_env!`, nên đây là compile-time env vars. Nghĩa là chúng phải có sẵn trong GitHub Actions trước khi chạy build. |
| 13 | + |
| 14 | +## 1. Tạo lại updater key |
| 15 | + |
| 16 | +Chỉ tạo lại key nếu bạn chưa phát hành updater cho người dùng, hoặc bạn chấp nhận rằng các bản đã cài bằng key cũ sẽ không nhận được native update nữa. |
| 17 | + |
| 18 | +### Xóa key cũ |
| 19 | + |
| 20 | +Chạy trên PowerShell: |
| 21 | + |
| 22 | +```powershell |
| 23 | +Remove-Item "$HOME\.tauri\devstack.key" -Force -ErrorAction SilentlyContinue |
| 24 | +Remove-Item "$HOME\.tauri\devstack.key.pub" -Force -ErrorAction SilentlyContinue |
| 25 | +``` |
| 26 | + |
| 27 | +Nếu thư mục chưa tồn tại: |
| 28 | + |
| 29 | +```powershell |
| 30 | +New-Item -ItemType Directory -Force "$HOME\.tauri" |
| 31 | +``` |
| 32 | + |
| 33 | +### Tạo key mới có password |
| 34 | + |
| 35 | +```powershell |
| 36 | +npm run tauri signer generate -- -w "$HOME\.tauri\devstack.key" |
| 37 | +``` |
| 38 | + |
| 39 | +CLI sẽ hỏi: |
| 40 | + |
| 41 | +```text |
| 42 | +Please enter a password to protect the secret key. |
| 43 | +Password: |
| 44 | +Password (one more time): |
| 45 | +``` |
| 46 | + |
| 47 | +Nhập password bạn muốn dùng để mã hóa private key. |
| 48 | + |
| 49 | +### Kiểm tra key đã tạo |
| 50 | + |
| 51 | +```powershell |
| 52 | +Get-ChildItem "$HOME\.tauri\devstack.key*" |
| 53 | +``` |
| 54 | + |
| 55 | +Lấy public key: |
| 56 | + |
| 57 | +```powershell |
| 58 | +Get-Content "$HOME\.tauri\devstack.key.pub" |
| 59 | +``` |
| 60 | + |
| 61 | +Lấy private key: |
| 62 | + |
| 63 | +```powershell |
| 64 | +Get-Content "$HOME\.tauri\devstack.key" |
| 65 | +``` |
| 66 | + |
| 67 | +## 2. GitHub cần setup gì |
| 68 | + |
| 69 | +Vào repo GitHub: |
| 70 | + |
| 71 | +`Settings` -> `Secrets and variables` -> `Actions` -> `New repository secret` |
| 72 | + |
| 73 | +Tạo 3 secrets sau: |
| 74 | + |
| 75 | +### `TAURI_SIGNING_PRIVATE_KEY` |
| 76 | + |
| 77 | +Giá trị là nội dung file private key: |
| 78 | + |
| 79 | +```powershell |
| 80 | +Get-Content "$HOME\.tauri\devstack.key" -Raw |
| 81 | +``` |
| 82 | + |
| 83 | +Copy toàn bộ nội dung đó vào secret. |
| 84 | + |
| 85 | +### `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` |
| 86 | + |
| 87 | +Giá trị là password bạn vừa nhập lúc generate key. |
| 88 | + |
| 89 | +### `TAURI_UPDATER_PUBKEY` |
| 90 | + |
| 91 | +Giá trị là nội dung file public key: |
| 92 | + |
| 93 | +```powershell |
| 94 | +Get-Content "$HOME\.tauri\devstack.key.pub" -Raw |
| 95 | +``` |
| 96 | + |
| 97 | +Copy toàn bộ nội dung đó vào secret. |
| 98 | + |
| 99 | +## 3. `TAURI_UPDATER_ENDPOINT` là gì và setup thế nào |
| 100 | + |
| 101 | +Biến này là URL mà app sẽ dùng để check native updater. |
| 102 | + |
| 103 | +Trong workflow đã tạo sẵn, mình đặt: |
| 104 | + |
| 105 | +```text |
| 106 | +https://github.com/<owner>/<repo>/releases/latest/download/latest.json |
| 107 | +``` |
| 108 | + |
| 109 | +Với repo này nó sẽ trở thành: |
| 110 | + |
| 111 | +```text |
| 112 | +https://github.com/holdon1996/dev-stack/releases/latest/download/latest.json |
| 113 | +``` |
| 114 | + |
| 115 | +Bạn không cần tạo secret riêng cho biến này nếu giữ nguyên workflow hiện tại, vì workflow đã set trực tiếp trong `env`. |
| 116 | + |
| 117 | +Nếu sau này bạn muốn đổi sang CDN riêng hoặc update server riêng, sửa: |
| 118 | + |
| 119 | +[`release.yml`](/f:/dev-stack/.github/workflows/release.yml) |
| 120 | + |
| 121 | +dòng `TAURI_UPDATER_ENDPOINT`. |
| 122 | + |
| 123 | +## 3.1. Vì sao local build báo thiếu `pubkey` |
| 124 | + |
| 125 | +Tauri updater không chỉ đọc cấu hình ở runtime. Ngay lúc `tauri build`, bundler cũng sẽ parse: |
| 126 | + |
| 127 | +- `plugins.updater.pubkey` |
| 128 | +- `plugins.updater.endpoints` |
| 129 | + |
| 130 | +trong: |
| 131 | + |
| 132 | +[`tauri.conf.json`](/f:/dev-stack/src-tauri/tauri.conf.json) |
| 133 | + |
| 134 | +Nếu thiếu `pubkey`, build sẽ dừng với lỗi kiểu: |
| 135 | + |
| 136 | +```text |
| 137 | +failed to parse updater plugin configuration: missing field `pubkey` |
| 138 | +``` |
| 139 | + |
| 140 | +Vì vậy file config phải luôn có 2 trường này. |
| 141 | + |
| 142 | +Hiện trong repo mình đã thêm sẵn: |
| 143 | + |
| 144 | +```json |
| 145 | +"updater": { |
| 146 | + "pubkey": "PASTE_YOUR_TAURI_UPDATER_PUBLIC_KEY_HERE", |
| 147 | + "endpoints": [ |
| 148 | + "https://github.com/holdon1996/dev-stack/releases/latest/download/latest.json" |
| 149 | + ] |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +Việc bạn cần làm là thay: |
| 154 | + |
| 155 | +`PASTE_YOUR_TAURI_UPDATER_PUBLIC_KEY_HERE` |
| 156 | + |
| 157 | +bằng đúng nội dung file: |
| 158 | + |
| 159 | +```powershell |
| 160 | +Get-Content "$HOME\.tauri\devstack.key.pub" -Raw |
| 161 | +``` |
| 162 | + |
| 163 | +Lưu ý: |
| 164 | + |
| 165 | +- Đây là public key nên có thể commit vào repo. |
| 166 | +- Không dùng path file ở đây. |
| 167 | +- Phải là nội dung đầy đủ của public key trên một chuỗi string. |
| 168 | + |
| 169 | +## 4. Build release local để test |
| 170 | + |
| 171 | +Nếu muốn build local có updater native: |
| 172 | + |
| 173 | +```powershell |
| 174 | +$env:TAURI_SIGNING_PRIVATE_KEY = "$HOME\.tauri\devstack.key" |
| 175 | +$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD = "<password-của-bạn>" |
| 176 | +$env:TAURI_UPDATER_PUBKEY = Get-Content "$HOME\.tauri\devstack.key.pub" -Raw |
| 177 | +$env:TAURI_UPDATER_ENDPOINT = "https://github.com/holdon1996/dev-stack/releases/latest/download/latest.json" |
| 178 | +npm run tauri build |
| 179 | +``` |
| 180 | + |
| 181 | +Hoặc dùng script đã tạo sẵn: |
| 182 | + |
| 183 | +[`set-updater-env.ps1`](/f:/dev-stack/scripts/set-updater-env.ps1) |
| 184 | + |
| 185 | +```powershell |
| 186 | +. .\scripts\set-updater-env.ps1 |
| 187 | +npm run tauri build |
| 188 | +``` |
| 189 | + |
| 190 | +Nếu muốn truyền password trực tiếp: |
| 191 | + |
| 192 | +```powershell |
| 193 | +. .\scripts\set-updater-env.ps1 -Password "<password-của-bạn>" |
| 194 | +npm run tauri build |
| 195 | +``` |
| 196 | + |
| 197 | +Lưu ý: |
| 198 | + |
| 199 | +- `TAURI_SIGNING_PRIVATE_KEY` dùng path hoặc content đều được, theo docs Tauri. |
| 200 | +- `TAURI_UPDATER_PUBKEY` trong app hiện tại đang được nhúng vào lúc build, nên cần có trước `npm run tauri build`. |
| 201 | +- `.env` không được Tauri dùng cho signing key trong lúc build release. |
| 202 | +- Ngoài ra, trước khi build local bạn nên mở [`tauri.conf.json`](/f:/dev-stack/src-tauri/tauri.conf.json) và thay `pubkey` placeholder bằng public key thật. |
| 203 | + |
| 204 | +## 5. Release trên GitHub |
| 205 | + |
| 206 | +Workflow đã được tạo sẵn: |
| 207 | + |
| 208 | +[`release.yml`](/f:/dev-stack/.github/workflows/release.yml) |
| 209 | + |
| 210 | +Workflow này sẽ: |
| 211 | + |
| 212 | +- chạy khi push tag dạng `v*` |
| 213 | +- build bản Windows |
| 214 | +- ký updater artifacts |
| 215 | +- upload release assets lên GitHub Release |
| 216 | +- tạo `latest.json` để native updater dùng |
| 217 | + |
| 218 | +### Cách release |
| 219 | + |
| 220 | +Cập nhật version trước: |
| 221 | + |
| 222 | +- [`package.json`](/f:/dev-stack/package.json) |
| 223 | +- [`src-tauri/Cargo.toml`](/f:/dev-stack/src-tauri/Cargo.toml) |
| 224 | +- [`src-tauri/tauri.conf.json`](/f:/dev-stack/src-tauri/tauri.conf.json) |
| 225 | + |
| 226 | +Nên để cùng một version, ví dụ `1.0.1`. |
| 227 | + |
| 228 | +Sau đó tạo tag: |
| 229 | + |
| 230 | +```powershell |
| 231 | +git add . |
| 232 | +git commit -m "release: v1.0.1" |
| 233 | +git tag v1.0.1 |
| 234 | +git push origin main |
| 235 | +git push origin v1.0.1 |
| 236 | +``` |
| 237 | + |
| 238 | +Khi workflow chạy xong, vào tab `Releases` trên GitHub để kiểm tra: |
| 239 | + |
| 240 | +- có file installer `.exe` và/hoặc `.msi` |
| 241 | +- có file `.sig` |
| 242 | +- có file `latest.json` |
| 243 | + |
| 244 | +## 6. App đang dùng updater như thế nào |
| 245 | + |
| 246 | +Nếu build có đầy đủ biến updater: |
| 247 | + |
| 248 | +- Settings sẽ hiện chế độ `Native auto-update` |
| 249 | +- app có thể check, download, install update ngay trong app |
| 250 | + |
| 251 | +Nếu build thiếu cấu hình updater: |
| 252 | + |
| 253 | +- Settings sẽ hiện `Manual download` |
| 254 | +- app vẫn check release mới nhất, nhưng sẽ mở trang tải về thay vì auto-install |
| 255 | + |
| 256 | +## 7. Nguồn tham khảo chính thức |
| 257 | + |
| 258 | +- Tauri updater guide: https://v2.tauri.app/plugin/updater/ |
| 259 | +- Tauri updater JS API: https://v2.tauri.app/reference/javascript/updater/ |
| 260 | +- tauri-plugin-updater README: https://docs.rs/crate/tauri-plugin-updater/latest/source/README.md |
0 commit comments