mirror of
https://github.com/fergalmoran/picard.git
synced 2026-02-10 01:33:58 +00:00
Only keep it disabled for the legacy macOS 10.12 builds since those use an older Qt5 version.
157 lines
6.0 KiB
Bash
Executable File
157 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
if [ -z "$TRAVIS_TAG" ] && [ -n "$TRAVIS_OSX_IMAGE" ]; then
|
|
python3 setup.py patch_version --platform="osx.$TRAVIS_OSX_IMAGE"
|
|
fi
|
|
VERSION=$(python3 -c 'import picard; print(picard.__version__)')
|
|
|
|
MACOS_VERSION=$(sw_vers -productVersion)
|
|
MACOS_VERSION_MAJOR=${MACOS_VERSION%.*}
|
|
MACOS_VERSION_MAJOR=${MACOS_VERSION_MAJOR%.*}
|
|
MACOS_VERSION_MINOR=${MACOS_VERSION#*.}
|
|
MACOS_VERSION_MINOR=${MACOS_VERSION_MINOR%.*}
|
|
|
|
echo "Building Picard..."
|
|
rm -rf dist build locale
|
|
python3 setup.py clean
|
|
python3 setup.py build
|
|
python3 setup.py build_ext -i
|
|
pyinstaller --noconfirm --clean picard.spec
|
|
|
|
CODESIGN=0
|
|
NOTARIZE=0
|
|
KEYCHAIN_PATH=picard.keychain
|
|
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
|
|
CERTIFICATE_NAME="MetaBrainz Foundation Inc."
|
|
CERTIFICATE_FILE=scripts/package/appledev.p12
|
|
|
|
if [ -f "$CERTIFICATE_FILE" ] && [ -n "$CODESIGN_MACOS_P12_PASSWORD" ]; then
|
|
echo "Preparing code signing certificate..."
|
|
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
security set-keychain-settings "$KEYCHAIN_PATH" # Ensure keychain stays unlocked
|
|
security list-keychains -d user -s "$KEYCHAIN_PATH"
|
|
security default-keychain -s "$KEYCHAIN_PATH"
|
|
security import "$CERTIFICATE_FILE" -k "$KEYCHAIN_PATH" -P "$CODESIGN_MACOS_P12_PASSWORD" -T /usr/bin/codesign
|
|
# The line below is necessary when building on Sierra.
|
|
# See https://stackoverflow.com/q/39868578
|
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
security find-identity -p codesigning # For debugging
|
|
CODESIGN=1
|
|
fi
|
|
|
|
# Submit app for notarization on macOS >= 10.14
|
|
if { [ "$MACOS_VERSION_MAJOR" -eq 10 ] && [ "$MACOS_VERSION_MINOR" -ge 14 ]; } || [ "$MACOS_VERSION_MAJOR" -ge 11 ]; then
|
|
NOTARIZE=1
|
|
fi
|
|
|
|
cd dist
|
|
|
|
echo "Create and sign app bundle..."
|
|
APP_BUNDLE="MusicBrainz Picard.app"
|
|
ditto -rsrc --arch x86_64 "$APP_BUNDLE" "$APP_BUNDLE.tmp"
|
|
rm -r "$APP_BUNDLE"
|
|
mv "$APP_BUNDLE.tmp" "$APP_BUNDLE"
|
|
|
|
# Fix placing text files in Resources instead of Contents to avoid signatures ending up in extended attributes.
|
|
# This fixes the signature breaking if extended attributes get removed or modified.
|
|
# Fixes https://tickets.metabrainz.org/browse/PICARD-1943 and related issues.
|
|
echo "Fixing location of Qt5 translation resources for code signing..."
|
|
if [[ -d "$APP_BUNDLE/Contents/MacOS/PyQt5/Qt5/" ]]; then
|
|
QT5_DIR=Qt5
|
|
else # For older PyQt5 installs
|
|
QT5_DIR=Qt
|
|
fi
|
|
mkdir "$APP_BUNDLE/Contents/Resources/$QT5_DIR/"
|
|
mv "$APP_BUNDLE/Contents/MacOS/PyQt5/$QT5_DIR/translations" "$APP_BUNDLE/Contents/Resources/$QT5_DIR/"
|
|
pushd "$APP_BUNDLE/Contents/MacOS/PyQt5/$QT5_DIR/"
|
|
ln -s "../../../Resources/$QT5_DIR/translations" .
|
|
popd
|
|
|
|
if [ "$DISABLE_WEBP" = '1' ]; then
|
|
# Mitigate libwebp vulnerability allowing for arbitrary code execution (CVE-2023-4863).
|
|
# Disable the Qt webp imageformat plugin if requested.
|
|
rm "$APP_BUNDLE/Contents/MacOS/PyQt5/$QT5_DIR/plugins/imageformats/libqwebp.dylib"
|
|
fi
|
|
|
|
if [ "$CODESIGN" = '1' ]; then
|
|
# Enable hardened runtime if app will get notarized
|
|
if [ "$NOTARIZE" = "1" ]; then
|
|
codesign --verbose --deep --force \
|
|
--options runtime \
|
|
--entitlements ../scripts/package/entitlements.plist \
|
|
--keychain "$KEYCHAIN_PATH" --sign "$CERTIFICATE_NAME" \
|
|
"$APP_BUNDLE"
|
|
../scripts/package/macos-notarize-app.sh "$APP_BUNDLE"
|
|
codesign --verbose --deep --verbose --strict=all --check-notarization "$APP_BUNDLE"
|
|
else
|
|
codesign --verify --verbose --deep --force \
|
|
--keychain "$KEYCHAIN_PATH" --sign "$CERTIFICATE_NAME" \
|
|
"$APP_BUNDLE"
|
|
fi
|
|
fi
|
|
|
|
# Only test the app if it was codesigned, otherwise execution likely fails
|
|
if [ "$CODESIGN" = '1' ]; then
|
|
echo "Verify Picard executable works and required dependencies are bundled..."
|
|
VERSIONS=$("$APP_BUNDLE/Contents/MacOS/picard-run" --long-version --no-crash-dialog)
|
|
echo "$VERSIONS"
|
|
ASTRCMP_REGEX="astrcmp C"
|
|
[[ $VERSIONS =~ $ASTRCMP_REGEX ]] || (echo "Failed: Build does not include astrcmp C" && false)
|
|
LIBDISCID_REGEX="libdiscid [0-9]+\.[0-9]+\.[0-9]+"
|
|
[[ $VERSIONS =~ $LIBDISCID_REGEX ]] || (echo "Failed: Build does not include libdiscid" && false)
|
|
"$APP_BUNDLE/Contents/MacOS/fpcalc" -version
|
|
fi
|
|
|
|
echo "Package app bundle into DMG image..."
|
|
if [ -n "$MACOSX_DEPLOYMENT_TARGET" ]; then
|
|
DMG="MusicBrainz-Picard-${VERSION}-macOS-${MACOSX_DEPLOYMENT_TARGET}.dmg"
|
|
else
|
|
DMG="MusicBrainz-Picard-${VERSION}.dmg"
|
|
fi
|
|
mkdir staging
|
|
mv "$APP_BUNDLE" staging/
|
|
# Offer a link to /Applications for easy installation
|
|
ln -s /Applications staging/Applications
|
|
|
|
set +e
|
|
# workaround hdiutil: create failed - Resource busy
|
|
ATTEMPTS=5
|
|
DELAY=5
|
|
for i in $(seq $ATTEMPTS); do
|
|
hdiutil create -verbose -volname "MusicBrainz Picard $VERSION" \
|
|
-srcfolder staging -ov -format UDBZ "$DMG"
|
|
ret=$?
|
|
[ "$ret" -eq 0 ] && break
|
|
echo "hdutil failed with exit code $ret ($i/$ATTEMPTS), retrying in $DELAY seconds"
|
|
sleep $DELAY
|
|
done
|
|
if [ "$ret" -ne 0 ]; then
|
|
echo "hdiutil failed too many times, exiting..."
|
|
exit "$ret"
|
|
fi
|
|
set -e
|
|
|
|
[ "$CODESIGN" = '1' ] && codesign --verify --verbose \
|
|
--keychain "$KEYCHAIN_PATH" --sign "$CERTIFICATE_NAME" "$DMG"
|
|
md5 -r "$DMG"
|
|
|
|
if [ -n "$UPLOAD_OSX" ]; then
|
|
echo "Preparing to upload $DMG..."
|
|
# make upload failures non fatal
|
|
set +e
|
|
# Set $AWS_ARTIFACTS_BUCKET, $AWS_ACCESS_KEY_ID and $AWS_SECRET_ACCESS_KEY for AWS S3 upload to work
|
|
if [ -n "$AWS_ARTIFACTS_BUCKET" ] && [ -n "$AWS_ACCESS_KEY_ID" ]; then
|
|
pip3 install --upgrade awscli
|
|
aws s3 cp --acl public-read "$DMG" "s3://${AWS_ARTIFACTS_BUCKET}/${TRAVIS_REPO_SLUG}/${TRAVIS_BUILD_NUMBER}/$DMG"
|
|
echo "Package uploaded to https://s3.${AWS_DEFAULT_REGION}.amazonaws.com/${AWS_ARTIFACTS_BUCKET}/${TRAVIS_REPO_SLUG}/${TRAVIS_BUILD_NUMBER}/${DMG// /%20}"
|
|
else
|
|
# Fall back to transfer.sh
|
|
curl -v --retry 6 --retry-delay 10 --max-time 180 --upload-file "$DMG" https://transfer.sh/
|
|
fi
|
|
set -e
|
|
# Required for a newline between the outputs
|
|
echo -e "\n"
|
|
fi
|