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