Skip to content

Commit

Permalink
Merge pull request #23 from mbeddr/refactor/dmg-signing
Browse files Browse the repository at this point in the history
Code signing of apps for macOS enabled
  • Loading branch information
sergej-koscejev authored Aug 2, 2018
2 parents e1e83bd + 0284181 commit 3ac8f05
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 23 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ task buildDmg(type: de.itemis.mps.gradle.CreateDmg) {
backgroundImage file('path/to/background.png')
dmgFile file('output.dmg')
signKeyChain file("/path/to/my.keychain-db")
signKeyChainPassword "my.keychain-db-password"
signIdentity "my Application ID Name"
}
```

Expand All @@ -52,13 +58,17 @@ Parameters:
* `backgroundImage` - the path to the background image.
* `dmgFile` - the path and file name of the output DMG image. Must end
with `.dmg`.
* `signKeyChain (optional)` - the path and file name of the keychain which contains a code signing certificate.
* `signKeyChainPassword (optional)` - the password which should be use to unlock the keychain.
* `signIdentity (optional)` - the application ID of the code signing certificate.

### Operation

The task unpacks `rcpArtifact` into a temporary directory, unpacks
the JDK given by `jdkDependency`/`jdk` under the `jre` subdirectory of
the unpacked RCP artifact, fixes file permissions and creates missing
symlinks, then creates a DMG image and configures its layout, using the
symlinks. If the additional properties for code signing (`signKeyChain`, `signKeyChainPassword`, `signIdentity`) are defined,
the application will be signed with the given certificate. Afterwards a DMG image is created and its layout is configured using the
background image. Finally, the DMG is copied to `dmgFile`.

## BundleMacosJdk
Expand Down
24 changes: 23 additions & 1 deletion src/main/groovy/de/itemis/mps/gradle/CreateDmg.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.gradle.api.artifacts.Dependency
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.Optional

class CreateDmg extends DefaultTask {
@InputFile
Expand All @@ -20,6 +21,19 @@ class CreateDmg extends DefaultTask {
@OutputFile
File dmgFile

@Optional
String signKeyChainPassword

@Optional
String signIdentity

@InputFile @Optional
File signKeyChain

def setSignKeyChain(Object file) {
this.signKeyChain = project.file(file)
}

def setRcpArtifact(Object file) {
this.rcpArtifact = project.file(file)
}
Expand Down Expand Up @@ -59,11 +73,19 @@ class CreateDmg extends DefaultTask {
'Mac/Finder/DSStore/BuddyAllocator.pm', 'Mac/Finder/DSStore.pm']
File scriptsDir = File.createTempDir()
File dmgDir = File.createTempDir()
def signingInfo = [signKeyChainPassword, signKeyChain, signIdentity]
try {
BundledScripts.extractScriptsToDir(scriptsDir, scripts)
project.exec {
executable new File(scriptsDir, 'mpssign.sh')
args rcpArtifact, dmgDir, jdk

if(signingInfo.every {it != null}) {
args '-r', rcpArtifact, '-o', dmgDir, '-j', jdk, '-p', signKeyChainPassword, '-k', signKeyChain, '-i', signIdentity
}else if (signingInfo.every {it == null}){
args '-r', rcpArtifact, '-o', dmgDir, '-j', jdk
}else{
throw new IllegalArgumentException("Not all signing paramters set. signKeyChain: ${getSigningInfo[1]}, signIdentity: ${getSigningInfo[2]} and signKeyChainPassword needs to be set. ")
}
workingDir scriptsDir
}
project.exec {
Expand Down
64 changes: 43 additions & 21 deletions src/main/resources/de/itemis/mps/gradle/mpssign.sh
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
#!/bin/bash
if [[ $# -ne 3 && $# -ne 2 ]]; then
cat <<EOF
Usage:
USAGE="Usage:
$0 RCP_FILE OUTPUT_DIR [JDK_FILE]
$0 -r <rcp_file> -o <output_dir> [-j <jdk_file>] [-p <password keychain> -k <keychain> -i <sign identity>]
1. Extracts RCP_FILE into OUTPUT_DIR
2. Creates symlinks Contents/bin/*.dylib -> *.jnilib
3. If JDK_FILE is given, extracts JDK_FILE under Contents/jre/
3. If JDK_FILE is given extracts JDK_FILE under Contents/jre/
4. Builds help indices using hiutil if help is present under Contents/Resources/
5. Sets executable permissions on Contents/MacOS/* and appropriate Contents/bin/ files
6. If given, signs the application with the passed SIGN_PW, SIGN_KEY_CHAIN and SIGN_IDENTITY
IMPORTANT: All arguments must use absolute paths because the script changes the current directory several times!
EOF
exit 1
fi

"
set -o errexit # Exit immediately on any error

# Arguments
RCP_FILE="$1"
OUTPUT_DIR="$2"
JDK_FILE="$3"
# Parse arguments
while getopts ":r:o:j:p:k:i:h" option;
do
case "${option}" in
r) RCP_FILE="$OPTARG";;
o) OUTPUT_DIR="$OPTARG";;
j) JDK_FILE="$OPTARG";;
p) SIGN_PW="$OPTARG";;
k) SIGN_KEY_CHAIN="$OPTARG";;
i) SIGN_IDENTITY="$OPTARG";;
h) echo "$USAGE"
exit 0;;
\?) echo "illegal option: -$OPTARG usage: $0 -r <rcp_file> -o <output_dir> [-j <jdk_file>] [-p <password keychain> -k <keychain> -i <sign identity>]" >&2
exit 1;;
:) echo "option: -$OPTARG requires an argument" >&2
exit 1;;
esac
done
shift $((OPTIND -1)) #remove options that have already been handled from $@

if [[ -z "$RCP_FILE" || -z "$OUTPUT_DIR" ]]; then
echo "$USAGE"
exit 1
fi

echo "Unzipping $RCP_FILE to $OUTPUT_DIR..."
unzip -q -o "$RCP_FILE" -d "$OUTPUT_DIR"
Expand Down Expand Up @@ -71,13 +86,20 @@ if [[ -d "$HELP_DIR" ]]; then
hiutil -Cagvf "$HELP_DIR/search.helpindex" "$HELP_DIR"
fi

# Make sure JetBrainsMacApplication.p12 is imported into local KeyChain
#security unlock-keychain -p <password> /Users/builduser/Library/Keychains/login.keychain
#codesign -v --deep -s "Developer ID Application: JetBrains" "$OUTPUT_DIR/$BUILD_NAME"
#echo "signing is done"
#echo "check sign"
#codesign -v "$OUTPUT_DIR/$BUILD_NAME" -vvvvv
#echo "check sign done"
# Make sure your certificate is imported into local KeyChain
if [[ -n "$SIGN_PW" && -n "$SIGN_KEY_CHAIN" && -n "$SIGN_IDENTITY" ]]; then
echo "Signing application $BUILD_NAME"
echo "key chain: $SIGN_KEY_CHAIN"
echo "sign identity: $SIGN_IDENTITY"
security unlock-keychain -p $SIGN_PW $SIGN_KEY_CHAIN
codesign -v --deep -s "$SIGN_IDENTITY" "$OUTPUT_DIR/$BUILD_NAME"
echo "signing is done"
echo "check sign"
codesign -v "$OUTPUT_DIR/$BUILD_NAME" -vvvvv
echo "check sign done"
else
echo "for signing the application $BUILD_NAME: SIGN_PW, SIGN_KEY_CHAIN and SIGN_IDENTITY needs to be provided"
fi

chmod a+x "$CONTENTS"/MacOS/*
chmod a+x "$CONTENTS"/bin/*.py
Expand Down

0 comments on commit 3ac8f05

Please sign in to comment.