본문으로 바로가기

[Electron] electron 자동 업데이트

category 공유/Electron 2022. 3. 23. 06:59

[Electron] electron 자동 업데이트

electron의 장점 중 하나는 자동 업데이트를 할 수 있다는 것입니다. electron-updater package를 사용하면 됩니다. 자세하게 알아보도록 하겠습니다.

electron 자동 업데이트

우선 electron-updater package를 설치해주어야 합니다.

설치 명령어 : yarn add -D electron-updater

그리고 자동 업데이트를 하는 중 아무 표시가 되지 않으면 사용자는 모르기 때문에 progressbar를 띄워주도록 합니다. electron-progressbar package를 이용하면 됩니다.

설치 명령어 : yarn add -D electron-progressbar

electron.js 코드를 수정해주어야 합니다. 아래 코드처럼 수정해줍시다.

const { app, BrowserWindow, ipcMain, dialog } = require("electron");
const isDev = require("electron-is-dev");
const path = require("path");
const { autoUpdater } = require("electron-updater");
const ProgressBar = require("electron-progressbar");

let mainWindow = null;
let progressBar = null;

const createWindow = () => {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 640,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      devTools: isDev,
      preload: path.join(__dirname, "preload.js")
    }
  });

  mainWindow.loadURL(
    isDev
      ? "http://localhost:3000"
      : `file://${path.join(__dirname, "../build/index.html")}`
  );

  if (isDev) {
    mainWindow.webContents.openDevTools({ mode: "detach" });
  }

  // mainWindow.setResizable(false);
  mainWindow.setResizable(true);
  mainWindow.on("closed", () => (mainWindow = null));
  mainWindow.focus();
};

ipcMain.on("app_version", event => {
  event.reply("app_version", { version: app.getVersion() });
});

ipcMain.on("files", async event => {
  const result = await dialog
    .showOpenDialog(null, {
      filters: [
        {
          name: "Images",
          extensions: ["jpg", "png"]
        }
      ],
      properties: ["openFile", "multiSelections"]
    })
    .then(result => {
      const { canceled, filePaths } = result;

      if (canceled) return [];
      return filePaths;
    })
    .catch(err => {
      console.log(err);
      return [];
    });

  event.reply("files", { files: result });
});

// 자동으로 업데이트가 되는 것 방지
autoUpdater.autoDownload = false;

autoUpdater.on("checking-for-update", () => {
  console.log("업데이트 확인 중");
});

autoUpdater.on("update-available", () => {
  console.log("업데이트 버전 확인");

  dialog
    .showMessageBox({
      type: "info",
      title: "Update",
      message:
        "새로운 버전이 확인되었습니다. 설치 파일을 다운로드 하시겠습니까?",
      buttons: ["지금 설치", "나중에 설치"]
    })
    .then(result => {
      const { response } = result;

      if (response === 0) autoUpdater.downloadUpdate();
    });
});

autoUpdater.on("update-not-available", () => {
  console.log("업데이트 불가");
});

autoUpdater.once("download-progress", () => {
  console.log("설치 중");

  progressBar = new ProgressBar({
    text: "Download 합니다."
  });

  progressBar
    .on("completed", () => {
      console.log("설치 완료");
    })
    .on("aborted", () => {
      console.log("aborted");
    });
});

autoUpdater.on("update-downloaded", () => {
  console.log("업데이트 완료");

  progressBar.setCompleted();

  dialog
    .showMessageBox({
      type: "info",
      title: "Update",
      message: "새로운 버전이 다운로드 되었습니다. 다시 시작하시겠습니까?",
      buttons: ["예", "아니오"]
    })
    .then(result => {
      const { response } = result;

      if (response === 0) autoUpdater.quitAndInstall(false, true);
    });
});

// electron이 초기화 끝났을 때
app.on("ready", () => {
  createWindow();
  autoUpdater.checkForUpdates();
});

// 모든 window가 종료되었을 때
app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

// app이 활성화 되었을 때
app.on("activate", () => {
  if (!mainWindow) {
    createWindow();
  }
});

자동 업데이트 코드에 대해 알아보도록 합시다.

◆ 자동 업데이트 방지

- autoUpdater.autoDownload = false;

위 코드를 추가하지 않으면 자동으로 최신 버전이 다운로드 되기 때문에 수동으로 하기 위하여 추가해주었습니다.

◆ autoUpdater 이벤트

checking-for-update : 업데이트 가능한 지 체크

update-available : 업데이트 가능한 경우

update-not-available : 업데이트 불가능한 경우

download-progress : 최신 버전 다운로드 중

update-downloaded : 최신 버전 다운로드 완료

위 이벤트를 잘 이용하면 됩니다. download-progress 이벤트는 once를 사용하였는데 처음 이벤트만 받기 위해서 입니다. 만약 다른 이벤트처럼 on을 사용하면 중간 중간 계속해서 이벤트가 발생하기 때문에 사용자에게 다운로드 중을 알 수 있게 보여주는 progressBar가 계속 표시될 것입니다. 직접 한번 해보시길 바랍니다.

 

특정 이벤트마다 dialog를 사용하여 사용자에게 예, 아니오를 선택할 수 있게하고 다음 이벤트를 진행하도록 하였습니다.

◆ update 확인 요청

electron 초기화가 끝난 경우 autoUpdater.checkForUpdates() 함수를 호출 하여 최신 버전이 있는 지 확인 요청합니다. 만약 호출하였는데

autoUpdater.autoDownload = false;

위 값을 설정하지 않았다면 중간 예, 아니오 dialog가 표시되어도 선택 유무에 상관없이 다운로드 될 것입니다.

◆ package.json script 추가

release 할 script를 추가해야합니다.

"scripts": {
	...
	"release": "yarn build:react && set GH_TOKEN={github_token} && electron-builder"
}

필자는 window에서만 테스트 해보아서 위처럼 하였습니다. GH_TOKEN환경 변수에 넣어서 사용하셔도 됩니다. 예시 script는 아래와 같습니다.

yarn build:react && set GH_TOKEN=asdjqklwjdlkajslkdjklw && electron-builder

electron 자동 업데이트 해보기

위 작성한 script로 release를 하면 됩니다. 그리고 package.json에 있는 version 정보를 수정하며 versioning을 하면 됩니다.

release 명령어 : yarn release

위 명령어를 이용하면 해당 github repo에 release draft가 됩니다.

수정을 클릭한 후 release를 하시면 됩니다.

그럼 아래와 같이 최종 release가 됩니다.

package.json의 version을 변경 후 다시 release 를 하면 다음 버전이 생성됩니다. 그럼 이전에 설치해둔 app을 실행하면 최신 버전이 확인되어 업데이트할 것인지 물어봅니다. (즉, 위 작성한 코드 실행) 아래 결과를 확인해봅시다. (최신 버전 0.1.3 가정)

위 결과를 보면 알 수 있듯이 중간 과정 모두 예 하면 정상적으로 최신 버전이 다운로드 되고 설치가 됩니다.

 

이번 게시글에서는 자동 업데이트를 하는 방법을 알아보았습니다.

 

참고자료

 

마지막

해당 내용은 틀릴 수도 있습니다. 틀린 내용이 있으면 조언 부탁드립니다.

반응형