From 3483b4ef87eceb623b5cfc0bc1b715b09c49ba56 Mon Sep 17 00:00:00 2001 From: JeongUk Park Date: Sun, 6 Sep 2026 13:10:14 +0900 Subject: [PATCH 1/2] =?UTF-8?q?ci:=20=EC=84=9C=EB=AA=85=EC=9A=A9=20?= =?UTF-8?q?=ED=82=A4=EC=B2=B4=EC=9D=B8=EC=9D=84=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=EC=97=90=EC=84=9C=20=EC=A7=81=EC=A0=91=20?= =?UTF-8?q?=EB=A7=8C=EB=93=A0=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macos-latest 가 2026-08-28 자 이미지로 바뀐 뒤 mac 빌드가 서명 단계에서 실패한다. set-key-partition-list 가 키체인 비밀번호를 거부한다. electron-builder 가 자기 임시 키체인에 그 명령을 부를 때 키체인 자신의 비밀번호가 아닌 값을 넘기는 버그다. 예전 macOS 는 느슨하게 검사해 넘어갔고 새 이미지부터 거부한다. 수정은 upstream 에 들어갔으나 아직 npm 에 나오지 않았다. 키체인을 워크플로에서 직접 만들고 CSC_KEYCHAIN 으로 넘겨 그 경로를 타지 않게 한다. CSC_LINK 를 빌드 단계에서 빼야 electron-builder 가 다시 자기 키체인을 만들지 않는다. --- .github/workflows/release.yml | 49 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 88c070f..de438f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,16 +28,57 @@ jobs: APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY_CONTENT }} run: printf '%s' "$APPLE_API_KEY_CONTENT" > "$RUNNER_TEMP/AuthKey.p8" - - name: 빌드·서명·공증 후 draft 릴리스 업로드 + - name: 서명용 키체인 준비 env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} CSC_LINK: ${{ secrets.CSC_LINK }} CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} + run: | + set -euo pipefail + # electron-builder 가 스스로 만드는 키체인은 set-key-partition-list 에 키체인 비밀번호가 + # 아닌 값을 넘긴다(upstream #10101). 예전 macOS 는 그냥 넘어갔지만 2026-08-28 자 runner + # 이미지부터 거부한다. 키체인을 직접 만들어 그 경로를 타지 않게 한다 + KEYCHAIN="$RUNNER_TEMP/build.keychain-db" + KEYCHAIN_PASSWORD=$(openssl rand -base64 24) + + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN" + security set-keychain-settings -lut 21600 "$KEYCHAIN" + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN" + + printf '%s' "$CSC_LINK" | base64 --decode > "$RUNNER_TEMP/cert.p12" + security import "$RUNNER_TEMP/cert.p12" -k "$KEYCHAIN" -P "$CSC_KEY_PASSWORD" \ + -T /usr/bin/codesign + rm -f "$RUNNER_TEMP/cert.p12" + + # 여기서 넘기는 것이 키체인 자신의 비밀번호여야 한다 + security set-key-partition-list -S apple-tool:,apple:,codesign: \ + -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN" > /dev/null + + # codesign 이 찾을 수 있게 검색 목록에 넣는다. 기존 목록은 유지한다 + security list-keychains -d user -s "$KEYCHAIN" \ + $(security list-keychains -d user | sed 's/[" ]//g') + + # 인증서가 없으면 grep 이 실패한다. set -e 에 걸려 죽지 않게 받아서 직접 검사한다 + IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN" \ + | grep 'Developer ID Application' | head -1 | sed -E 's/.*"(.+)"$/\1/' || true) + if [ -z "$IDENTITY" ]; then + echo "::error::키체인에서 Developer ID Application 인증서를 찾지 못했다" + exit 1 + fi + + # CSC_LINK 를 그대로 두면 electron-builder 가 다시 자기 키체인을 만든다. 여기서 끊는다 + echo "CSC_KEYCHAIN=$KEYCHAIN" >> "$GITHUB_ENV" + echo "CSC_NAME=$IDENTITY" >> "$GITHUB_ENV" + + - name: 빌드·서명·공증 후 draft 릴리스 업로드 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} APPLE_API_KEY: ${{ runner.temp }}/AuthKey.p8 APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} run: npm run build:mac -- --publish always - - name: 공증용 API 키 정리 + - name: 자격증명 정리 if: always() - run: rm -f "$RUNNER_TEMP/AuthKey.p8" + run: | + rm -f "$RUNNER_TEMP/AuthKey.p8" "$RUNNER_TEMP/cert.p12" + security delete-keychain "$RUNNER_TEMP/build.keychain-db" 2>/dev/null || true From 307d593b0459d29c678b7bae8881a9588c7dc84e Mon Sep 17 00:00:00 2001 From: JeongUk Park Date: Sun, 6 Sep 2026 13:19:21 +0900 Subject: [PATCH 2/2] =?UTF-8?q?ci:=20=ED=82=A4=EC=B2=B4=EC=9D=B8=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EB=AA=A9=EB=A1=9D=EC=9D=84=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4=EB=A1=9C=20=EB=84=98=EA=B8=B4=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 목록을 명령 대체로 펼치면서 sed 로 공백까지 지웠다. 공백이 든 경로는 오히려 두 인자로 갈라진다. 줄 단위로 읽어 배열에 담고 따옴표째 넘긴다. --- .github/workflows/release.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de438f1..0780e28 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,9 +53,14 @@ jobs: security set-key-partition-list -S apple-tool:,apple:,codesign: \ -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN" > /dev/null - # codesign 이 찾을 수 있게 검색 목록에 넣는다. 기존 목록은 유지한다 - security list-keychains -d user -s "$KEYCHAIN" \ - $(security list-keychains -d user | sed 's/[" ]//g') + # codesign 이 찾을 수 있게 검색 목록에 넣는다. 기존 목록은 유지한다. + # 출력은 따옴표로 감싼 들여쓴 경로라, 공백이 든 경로도 깨지지 않게 줄 단위로 읽는다 + EXISTING=() + while IFS= read -r line; do + line=$(printf '%s' "$line" | sed -E 's/^[[:space:]]*"?//; s/"?[[:space:]]*$//') + if [ -n "$line" ]; then EXISTING+=("$line"); fi + done < <(security list-keychains -d user) + security list-keychains -d user -s "$KEYCHAIN" ${EXISTING[@]+"${EXISTING[@]}"} # 인증서가 없으면 grep 이 실패한다. set -e 에 걸려 죽지 않게 받아서 직접 검사한다 IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN" \