Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Sign build artifacts #71

Merged
merged 27 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c646527
add code signing for macOS and windows [ci skip]
infeo Nov 20, 2024
1df6c96
fix copy-paste-error [ci skip]
infeo Nov 20, 2024
d771f74
fix typo
infeo Nov 20, 2024
47e92cd
use unique id for cli project in macos entitlement [ci skip]
infeo Nov 20, 2024
9db4976
zip a tad different
infeo Nov 25, 2024
6ddc447
use same entitlements as desktop gui app
infeo Nov 25, 2024
253ee11
upload completely signed app
infeo Nov 25, 2024
eb150b1
add type for CI input [ci skip]
infeo Nov 25, 2024
8a2cb69
staple app dir, not zip file [ci skip]
infeo Nov 26, 2024
c62f99c
manually notarize app [ci skip]
infeo Nov 26, 2024
f144ecd
apply code signing from a different working directory
infeo Nov 26, 2024
e5c60a5
verify signing [ci skip]
infeo Nov 26, 2024
7a0a4b9
disable intel builds for now [ci skip]
infeo Nov 26, 2024
1b1f697
more verification
infeo Nov 26, 2024
a5a787e
use macos tool for zipping [ci skip]
infeo Nov 26, 2024
330a887
embed the source dir in the zip file
infeo Nov 26, 2024
2a5c970
remove debug commands
infeo Nov 26, 2024
046dc12
also on windows upload signed build [ci skip]
infeo Nov 26, 2024
5e5ec76
use correct option for ditto [ci skip]
infeo Nov 26, 2024
2a517ae
Merge branch 'develop' into feature/sign-build-artifacts
infeo Nov 26, 2024
8e5ae99
remove merge leftover
infeo Nov 26, 2024
6e4b453
add macos-13 runner again
infeo Nov 26, 2024
1d49324
make xcode path dependent on runner
infeo Nov 26, 2024
c2f147f
maybe quoting helps
infeo Nov 26, 2024
c6a5a2e
base64 is broken on macOS13 [ci skip]
infeo Nov 26, 2024
aa96f26
use correct xcode paths [ci skip]
infeo Nov 26, 2024
0e3a8f1
place sha1 of windows cert in repository variable [ci skip]
infeo Nov 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 121 additions & 11 deletions .github/workflows/build-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
sem-version:
description: 'Version'
required: false
notarize:
description: 'Notarize app'
required: false
type: boolean

permissions:
contents: write
Expand All @@ -28,7 +32,11 @@ jobs:
outputs:
semVerStr: ${{ steps.determine-version.outputs.version }}
semVerNum: ${{steps.determine-number.outputs.number}}
revisionNum: ${{steps.determine-number.outputs.revision}}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: determine-version
shell: pwsh
run: |
Expand All @@ -45,6 +53,8 @@ jobs:
run: |
SEM_VER_NUM=$(echo "${{ steps.determine-version.outputs.version }}" | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
echo "number=${SEM_VER_NUM}" >> "$GITHUB_OUTPUT"
REVISION_NUM=`git rev-list --count HEAD`
echo "revision=${REVISION_NUM}" >> "$GITHUB_OUTPUT"

build-binary:
name: Build java app image
Expand All @@ -56,9 +66,11 @@ jobs:
- os: macos-latest
architecture: arm64
artifact-name: cryptomator-cli-${{ needs.prepare.outputs.semVerStr }}-mac-arm64.zip
xcode-path: /Applications/Xcode_16.app
- os: macos-13
architecture: x64
artifact-name: cryptomator-cli-${{ needs.prepare.outputs.semVerStr }}-mac-x64.zip
xcode-path: /Applications/Xcode_15.2.app
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -86,22 +98,121 @@ jobs:
JP_APP_VERSION: ${{ needs.prepare.outputs.semVerNum }}
APP_VERSION: ${{ needs.prepare.outputs.semVerStr }}
NATIVE_ACCESS_PACKAGE: org.cryptomator.jfuse.mac
- uses: actions/upload-artifact@v4
with:
name: cryptomator-cli-mac-${{ matrix.architecture }}
path: ./target/cryptomator-cli.app
if-no-files-found: error
- name: TODO sign binaries
run: echo "TODO sign it and notarize it"
- name: Zip binary for release
run: zip -r ./${{ matrix.artifact-name}} ./target/cryptomator-cli.app
- name: Patch .app dir
run: |
sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" cryptomator-cli.app/Contents/Info.plist
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" cryptomator-cli.app/Contents/Info.plist
echo -n "$PROVISIONING_PROFILE_BASE64" | base64 --decode -o "cryptomator-cli.app/Contents/embedded.provisionprofile"
working-directory: target
env:
VERSION_NO: ${{ needs.prepare.outputs.semVerNum }}
REVISION_NO: ${{ needs.prepare.outputs.revisionNum }}
PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }}
- name: Install codesign certificate
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/codesign.p12
KEYCHAIN_PATH=$RUNNER_TEMP/codesign.keychain-db

# import certificate and provisioning profile from secrets
echo -n "$CODESIGN_P12_BASE64" | base64 --decode -o $CERTIFICATE_PATH

# create temporary keychain
security create-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
security set-keychain-settings -lut 900 $KEYCHAIN_PATH
security unlock-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH

# import certificate to keychain
security import $CERTIFICATE_PATH -P "$CODESIGN_P12_PW" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
env:
CODESIGN_P12_BASE64: ${{ secrets.MACOS_CODESIGN_P12_BASE64 }}
CODESIGN_P12_PW: ${{ secrets.MACOS_CODESIGN_P12_PW }}
CODESIGN_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_CODESIGN_TMP_KEYCHAIN_PW }}
infeo marked this conversation as resolved.
Show resolved Hide resolved
- name: Codesign
run: |
echo "Codesigning jdk files..."
find cryptomator-cli.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
find cryptomator-cli.app/Contents/runtime/Contents/Home/lib/ \( -name 'jspawnhelper' -o -name 'pauseengine' -o -name 'simengine' \) -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \;
echo "Codesigning jar contents..."
find cryptomator-cli.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
for JAR_PATH in `find cryptomator-cli.app -name "*.jar"`; do
if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
JAR_FILENAME=$(basename ${JAR_PATH})
OUTPUT_PATH=${JAR_PATH%.*}
echo "Codesigning libs in ${JAR_FILENAME}..."
unzip -q ${JAR_PATH} -d ${OUTPUT_PATH}
find ${OUTPUT_PATH} -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
find ${OUTPUT_PATH} -name '*.jnilib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
rm ${JAR_PATH}
pushd ${OUTPUT_PATH} > /dev/null
zip -qr ../${JAR_FILENAME} *
popd > /dev/null
rm -r ${OUTPUT_PATH}
fi
done
echo "Codesigning Cryptomator-cli.app..."
sed -i '' "s|###APP_IDENTIFIER_PREFIX###|${TEAM_IDENTIFIER}.|g" ../dist/mac/cryptomator-cli.entitlements
sed -i '' "s|###TEAM_IDENTIFIER###|${TEAM_IDENTIFIER}|g" ../dist/mac/cryptomator-cli.entitlements
codesign --force --deep --entitlements ../dist/mac/cryptomator-cli.entitlements -o runtime -s ${CODESIGN_IDENTITY} cryptomator-cli.app
env:
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
TEAM_IDENTIFIER: ${{ secrets.MACOS_TEAM_IDENTIFIER }}
working-directory: target
# ditto must be used, see https://developer.apple.com/documentation/xcode/packaging-mac-software-for-distribution#Build-a-zip-archive
infeo marked this conversation as resolved.
Show resolved Hide resolved
- name: Zip binary for notarization
if: inputs.notarize
run: ditto -c -k --keepParent ./target/cryptomator-cli.app ./${{ matrix.artifact-name}}
- name: Setup Xcode
if: inputs.notarize
run: sudo xcode-select -s ${{ matrix.xcode-path}}
shell: bash
#would like to uses cocoalibs/xcode-notarization-action@v1, but blocked due to https://github.com/cocoalibs/xcode-notarization-action/issues/1
- name: Prepare Notarization Credentials
if: inputs.notarize
run: |
# create temporary keychain
KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
KEYCHAIN_PASS=$(uuidgen)
security create-keychain -p "${KEYCHAIN_PASS}" ${KEYCHAIN_PATH}
security set-keychain-settings -lut 900 ${KEYCHAIN_PATH}
security unlock-keychain -p "${KEYCHAIN_PASS}" ${KEYCHAIN_PATH}
# import credentials from secrets
xcrun notarytool store-credentials "notary" --apple-id "${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}" --password "${{ secrets.MACOS_NOTARIZATION_PW }}" --team-id "${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}" --keychain "${KEYCHAIN_PATH}"
shell: bash
- name: Notarize
if: inputs.notarize
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
xcrun notarytool submit ${{ matrix.artifact-name }} --keychain-profile "notary" --keychain "${KEYCHAIN_PATH}" --wait
shell: bash
- name: Staple
if: inputs.notarize
run: xcrun stapler staple ./target/cryptomator-cli.app
shell: bash
- name: Cleanup
if: ${{ always() }}
run: |
rm -f ./${{ matrix.artifact-name}}
security delete-keychain $RUNNER_TEMP/notarization.keychain-db
shell: bash
continue-on-error: true
- name: Zip app for distribution
run: ditto -c -k --keepParent ./target/cryptomator-cli.app ./${{ matrix.artifact-name}}
- name: Create detached GPG signature with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a ./${{ matrix.artifact-name }}
env:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- uses: actions/upload-artifact@v4
with:
name: cryptomator-cli-mac-${{ matrix.architecture }}
path: |
${{ matrix.artifact-name}}
*.asc
if-no-files-found: error
- name: Publish artefact on GitHub Releases
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
uses: softprops/action-gh-release@v2
Expand All @@ -110,5 +221,4 @@ jobs:
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
files: |
${{ matrix.artifact-name }}
cryptomator-cli-*.asc

cryptomator-cli-*.asc
56 changes: 50 additions & 6 deletions .github/workflows/build-win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,50 @@ jobs:
JP_APP_VERSION: ${{ needs.prepare.outputs.semVerNum }}
APP_VERSION: ${{ needs.prepare.outputs.semVerStr }}
NATIVE_ACCESS_PACKAGE: org.cryptomator.jfuse.win
- uses: actions/upload-artifact@v4
- name: Fix permissions
run: attrib -r target/cryptomator-cli/cryptomator-cli.exe
shell: pwsh
- name: Extract jars with DLLs for Codesigning
shell: pwsh
run: |
Add-Type -AssemblyName "System.io.compression.filesystem"
$jarFolder = Resolve-Path ".\target\Cryptomator-cli\app\mods"
$jarExtractDir = New-Item -Path ".\target\jar-extract" -ItemType Directory

#for all jars inspect
Get-ChildItem -Path $jarFolder -Filter "*.jar" | ForEach-Object {
$jar = [Io.compression.zipfile]::OpenRead($_.FullName)
if (@($jar.Entries | Where-Object {$_.Name.ToString().EndsWith(".dll")} | Select-Object -First 1).Count -gt 0) {
#jars containing dlls extract
Set-Location $jarExtractDir
Expand-Archive -Path $_.FullName
}
$jar.Dispose()
}
- name: Codesign
uses: skymatic/code-sign-action@v3
with:
name: cryptomator-cli-win-x64
path: ./target/cryptomator-cli
if-no-files-found: error
- name: TODO Sign binaries
run: echo TODO
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: ${{ vars.WIN_CODESIGN_CERT_SHA1 }}
description: Cryptomator
timestampUrl: 'http://timestamp.digicert.com'
folder: target
recursive: true
- name: Replace DLLs inside jars with signed ones
shell: pwsh
run: |
$jarExtractDir = Resolve-Path ".\target\jar-extract"
$jarFolder = Resolve-Path ".\target\cryptomator-cli\app\mods"
Get-ChildItem -Path $jarExtractDir | ForEach-Object {
$jarName = $_.Name
$jarFile = "${jarFolder}\${jarName}.jar"
Set-Location $_
Get-ChildItem -Path $_ -Recurse -File "*.dll" | ForEach-Object {
# update jar with signed dll
jar --file="$jarFile" --update $(Resolve-Path -Relative -Path $_)
}
}
infeo marked this conversation as resolved.
Show resolved Hide resolved
- name: Zip binary for release
shell: pwsh
run: Compress-Archive -Path .\target\cryptomator-cli -DestinationPath .\${{ env.artifact-name}}
Expand All @@ -95,6 +132,13 @@ jobs:
env:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- uses: actions/upload-artifact@v4
with:
name: cryptomator-cli-win-x64
path: |
${{ env.artifact-name}}
*.asc
if-no-files-found: error
- name: Publish artefact on GitHub Releases
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
uses: softprops/action-gh-release@v2
Expand Down
18 changes: 18 additions & 0 deletions dist/mac/cryptomator-cli.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.application-identifier</key>
<string>###APP_IDENTIFIER_PREFIX###org.cryptomator.cli</string>
<key>com.apple.developer.team-identifier</key>
<string>###TEAM_IDENTIFIER###</string>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>