Electron 자동 업데이트 구현 삽질기 — electron-updater의 함정들
업데이트가 무한 루프 빠진 거 인지하는 데 3일 걸렸다. 사용자 컴퓨터는 계속 재부팅을 반복하고 있었다.
Setup: electron-updater 기본
npm install electron-updater
main.ts:
import { autoUpdater } from 'electron-updater';
app.on('ready', () => {
autoUpdater.checkForUpdatesAndNotify();
// ← 이 한 줄로 끝이라고 생각했다
});
package.json:
{
"name": "my-app",
"version": "1.0.0",
"build": {
"publish": {
"provider": "github", // 또는 "s3"
"owner": "myname",
"repo": "my-app"
}
}
}
문제 1: Code Signing 필수
업데이트가 검증되지 않으면 설치되지 않는다.
Mac에서:
// package.json build config
"build": {
"mac": {
"certificateFile": "path/to/certificate.p12",
"certificatePassword": "password"
}
}
Windows에서:
// package.json "build": { "win": { "certificateFile": "path/to/certificate.pfx", "certificatePassword": "password" } }없으면:
Error: Code sign failed. Signing certificate not found. Unable to find a matching code signing certificate.
해결: Windows에서는 자체 서명 인증서로 테스트 가능:
// electron-builder는 자체 서명 인증서 생성 // 개발 중에는 코드 서명 건너뛰기 "build": { "win": { "sign": false // ← 개발 중에만 } }문제 2: 무한 업데이트 루프
우리의 경우:
버전 1.0.0 설치됨
자동 업데이트 체크 → 새 버전 1.0.1 있음
1.0.1 설치 및 재부팅
다시 시작된 앱이 자동 업데이트 체크 → 1.0.1이 이미 설치됨, 아무것도 안 함 (OK)
하지만 우리 경우:
계속 1.0.1을 "새 버전"으로 인식 → 무한 루프원인: GitHub release가 잘못 설정됨
electron-updater는 다음을 읽음:
https://api.github.com/repos/myname/my-app/releases/latest이 응답에서 "latest" release를 찾는다.
해결: GitHub에서 release를 "Latest Release"로 마크:
// GitHub UI Release tab → Edit → "Set as the latest release" 체크문제 3: Differential Updates가 안 됨
differential update는 변경된 부분만 다운로드하는 기능이다 (100MB → 5MB)
작동하려면:
1. 이전 버전의 .exe 또는 .app이 존재해야 함
2. GitHub release에 최소 2개 이상의 버전이 있어야 함
3. electron-builder가 자동으로 delta 파일 생성해야 함github.yml (GitHub Actions):
name: CI on: push: tags: - 'v*' jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm install - run: npm run build:electron - uses: softprops/action-gh-release@v1 with: files: | dist/my-app-*.exe dist/my-app-*.dmg dist/*.blockmap # ← Delta 정보 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}중요: dist/*.blockmap을 GitHub release에 업로드해야 delta update가 작동한다.
문제 4: S3 호스팅
GitHub 용량 제한 (100MB 이상 안 됨)이 있으면 S3 사용:
// package.json "build": { "publish": { "provider": "s3", "bucket": "my-app-releases", "region": "us-east-1" } }AWS IAM 정책:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::my-app-releases/*" } ] }환경변수:
export AWS_ACCESS_KEY_ID=xxx export AWS_SECRET_ACCESS_KEY=xxx npm run build:electron // ← S3에 자동 업로드문제 5: 업데이트 UI
단순한 자동 업데이트는 사용자가 모른다.
좋은 UX:
import { autoUpdater } from 'electron-updater'; autoUpdater.on('checking-for-update', () => { mainWindow.webContents.send('update-status', '업데이트 확인 중...'); }); autoUpdater.on('update-available', () => { mainWindow.webContents.send('update-status', '새 버전 다운로드 중...'); }); autoUpdater.on('update-downloaded', () => { dialog.showMessageBox(mainWindow, { type: 'info', title: '업데이트 준비 완료', message: '앱을 다시 시작하여 업데이트를 적용합니다.', buttons: ['지금 다시 시작', '나중에'] }).then(result => { if (result.response === 0) { autoUpdater.quitAndInstall(); } }); }); autoUpdater.on('error', (error) => { mainWindow.webContents.send('update-error', error.message); }); // 1시간마다 체크 setInterval(() => { autoUpdater.checkForUpdates(); }, 1000 * 60 * 60);배포 체크리스트
□ package.json 버전 업데이트 (예: 1.0.0 → 1.0.1)
□ 코드 서명 인증서 준비
□ npm run build:electron 실행
□ dist/ 폴더에 .exe/.dmg/.blockmap 생성 확인
□ GitHub release 생성 및 파일 업로드
□ "Set as latest release" 체크
□ 이전 버전 앱에서 업데이트 테스트
□ 모니터링 (업데이트 성공률)결론
electron-updater는 강력하지만 함정이 많다. 특히 code signing과 delta update 설정이 중요하다.
우리는 이 경험 후 모든 업데이트를 다음 버전부터 자동화했다:
- Git tag 푸시 → GitHub Actions 자동 빌드 및 배포
- release-it 도구로 버전/changelog 자동 관리
- 모니터링: 업데이트 성공/실패율 추적
이제 업데이트는 안정적이다. 그리고 사용자는 자동으로 최신 버전을 받는다.