1+ name : Java app image macOS
2+
3+ on :
4+ release :
5+ types : [published]
6+ workflow_dispatch :
7+ inputs :
8+ sem-version :
9+ description : ' Version'
10+ required : true
11+ notarize :
12+ description : ' Notarize app'
13+ required : false
14+ type : boolean
15+
16+ permissions :
17+ contents : write
18+
19+ env :
20+ JAVA_DIST : ' zulu'
21+ JAVA_VERSION : ' 23.0.1+11'
22+
23+ defaults :
24+ run :
25+ shell : bash
26+
27+ jobs :
28+ prepare :
29+ name : Determines the versions strings for the binaries
30+ runs-on : [ubuntu-latest]
31+ outputs :
32+ semVerStr : ${{ steps.determine-version.outputs.version }}
33+ semVerNum : ${{steps.determine-number.outputs.number}}
34+ revisionNum : ${{steps.determine-number.outputs.revision}}
35+ steps :
36+ - uses : actions/checkout@v4
37+ with :
38+ fetch-depth : 0
39+ - id : determine-version
40+ shell : pwsh
41+ run : |
42+ if ( '${{github.event_name}}' -eq 'release') {
43+ echo 'version=${{ github.event.release.tag_name}}' >> "$env:GITHUB_OUTPUT"
44+ exit 0
45+ } elseif ('${{inputs.sem-version}}') {
46+ echo 'version=${{ inputs.sem-version}}' >> "$env:GITHUB_OUTPUT"
47+ exit 0
48+ }
49+ Write-Error "Version neither via input nor by tag specified. Aborting"
50+ exit 1
51+ - id : determine-number
52+ run : |
53+ SEM_VER_NUM=$(echo "${{ steps.determine-version.outputs.version }}" | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
54+ echo "number=${SEM_VER_NUM}" >> "$GITHUB_OUTPUT"
55+ REVISION_NUM=`git rev-list --count HEAD`
56+ echo "revision=${REVISION_NUM}" >> "$GITHUB_OUTPUT"
57+
58+ build-binary :
59+ name : Build java app image
60+ needs : [prepare]
61+ strategy :
62+ fail-fast : false
63+ matrix :
64+ include :
65+ - os : macos-latest
66+ architecture : arm64
67+ artifact-name : cryptomator-cli-${{ needs.prepare.outputs.semVerStr }}-mac-arm64.zip
68+ xcode-path : /Applications/Xcode_16.app
69+ - os : macos-13
70+ architecture : x64
71+ artifact-name : cryptomator-cli-${{ needs.prepare.outputs.semVerStr }}-mac-x64.zip
72+ xcode-path : /Applications/Xcode_15.2.app
73+ runs-on : ${{ matrix.os }}
74+ steps :
75+ - uses : actions/checkout@v4
76+ - uses : actions/setup-java@v4
77+ with :
78+ java-version : ${{ env.JAVA_VERSION }}
79+ distribution : ${{ env.JAVA_DIST }}
80+ - name : Set version
81+ run : mvn versions:set -DnewVersion=${{ needs.prepare.outputs.semVerStr }}
82+ - name : Run maven
83+ run : mvn -B clean package -DskipTests
84+ - name : Patch target dir
85+ run : |
86+ cp target/cryptomator-*.jar target/mods
87+ - name : Run jlink
88+ run : |
89+ envsubst < dist/jlink.args > target/jlink.args
90+ "${JAVA_HOME}/bin/jlink" '@./target/jlink.args'
91+ - name : Run jpackage
92+ run : |
93+ envsubst < dist/jpackage.args > target/jpackage.args
94+ "${JAVA_HOME}/bin/jpackage" '@./target/jpackage.args'
95+ env :
96+ JP_APP_VERSION : ' 1.0.0' # see https://github.com/cryptomator/cli/issues/72
97+ APP_VERSION : ${{ needs.prepare.outputs.semVerStr }}
98+ NATIVE_ACCESS_PACKAGE : org.cryptomator.jfuse.mac
99+ - name : Patch .app dir
100+ run : |
101+ cp ../LICENSE.txt cryptomator-cli.app/Contents
102+ cp cryptomator-cli_completion.sh cryptomator-cli.app/Contents
103+ sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" cryptomator-cli.app/Contents/Info.plist
104+ sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" cryptomator-cli.app/Contents/Info.plist
105+ echo -n "$PROVISIONING_PROFILE_BASE64" | base64 --decode -o "cryptomator-cli.app/Contents/embedded.provisionprofile"
106+ working-directory : target
107+ env :
108+ VERSION_NO : ${{ needs.prepare.outputs.semVerNum }}
109+ REVISION_NO : ${{ needs.prepare.outputs.revisionNum }}
110+ PROVISIONING_PROFILE_BASE64 : ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }}
111+ - name : Install codesign certificate
112+ run : |
113+ # create variables
114+ CERTIFICATE_PATH=$RUNNER_TEMP/codesign.p12
115+ KEYCHAIN_PATH=$RUNNER_TEMP/codesign.keychain-db
116+
117+ # import certificate and provisioning profile from secrets
118+ echo -n "$CODESIGN_P12_BASE64" | base64 --decode -o $CERTIFICATE_PATH
119+
120+ # create temporary keychain
121+ security create-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
122+ security set-keychain-settings -lut 900 $KEYCHAIN_PATH
123+ security unlock-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
124+
125+ # import certificate to keychain
126+ security import $CERTIFICATE_PATH -P "$CODESIGN_P12_PW" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
127+ security list-keychain -d user -s $KEYCHAIN_PATH
128+ env :
129+ CODESIGN_P12_BASE64 : ${{ secrets.MACOS_CODESIGN_P12_BASE64 }}
130+ CODESIGN_P12_PW : ${{ secrets.MACOS_CODESIGN_P12_PW }}
131+ CODESIGN_TMP_KEYCHAIN_PW : ${{ secrets.MACOS_CODESIGN_TMP_KEYCHAIN_PW }}
132+ - name : Codesign
133+ run : |
134+ echo "Codesigning jdk files..."
135+ find cryptomator-cli.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
136+ 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} {} \;
137+ echo "Codesigning jar contents..."
138+ find cryptomator-cli.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
139+ for JAR_PATH in `find cryptomator-cli.app -name "*.jar"`; do
140+ if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
141+ JAR_FILENAME=$(basename ${JAR_PATH})
142+ OUTPUT_PATH=${JAR_PATH%.*}
143+ echo "Codesigning libs in ${JAR_FILENAME}..."
144+ unzip -q ${JAR_PATH} -d ${OUTPUT_PATH}
145+ find ${OUTPUT_PATH} -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
146+ find ${OUTPUT_PATH} -name '*.jnilib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
147+ rm ${JAR_PATH}
148+ pushd ${OUTPUT_PATH} > /dev/null
149+ zip -qr ../${JAR_FILENAME} *
150+ popd > /dev/null
151+ rm -r ${OUTPUT_PATH}
152+ fi
153+ done
154+ echo "Codesigning Cryptomator-cli.app..."
155+ sed -i '' "s|###APP_IDENTIFIER_PREFIX###|${TEAM_IDENTIFIER}.|g" ../dist/mac/cryptomator-cli.entitlements
156+ sed -i '' "s|###TEAM_IDENTIFIER###|${TEAM_IDENTIFIER}|g" ../dist/mac/cryptomator-cli.entitlements
157+ codesign --force --deep --entitlements ../dist/mac/cryptomator-cli.entitlements -o runtime -s ${CODESIGN_IDENTITY} cryptomator-cli.app
158+ env :
159+ CODESIGN_IDENTITY : ${{ secrets.MACOS_CODESIGN_IDENTITY }}
160+ TEAM_IDENTIFIER : ${{ secrets.MACOS_TEAM_IDENTIFIER }}
161+ working-directory : target
162+ # ditto must be used, see https://developer.apple.com/documentation/xcode/packaging-mac-software-for-distribution#Build-a-zip-archive
163+ - name : Zip binary for notarization
164+ if : (startsWith(github.ref, 'refs/tags/') && github.event.action == 'published') || inputs.notarize
165+ run : ditto -c -k --keepParent ./target/cryptomator-cli.app ./${{ matrix.artifact-name}}
166+ - name : Setup Xcode
167+ if : (startsWith(github.ref, 'refs/tags/') && github.event.action == 'published') || inputs.notarize
168+ run : sudo xcode-select -s ${{ matrix.xcode-path}}
169+ shell : bash
170+ # would like to uses cocoalibs/xcode-notarization-action@v1, but blocked due to https://github.com/cocoalibs/xcode-notarization-action/issues/1
171+ - name : Prepare Notarization Credentials
172+ if : (startsWith(github.ref, 'refs/tags/') && github.event.action == 'published') || inputs.notarize
173+ run : |
174+ # create temporary keychain
175+ KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
176+ KEYCHAIN_PASS=$(uuidgen)
177+ security create-keychain -p "${KEYCHAIN_PASS}" ${KEYCHAIN_PATH}
178+ security set-keychain-settings -lut 900 ${KEYCHAIN_PATH}
179+ security unlock-keychain -p "${KEYCHAIN_PASS}" ${KEYCHAIN_PATH}
180+ # import credentials from secrets
181+ 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}"
182+ shell : bash
183+ - name : Notarize
184+ if : (startsWith(github.ref, 'refs/tags/') && github.event.action == 'published') || inputs.notarize
185+ run : |
186+ KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
187+ xcrun notarytool submit ${{ matrix.artifact-name }} --keychain-profile "notary" --keychain "${KEYCHAIN_PATH}" --wait
188+ shell : bash
189+ - name : Staple
190+ if : (startsWith(github.ref, 'refs/tags/') && github.event.action == 'published') || inputs.notarize
191+ run : xcrun stapler staple ./target/cryptomator-cli.app
192+ shell : bash
193+ - name : Cleanup
194+ if : ${{ always() }}
195+ run : |
196+ rm -f ./${{ matrix.artifact-name}}
197+ security delete-keychain $RUNNER_TEMP/notarization.keychain-db
198+ shell : bash
199+ continue-on-error : true
200+ - name : Zip app for distribution
201+ run : ditto -c -k --keepParent ./target/cryptomator-cli.app ./${{ matrix.artifact-name}}
202+ - name : Create detached GPG signature with key 615D449FE6E6A235
203+ run : |
204+ echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
205+ echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a ./${{ matrix.artifact-name }}
206+ env :
207+ GPG_PRIVATE_KEY : ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
208+ GPG_PASSPHRASE : ${{ secrets.RELEASES_GPG_PASSPHRASE }}
209+ - uses : actions/upload-artifact@v4
210+ with :
211+ name : cryptomator-cli-mac-${{ matrix.architecture }}
212+ path : |
213+ ${{ matrix.artifact-name}}
214+ *.asc
215+ if-no-files-found : error
216+ - name : Publish artefact on GitHub Releases
217+ if : startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
218+ uses : softprops/action-gh-release@v2
219+ with :
220+ fail_on_unmatched_files : true
221+ token : ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
222+ files : |
223+ ${{ matrix.artifact-name }}
224+ cryptomator-cli-*.asc
0 commit comments