Skip to content

IEP-1475: Signing Windows Executable #25

IEP-1475: Signing Windows Executable

IEP-1475: Signing Windows Executable #25

name: Espressif-IDE Cross-platform Release
on:
push:
branches: [master]
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
pull_request:
branches: [master]
env:
ARCHIVE_PREFIX: com.espressif.idf.update-
ARCHIVE_SUFFIX: -SNAPSHOT.zip
jobs:
macos-build:
runs-on: macos-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Get version from tag
id: get_version
run: echo "version=${GITHUB_REF##*/v}" >> $GITHUB_OUTPUT
- name: Decode keystore and build with Maven
env:
JARSIGNER_KEYSTORE_B64: ${{ secrets.JARSIGNER_REL_KEYSTORE_B64 }}
JARSIGNER_STOREPASS: ${{ secrets.JARSIGNER_REL_STOREPASS }}
JARSIGNER_ALIAS: ${{ secrets.JARSIGNER_REL_ALIAS }}
run: |
KEYSTORE_FILE="${PWD}/{{secrets.JARSIGNER_KEYSTORE}}"
echo "${KEYSTORE_FILE}"
printf "%s" "${JARSIGNER_KEYSTORE_B64}" | base64 -d > "${KEYSTORE_FILE}"
mvn -e -X clean install -Djarsigner.keystore="${KEYSTORE_FILE}" -Djarsigner.alias="${JARSIGNER_ALIAS}" -Djarsigner.storepass="${JARSIGNER_STOREPASS}" -DskipTests=true
rm -v "${KEYSTORE_FILE}"
- name: Codesign Espressif-IDE
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
run: |
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
/usr/bin/security create-keychain -p espressif build.keychain
/usr/bin/security default-keychain -s build.keychain
/usr/bin/security unlock-keychain -p espressif build.keychain
/usr/bin/security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
/usr/bin/security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k espressif build.keychain
echo "codesigning espressif-ide-macosx.cocoa.x86_64"
/usr/bin/codesign --entitlements $PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" $PWD/releng/com.espressif.idf.product/target/products/com.espressif.idf.product/macosx/cocoa/x86_64/Espressif-IDE.app -v
/usr/bin/codesign -v -vvv --deep $PWD/releng/com.espressif.idf.product/target/products/com.espressif.idf.product/macosx/cocoa/x86_64/Espressif-IDE.app
echo "codesigning espressif-ide-macosx.cocoa.aarch64"
/usr/bin/codesign --entitlements $PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" $PWD/releng/com.espressif.idf.product/target/products/com.espressif.idf.product/macosx/cocoa/aarch64/Espressif-IDE.app -v
/usr/bin/codesign -v -vvv --deep $PWD/releng/com.espressif.idf.product/target/products/com.espressif.idf.product/macosx/cocoa/aarch64/Espressif-IDE.app
echo "Creating dmg for espressif-ide-macosx.cocoa.x86_64"
$PWD/releng/ide-dmg-builder/ide-dmg-builder.sh
/usr/bin/codesign --entitlements $PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-x86_64.dmg -v
/usr/bin/codesign -v -vvv --deep $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-x86_64.dmg
echo "Creating dmg for espressif-ide-macosx.cocoa.aarch64"
$PWD/releng/ide-dmg-builder/ide-dmg-builder-aarch64.sh
/usr/bin/codesign --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-aarch64.dmg -v
/usr/bin/codesign -v -vvv --deep $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-aarch64.dmg
- name: Notarization of Espressif-IDE dmg files
env:
NOTARIZATION_USERNAME: ${{ secrets.NOTARIZATION_USERNAME }}
NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }}
NOTARIZATION_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }}
run: |
echo "Create notary keychain"
/usr/bin/security create-keychain -p espressif notary.keychain
/usr/bin/security default-keychain -s notary.keychain
/usr/bin/security unlock-keychain -p espressif notary.keychain
echo "Create keychain profile"
xcrun notarytool store-credentials "ide-notarytool-profile" --apple-id $NOTARIZATION_USERNAME --team-id $NOTARIZATION_TEAM_ID --password $NOTARIZATION_PASSWORD
xcrun notarytool submit $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-x86_64.dmg --keychain-profile "ide-notarytool-profile" --wait
echo "Attach staple for x86_64.dmg"
xcrun stapler staple $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-x86_64.dmg
echo "Unlock the notary keychain"
/usr/bin/security unlock-keychain -p espressif notary.keychain
xcrun notarytool submit $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-aarch64.dmg --keychain-profile "ide-notarytool-profile" --wait
echo "Attach staple for aarch64.dmg"
xcrun stapler staple $PWD/releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-aarch64.dmg
- name: Upload Espressif-IDE-macosx-cocoa-x86_64.dmg
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: espressif-ide-macosx-cocoa-x86_64
path: releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-x86_64.dmg
- name: Upload Espressif-IDE-macosx-cocoa-aarch64.dmg
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: espressif-ide-macosx.cocoa.aarch64
path: releng/ide-dmg-builder/Espressif-IDE-macosx-cocoa-aarch64.dmg
- name: Upload build artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: com.espressif.idf.update
path: releng/com.espressif.idf.update/target/repository
- name: Upload windows rcp
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: espressif-ide-win32
path: releng/com.espressif.idf.product/target/products/Espressif-IDE-*-win32.win32.x86_64.zip
- name: Upload linux rcp
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: espressif-ide-linux
path: releng/com.espressif.idf.product/target/products/Espressif-IDE-*-linux.gtk.x86_64.tar.gz
windows-sign:
runs-on: windows-latest
needs: macos-build
env:
JKS_B64: ${{ secrets.JARSIGNER_REL_KEYSTORE_B64 }}
JKS_PASS: ${{ secrets.JARSIGNER_REL_STOREPASS }}
ALIAS: ${{ secrets.JARSIGNER_REL_ALIAS }}
PFX_PASS: ${{ secrets.JARSIGNER_REL_STOREPASS }}
steps:
- uses: actions/checkout@v3
- name: Download built artifacts
uses: actions/download-artifact@v4
with:
name: espressif-ide-win32
path: artifacts
- name: Verify the downloaded file
shell: pwsh
run: |
ls .\artifacts\*
- name: Extract Windows ZIP
shell: pwsh
run: |
Expand-Archive -Path artifacts\*.zip -DestinationPath extracted -Force
ls .\artifacts\*
- name: Decode base64-encoded JKS
run: |
echo "$env:JKS_B64" | Out-File -FilePath encoded.b64 -Encoding ASCII
certutil -decode encoded.b64 mykeystore.jks
Remove-Item encoded.b64
- name: Convert JKS to PFX
shell: pwsh
run: |
& "${env:JAVA_HOME}\bin\keytool.exe" -importkeystore `
-srckeystore mykeystore.jks `
-srcstorepass $env:JKS_PASS `
-srcalias $env:ALIAS `
-destkeystore cert.pfx `
-deststoretype PKCS12 `
-deststorepass $env:PFX_PASS
- name: Sign Windows Executable
shell: pwsh
run: |
$exe = Get-ChildItem -Recurse extracted\Espressif-IDE\espressif-ide.exe | Select-Object -First 1
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\signtool.exe" sign `
/f cert.pfx `
/p $env:PFX_PASS `
/tr http://timestamp.digicert.com `
/td sha256 `
/fd sha256 `
$exe.FullName
- name: Verify Signature
run: |
$exe = Get-ChildItem -Recurse extracted\Espressif-IDE\espressif-ide.exe | Select-Object -First 1
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\signtool.exe" verify `
/pa `
$exe.FullName
- name: Removing original ZIP from extracted folder
run: |
Remove-Item -Force artifacts\*.zip
- name: Delete the unsigned Binary
uses: geekyeggo/delete-artifact@v5
with:
name: espressif-ide-win32
failOnError: false
- name: Upload Signed Windows ZIP
uses: actions/upload-artifact@v4
with:
name: espressif-ide-win32
path: extracted/
overwrite: true
if-no-files-found: error
upload-aws:
runs-on: macos-latest
needs: windows-sign
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
steps:
- uses: actions/checkout@v3
- name: Download built windows artifact
uses: actions/download-artifact@v4
with:
name: espressif-ide-win32
path: artifacts
- name: Download built linux artifact
uses: actions/download-artifact@v4
with:
name: espressif-ide-linux
path: artifacts
- name: Download macOS x86_64 dmg zip
uses: actions/download-artifact@v4
with:
name: espressif-ide-macosx-cocoa-x86_64
path: artifacts/macos_x86
- name: Download macOS aarch64 dmg zip
uses: actions/download-artifact@v4
with:
name: espressif-ide-macosx.cocoa.aarch64
path: artifacts/macos_arm
- name: Download update site zip
uses: actions/download-artifact@v4
with:
name: com.espressif.idf.update
path: artifacts
- name: Extract macOS x86_64 dmg
run: unzip -q artifacts/macos_x86/*.zip -d artifacts/macos_x86
- name: Extract macOS aarch64 dmg
run: unzip -q artifacts/macos_arm/*.zip -d artifacts/macos_arm
- name: Extract linux zip (keep internal .tar.gz intact)
run: unzip -q artifacts/*.zip -d artifacts/linux
- name: Determine version and prepare folder
run: |
ZIP_FILE=$(find artifacts -name "com.espressif.idf.update-*.zip")
ARCHIVE_PREFIX="com.espressif.idf.update-"
ARCHIVE_SUFFIX="-SNAPSHOT.zip"
tmp=${ZIP_FILE##*${ARCHIVE_PREFIX}}
VERSION=${tmp%${ARCHIVE_SUFFIX}*}
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "FOLDER=v${VERSION}" >> $GITHUB_ENV
- name: Rename DMGs with version suffix
run: |
mv artifacts/macos_x86/Espressif-IDE-macosx-cocoa-x86_64.dmg artifacts/macos_x86/Espressif-IDE-macosx-cocoa-x86_64-v${VERSION}.dmg
mv artifacts/macos_arm/Espressif-IDE-macosx-cocoa-aarch64.dmg artifacts/macos_arm/Espressif-IDE-macosx-cocoa-aarch64-v${VERSION}.dmg
- name: Upload build assets to dl.espressif.com
run: |
aws s3 rm s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin-test/updates/latest --recursive
aws s3 cp --acl=public-read --recursive artifacts/linux/ s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin-test/updates/latest
aws s3 cp --acl=public-read ./releng/index.html s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin-test/updates/latest/
aws s3 cp --acl=public-read --recursive artifacts/linux/ s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin-test/updates/v${VERSION}
aws s3 cp --acl=public-read artifacts/com.espressif.idf.update-*.zip s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin-test/updates/
aws s3 cp --acl=public-read artifacts/macos_x86/Espressif-IDE-macosx-cocoa-x86_64-v${VERSION}.dmg s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin-test/ide/
aws s3 cp --acl=public-read artifacts/macos_arm/Espressif-IDE-macosx-cocoa-aarch64-v${VERSION}.dmg s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin-test/ide/
aws s3 cp --acl=public-read artifacts/Espressif-IDE-win32.win32.x86_64.zip s3://${{ secrets.DL_BUCKET }}/dl/idf-eclipse-plugin/ide/
aws cloudfront create-invalidation --distribution-id ${{ secrets.DL_DISTRIBUTION_ID }} --paths "/dl/idf-eclipse-plugin-test/updates/latest/*"
aws s3api put-object --acl=public-read --bucket espdldata --key "dl/idf-eclipse-plugin-test/ide/Espressif-IDE-win32.win32.x86_64/latest" --website-redirect-location "/dl/idf-eclipse-plugin-test/ide/Espressif-IDE-${VERSION}-win32.win32.x86_64.zip"
aws s3api put-object --acl=public-read --bucket espdldata --key "dl/idf-eclipse-plugin-test/ide/Espressif-IDE-macosx-cocoa-x86_64/latest" --website-redirect-location "/dl/idf-eclipse-plugin-test/ide/Espressif-IDE-macosx-cocoa-x86_64-v${VERSION}.dmg"
aws s3api put-object --acl=public-read --bucket espdldata --key "dl/idf-eclipse-plugin-test/ide/Espressif-IDE-macosx-cocoa-aarch64/latest" --website-redirect-location "/dl/idf-eclipse-plugin-test/ide/Espressif-IDE-macosx-cocoa-aarch64-v${VERSION}.dmg"
aws s3api put-object --acl=public-read --bucket espdldata --key "dl/idf-eclipse-plugin-test/ide/Espressif-IDE-linux.gtk.x86_64/latest" --website-redirect-location "/dl/idf-eclipse-plugin-test/ide/Espressif-IDE-${VERSION}-linux.gtk.x86_64.tar.gz"