Skip to content

Commit 2778a98

Browse files
authored
Merge pull request #246 from prixe/auto-updater
Auto updater - Linux / Windows
2 parents 17f96ec + 5e375e4 commit 2778a98

File tree

11 files changed

+160
-159
lines changed

11 files changed

+160
-159
lines changed

.github/workflows/build.yml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ jobs:
4747
path: |
4848
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-win.zip
4949
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-ia32-win.zip
50-
release/${{ steps.extract_version.outputs.version }}/Lindo ${{ steps.extract_version.outputs.version }}.exe
51-
release/${{ steps.extract_version.outputs.version }}/Lindo Setup ${{ steps.extract_version.outputs.version }}.exe
50+
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}.exe
51+
release/${{ steps.extract_version.outputs.version }}/Lindo-Setup-${{ steps.extract_version.outputs.version }}.exe
52+
release/${{ steps.extract_version.outputs.version }}/Lindo-Setup-${{ steps.extract_version.outputs.version }}.exe.blockmap
53+
release/${{ steps.extract_version.outputs.version }}/latest.yml
5254
5355
- name: Upload MacOS artifacts
5456
uses: actions/upload-artifact@v2
@@ -57,7 +59,14 @@ jobs:
5759
name: macos
5860
path: |
5961
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}.dmg
62+
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}.dmg.blockmap
6063
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-arm64.dmg
64+
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-arm64.dmg.blockmap
65+
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-mac.zip
66+
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-mac.zip.blockmap
67+
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-arm64-mac.zip
68+
release/${{ steps.extract_version.outputs.version }}/Lindo-${{ steps.extract_version.outputs.version }}-arm64-mac.zip.blockmap
69+
release/${{ steps.extract_version.outputs.version }}/latest-mac.yml
6170
6271
- name: Upload Linux artifacts
6372
uses: actions/upload-artifact@v2
@@ -71,6 +80,7 @@ jobs:
7180
release/${{ steps.extract_version.outputs.version }}/lindo-${{ steps.extract_version.outputs.version }}-arm64.tar.gz
7281
release/${{ steps.extract_version.outputs.version }}/lindo_${{ steps.extract_version.outputs.version }}_amd64.deb
7382
release/${{ steps.extract_version.outputs.version }}/lindo_${{ steps.extract_version.outputs.version }}_arm64.deb
83+
release/${{ steps.extract_version.outputs.version }}/latest-linux.yml
7484
7585
create-release:
7686
name: "Upload Release"
@@ -99,16 +109,25 @@ jobs:
99109
automatic_release_tag: "v${{ steps.extract_version.outputs.version }}"
100110
title: "v${{ steps.extract_version.outputs.version }}"
101111
files: |
102-
windows/Lindo ${{ steps.extract_version.outputs.version }}.exe
103-
windows/Lindo Setup ${{ steps.extract_version.outputs.version }}.exe
112+
windows/Lindo-${{ steps.extract_version.outputs.version }}.exe
113+
windows/Lindo-Setup-${{ steps.extract_version.outputs.version }}.exe
114+
windows/Lindo-Setup-${{ steps.extract_version.outputs.version }}.exe.blockmap
104115
windows/Lindo-${{ steps.extract_version.outputs.version }}-win.zip
105116
windows/Lindo-${{ steps.extract_version.outputs.version }}-ia32-win.zip
117+
windows/latest.yml
106118
linux/Lindo-${{ steps.extract_version.outputs.version }}.AppImage
107119
linux/Lindo-${{ steps.extract_version.outputs.version }}-arm64.AppImage
108120
linux/lindo-${{ steps.extract_version.outputs.version }}.tar.gz
109121
linux/lindo-${{ steps.extract_version.outputs.version }}-arm64.tar.gz
110122
linux/lindo_${{ steps.extract_version.outputs.version }}_amd64.deb
111123
linux/lindo_${{ steps.extract_version.outputs.version }}_arm64.deb
124+
linux/latest-linux.yml
112125
macos/Lindo-${{ steps.extract_version.outputs.version }}.dmg
126+
macos/Lindo-${{ steps.extract_version.outputs.version }}.dmg.blockmap
113127
macos/Lindo-${{ steps.extract_version.outputs.version }}-arm64.dmg
114-
128+
macos/Lindo-${{ steps.extract_version.outputs.version }}-arm64.dmg.blockmap
129+
macos/Lindo-${{ steps.extract_version.outputs.version }}-mac.zip
130+
macos/Lindo-${{ steps.extract_version.outputs.version }}-mac.zip.blockmap
131+
macos/Lindo-${{ steps.extract_version.outputs.version }}-arm64-mac.zip
132+
macos/Lindo-${{ steps.extract_version.outputs.version }}-arm64-mac.zip.blockmap
133+
macos/latest-mac.yml

electron-builder.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,20 @@
4545
]
4646
},
4747
"nsis": {
48+
"artifactName": "${productName}-Setup-${version}.${ext}",
4849
"oneClick": false,
4950
"perMachine": false,
5051
"allowToChangeInstallationDirectory": true,
5152
"deleteAppDataOnUninstall": false
5253
},
54+
"portable": {
55+
"artifactName": "${productName}-${version}.${ext}"
56+
},
5357
"afterPack": "./scripts/afterPackHook.js",
5458
"mac": {
5559
"target": [
5660
{
57-
"target": "dmg",
61+
"target": "default",
5862
"arch": [
5963
"x64",
6064
"arm64"

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "lindo",
33
"productName": "Lindo",
44
"private": true,
5-
"version": "3.0.0-rc.3",
5+
"version": "3.0.0-rc.8",
66
"description": "Play Dofus Touch on Linux/OS X/Window",
77
"homepage": "https://github.com/prixe/lindo",
88
"author": "Zenoxs <[email protected]>",
@@ -19,7 +19,6 @@
1919
},
2020
"dependencies": {
2121
"@hfelix/electron-localshortcut": "^4.0.1",
22-
"@octokit/rest": "^19.0.3",
2322
"argon2": "^0.28.7",
2423
"axios": "^0.27.2",
2524
"axios-retry": "^3.2.5",
@@ -28,6 +27,7 @@
2827
"crypto-js": "^4.1.1",
2928
"custom-electron-titlebar": "^4.1.0",
3029
"electron-store": "^8.0.1",
30+
"electron-updater": "^5.2.1",
3131
"eventemitter3": "^4.0.7",
3232
"express": "^4.18.1",
3333
"firebase": "^9.9.2",

packages/i18n/en/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const en: BaseTranslation = {
66
title: 'New version available {version: string}',
77
message: 'A new version ({version: string}) of Lindo is available. Do you want to update?',
88
messageRequired: 'A required update ({version: string}) of Lindo is available, you must download it on GitHub.',
9-
download: 'Download on GitHub',
9+
download: 'Download',
1010
ignore: 'Ignore'
1111
},
1212
gameMenu: {

packages/i18n/es/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const es: Translation = {
77
message: 'Una nueva version ({version}) de Lindo esta disponible. ¿Quieres descargar la actualización?',
88
messageRequired:
99
'Está disponible una nueva versión ({version}) obligatoria de Lindo, puedes descárgarla en GitHub.',
10-
download: 'Descárgarla en GitHub.',
10+
download: 'Descárgarla.',
1111
ignore: 'Ignorar'
1212
},
1313
gameMenu: {

packages/i18n/fr/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const fr: Translation = {
77
message: 'Une nouvelle version ({version}) de Lindo est disponible. Voulez-vous télécharger la mise à jour?',
88
messageRequired:
99
'Une nouvelle version ({version}) obligatoire de Lindo est disponible, vous pouvez la télécharger sur GitHub.',
10-
download: 'Télécharger sur github',
10+
download: 'Télécharger',
1111
ignore: 'Ignorer'
1212
},
1313
gameMenu: {

packages/main/constants/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,8 @@ export const LOCAL_DOFUS_MANIFEST_PATH = GAME_PATH + 'manifest.json'
1616
export const REMOTE_DOFUS_MANIFEST_URL = DOFUS_ORIGIN + 'manifest.json'
1717
export const LOCAL_VERSIONS_PATH = GAME_PATH + 'versions.json'
1818
export const LOCAL_REGEX_PATH = GAME_PATH + 'regex.json'
19+
20+
// GitHub
21+
export const GITHUB_OWNER = 'prixe'
22+
export const GITHUB_REPO = 'lindo'
23+
export const GITHUB_LATEST_RELEASE_URL = 'https://github.com/' + GITHUB_OWNER + '/' + GITHUB_REPO + '/releases/latest'
Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,90 @@
11
import { RootStore } from '@lindo/shared'
2-
import { Octokit } from '@octokit/rest'
3-
import compareVersions from 'compare-versions'
42
import { app, dialog, shell } from 'electron'
53
import { logger } from '../logger'
64
import { I18n } from '../utils'
5+
import { autoUpdater, UpdateInfo } from 'electron-updater'
6+
import { UpdaterWindow } from '../windows/updater-window'
7+
import { GITHUB_LATEST_RELEASE_URL, GITHUB_OWNER, GITHUB_REPO } from '../constants'
78

89
export class AppUpdater {
10+
private readonly _updaterWindow: UpdaterWindow
911
private readonly _rootStore: RootStore
10-
private readonly _octokit: Octokit
1112
private readonly _i18n: I18n
1213

13-
private constructor(rootStore: RootStore, i18n: I18n) {
14+
private constructor(updaterWindow: UpdaterWindow, rootStore: RootStore, i18n: I18n) {
15+
this._updaterWindow = updaterWindow
1416
this._rootStore = rootStore
1517
this._i18n = i18n
16-
this._octokit = new Octokit()
1718
}
1819

1920
static async init(rootStore: RootStore, i18n: I18n): Promise<AppUpdater> {
20-
return new AppUpdater(rootStore, i18n)
21+
const updaterWindow = await UpdaterWindow.init(rootStore, { show: false })
22+
return new AppUpdater(updaterWindow, rootStore, i18n)
2123
}
2224

2325
async run() {
2426
// set the current version of the app
27+
logger.info('appUpdater -> Start app update checking...')
2528
const currentVersion = app.getVersion()
2629
this._rootStore.appStore.setLindoVersion(currentVersion)
2730

28-
return this._octokit.repos
29-
.getLatestRelease({
30-
owner: 'prixe',
31-
repo: 'lindo'
31+
autoUpdater.logger = logger
32+
autoUpdater.autoDownload = false
33+
autoUpdater.setFeedURL({ provider: 'github', owner: GITHUB_OWNER, repo: GITHUB_REPO })
34+
35+
return new Promise<void>((resolve, reject) => {
36+
autoUpdater.on('checking-for-update', () => {
37+
logger.info('appUpdater -> Checking for updates...')
3238
})
33-
.then((res) => {
34-
const latestVersion = res.data.tag_name.replaceAll('v', '')
35-
const required = res.data.body?.includes('__update:required__') ?? false
36-
logger.info({ latestVersion, currentVersion })
37-
if (compareVersions(latestVersion, currentVersion) === 1) {
38-
return this._showUpdateDialog(latestVersion, required)
39+
40+
autoUpdater.on('update-available', (updateInfo: UpdateInfo) => {
41+
logger.info('appUpdater -> An Update is available v' + updateInfo.version)
42+
let required = false
43+
if (typeof updateInfo.releaseNotes === 'string') {
44+
required = updateInfo.releaseNotes.includes('__update:required__') ?? false
3945
}
46+
this._showUpdateDialog(updateInfo.version, required).then((ignored) => {
47+
// resolve the promise if the update is ignored
48+
if (ignored) {
49+
resolve()
50+
}
51+
})
52+
})
53+
54+
autoUpdater.on('update-not-available', () => {
55+
logger.info('appUpdater -> There is no available update')
56+
resolve()
57+
})
58+
59+
autoUpdater.on('download-progress', ({ percent }) => {
60+
this._updaterWindow.show()
61+
this._updaterWindow.sendProgress({ message: 'DOWNLOADING UPDATE', percent })
62+
})
63+
64+
autoUpdater.on('update-downloaded', () => {
65+
logger.info('appUpdater -> Update downloaded, will install now')
66+
this._updaterWindow.close()
67+
autoUpdater.quitAndInstall()
68+
})
69+
70+
autoUpdater.on('error', (error: Error) => {
71+
if (error) logger.info('appUpdater -> An error occured: ' + error)
72+
reject(error)
4073
})
74+
75+
autoUpdater.checkForUpdatesAndNotify().then(() => {
76+
logger.info('appUpdater -> Update check done')
77+
})
78+
})
4179
}
4280

43-
private _showUpdateDialog(newVersion: string, required: boolean): Promise<void> {
81+
/**
82+
*
83+
* @param newVersion
84+
* @param required
85+
* @returns true if the update is ignored, false otherwise
86+
*/
87+
private _showUpdateDialog(newVersion: string, required: boolean): Promise<boolean> {
4488
const buttons: Array<string> = [this._i18n.LL.main.updater.download()]
4589
if (!required) {
4690
buttons.push(this._i18n.LL.main.updater.ignore())
@@ -56,12 +100,21 @@ export class AppUpdater {
56100
})
57101
.then((returnValue) => {
58102
if (returnValue.response === 0) {
59-
logger.info('[UPDATE] Redirected to app download page.')
60-
shell.openExternal('https://github.com/prixe/lindo/releases/latest')
61-
app.exit()
103+
return autoUpdater.downloadUpdate().catch(async (err) => {
104+
logger.error('appUpdater -> unable to download automatically the release', err)
105+
await this._downloadFromWeb()
106+
return false
107+
})
62108
} else {
63-
logger.info('[UPDATE] App update ignored.')
109+
logger.info('appUpdater -> App update ignored.')
110+
return true
64111
}
65112
})
66113
}
114+
115+
private async _downloadFromWeb() {
116+
logger.info('appUpdater -> Redirected to app download page.')
117+
await shell.openExternal(GITHUB_LATEST_RELEASE_URL)
118+
app.exit()
119+
}
67120
}

packages/main/updater/updater.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const runUpdater = async (rootStore: RootStore, i18n: I18n) => {
1111
logger.error('Error running app updater:', err)
1212
})
1313

14+
logger.info('runUpdater -> Start game update checking...')
1415
const gameUpdater = await GameUpdater.init(rootStore)
1516
await gameUpdater.run().catch((e) => {
1617
console.log(e)

packages/main/windows/updater-window.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ type UpdaterWindowEvents = {
1010
close: (event: Event) => void
1111
}
1212

13+
export interface UpdaterWindowOptions {
14+
show?: boolean // will automatically show the window when dom is ready
15+
}
16+
1317
export class UpdaterWindow extends (EventEmitter as new () => TypedEmitter<UpdaterWindowEvents>) {
1418
private readonly _win: BrowserWindow
1519

16-
private constructor(userAgent: string) {
20+
private constructor(userAgent: string, options?: UpdaterWindowOptions) {
1721
super()
1822
this._win = new BrowserWindow({
1923
show: false,
@@ -32,9 +36,11 @@ export class UpdaterWindow extends (EventEmitter as new () => TypedEmitter<Updat
3236
// Show window when page is ready
3337
this._win.webContents.on('ipc-message', (event, channel) => {
3438
if (channel === IPCEvents.APP_READY_TO_SHOW) {
35-
setTimeout(() => {
36-
this._win.show()
37-
}, 100)
39+
if (options?.show ?? true) {
40+
setTimeout(() => {
41+
this._win.show()
42+
}, 100)
43+
}
3844
}
3945
})
4046

@@ -58,9 +64,9 @@ export class UpdaterWindow extends (EventEmitter as new () => TypedEmitter<Updat
5864
}
5965
}
6066

61-
static async init(store: RootStore): Promise<UpdaterWindow> {
67+
static async init(store: RootStore, options?: UpdaterWindowOptions): Promise<UpdaterWindow> {
6268
const userAgent = await generateUserArgent(store.appStore.appVersion)
63-
return new UpdaterWindow(userAgent)
69+
return new UpdaterWindow(userAgent, options)
6470
}
6571

6672
sendProgress(progress: UpdateProgress) {
@@ -77,6 +83,10 @@ export class UpdaterWindow extends (EventEmitter as new () => TypedEmitter<Updat
7783
this._win.close()
7884
}
7985

86+
show() {
87+
this._win.show()
88+
}
89+
8090
focus = () => this._win.focus()
8191
isMinimized = () => this._win.isMinimized()
8292
restore = () => this._win.restore()

0 commit comments

Comments
 (0)