어느날 갑자기 잘 사용하고 있던 electron 자동 업데이트 기능이 업데이트 설치 파일은 자동으로 다운로드 되지만 다운로드가 진행되지 않는 이슈가 발생했습니다. 원인을 찾아보니 아래와 같은 에러 로그가 있었습니다.
Error: sha512 checksum mismatch, expected qHWVkiLxXqYpJ/xQvwLgUqIVxlljwBr+N9xFgT8GTaJsVjrWocIEMO63TEM7E5UG3wE8GeG/wIsMbgtPEBVAJg==, got 8lnk8td5trgPjqosIM+wLl+YITL4FEjPGT3NXalIjBY+DY/bU1xAw94ljvyazzOryf0W78U5dAoZsguwRqrL4A==
간단하게 얘기해서 checksum이 맞지 않아서 자동으로 업데이트 되지 않는 오류입니다. checksum오류는 보통 빌드 시점에 생성된 파일과 배포된 파일에 변형이 있어 차이가 발생 했을 때 나타나는 오류입니다.
참고로 checksum은 빌드 후 latest.yml 기록되는 애플리케이션의 고유 값이라고 생각하시면 됩니다.
이전과 달라진 점이 code sign 방식 밖에 없어서 이부분을 집중적으로 확인해봤다.
과거
# cer.pxf 서명 파일 사용 시
react build -> electron-builder build & code sign 서명 -> gitHub draft 배포
현재
# signtool.exe 서명 시
react build -> electron-builder build -> code sign 서명 -> gitHub draft 배포
과거와 달라진 부분은 과거엔 electron-builder build가 실행 될 때 code sign을 동시에 진행하고 setup.exe 파일을 만들었다면, 지금은 setup.exe파일을 만들고 code sign을 진행하는 것이었습니다. 이렇게 바뀐 이유는 이전엔 cert.pxf 파일을 PC에 보관하고 환경변수로 인증서 파일을 설정한 후 빌드 명령어를 실행하면 자동으로 code sign을 했지만, 이제는 인증서를 발급하지 않고 SageNet 이라는 클라이언트 툴로 인증서를 관리하고 signtool.exe 이용해 커맨드로 code sign을 하는 방식으로 바뀌었습니다.
각자 개발 환경에 맞게 어플리케이션에 서명을 하겠지만 저랑 같은 방식으로 작업을 하실 분들이 있을까 하고 삽질하는 시간을 줄여드리고자 공유드립니다.
결론부터 빠르게 가자면 electron-builder 커맨드를 실행할 때 package.json에 afterSign 키로 빌드와 동시에 서명을 할 수 있습니다.
# package.json
"build":{
"afterSign": "after-sign-hook.js"
}
위와 같이 build > afterSign 키를 사용하면 윈도우 기준으로 electron-builder가 빌드를 하면서 win-unpack 폴더에 프로그램명.exe 를 생성하면서 exe파일이 완성되면 곧바로 서명을 진행해 설치파일이 빌드되기 전 서명이 완료되어 checksum이 latest.yml에 정상적으로 기록됩니다.
아래는 after-sign-hook.js파일이고 어려운 내용은 없으니 주석은 생략하고 코드만 첨부하겠습니다.
const { exec } = require('child_process');
const { dirname } = require('path');
const path = require('path');
exports.default = async function afterSign(context) {
const { appOutDir, electronPlatformName, packager } = context;
if (electronPlatformName !== 'win32') {
return;
}
const signToolPath = 'E:\\서명\\signtool.exe';
const sha1Thumbprint = 'sha1Thumbprint 값';
const exeFilePath = path.join(appOutDir, `${packager.appInfo.productFilename}.exe`);
const signCommand = `${signToolPath} sign /s my /sha1 ${sha1Thumbprint} /fd sha256 /tr http://timestamp.digicert.com /v "${exeFilePath}"`;
return new Promise((resolve, reject) => {
exec(signCommand, (error, stdout, stderr) => {
if (error) {
console.error(`Error signing: ${stderr}`);
reject(error);
} else {
console.log(`Signed ${exeFilePath}: ${stdout}`);
resolve();
}
});
});
};
조금이나마 삽질 시간 줄이시길 바래요!
'스터디-ing > Programming' 카테고리의 다른 글
[Javascript] Node.js와 Socket.IO를 활용한 채팅 서버 (0) | 2024.05.31 |
---|---|
[Java] Spring으로 S3 Signed URL 발급 받기 (0) | 2024.05.24 |
[Javascript] Google reCAPTCHA (0) | 2024.05.23 |
[Electron] 자동 업데이트 electron-updater(with Github) (0) | 2022.04.15 |