#!/bin/bash if [ ! -f "$1" ] then echo "Please supply the path to an existing zip binary as the first argument" exit 1 fi GITHUB_TOKEN_FILE="${HOME}/.config/github-api-token" GPG_KEYFILE="${HOME}/.config/signkeys/Duplicati/updater-gpgkey.key" AUTHENTICODE_PFXFILE="${HOME}/.config/signkeys/Duplicati/authenticode.pfx" AUTHENTICODE_PASSWORD="${HOME}/.config/signkeys/Duplicati/authenticode.key" MONO=/Library/Frameworks/Mono.framework/Commands/mono GPG=/usr/local/bin/gpg2 FEDORA_INSTANCE_ID=i-deef5352 FEDORA_PUBKEY=AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM3OWpUJOqoh9hq/k48g/FFLqnxUHxecVZM/jRD69Y/cn0OygsSyi3E5X/PVgtfyoced/HV788f9rDpLbY08jXg= DEBIAN_INSTANCE_ID=i-f237887e DEBIAN_PUBKEY=AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJUDOPM7lBBOUtRbAZ8DUP7hHN88CvSvKzWQ15uXcOhdMgtqlznSQiLNfagD/AlqnPsOXWCnNN0fM+QAeMuMBEY= WINDOWS_INSTANCE_ID=i-be348b32 WINDOWS_PUBKEY=AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK5MD6Jg+p6rJmJfx8lWqIY+ZLDEYcGIwcf+eGzPSz4QKuOgxtDo0xgg3/OrxJibyk7sBWkT0f9RHD1qN9Nz/o8= ZIPFILE=`basename "$1"` VERSION=`echo "${ZIPFILE}" | cut -d "-" -f 2 | cut -d "_" -f 1` BUILDTYPE=`echo "${ZIPFILE}" | cut -d "-" -f 2 | cut -d "_" -f 2` BUILDTAG_RAW=`echo "${ZIPFILE}" | cut -d "." -f 1-4 | cut -d "-" -f 2-4` BUILDTAG="${BUILDTAG_RAW//-}" RPMNAME="duplicati-${VERSION}-${BUILDTAG}.noarch.rpm" DEBNAME="duplicati_${VERSION}-1_all.deb" MSI64NAME="duplicati-${BUILDTAG_RAW}-x64.msi" MSI32NAME="duplicati-${BUILDTAG_RAW}-x86.msi" DMGNAME="duplicati-${BUILDTAG_RAW}.dmg" PKGNAME="duplicati-${BUILDTAG_RAW}.pkg" SPKNAME="duplicati-${BUILDTAG_RAW}.spk" UPDATE_TARGET="Updates/build/${BUILDTYPE}_target-${VERSION}" KEYFILE=~/.ssh/duplicati-build-machines-key.pem SSH_OPTIONS="-i ${KEYFILE} -o UserKnownHostsFile=./tmp/known_hosts" echo "Filename: ${ZIPFILE}" echo "Version: ${VERSION}" echo "Buildtype: ${BUILDTYPE}" echo "Buildtag: ${BUILDTAG}" echo "RPMName: ${RPMNAME}" echo "DEBName: ${DEBNAME}" echo "SPKName: ${SPKNAME}" start_aws_instance() { local STATE=`aws ec2 describe-instances --profile=duplicati-builder --instance-ids $1 | python -c 'import sys, json; print json.load(sys.stdin)["Reservations"][0]["Instances"][0]["State"]["Name"]'` if [ "${STATE}" == "stopping" ]; then echo -n "Instance has state '${STATE}', waiting .." while [ "${STATE}" == "stopping" ]; do echo -n "." sleep 5 local STATE=`aws ec2 describe-instances --profile=duplicati-builder --instance-ids $1 | python -c 'import sys, json; print json.load(sys.stdin)["Reservations"][0]["Instances"][0]["State"]["Name"]'` done echo "" fi local STATE=`aws ec2 start-instances --profile=duplicati-builder --instance-ids $1 | python -c 'import sys, json; print json.load(sys.stdin)["StartingInstances"][0]["CurrentState"]["Name"]'` if [ "${STATE}" != "running" ]; then echo -n "Instance has state '${STATE}', waiting .." while [ "${STATE}" != "running" ]; do echo -n "." sleep 5 local STATE=`aws ec2 describe-instances --profile=duplicati-builder --instance-ids $1 | python -c 'import sys, json; print json.load(sys.stdin)["Reservations"][0]["Instances"][0]["State"]["Name"]'` done echo "" fi } stop_aws_instance() { local STATE=`aws ec2 stop-instances --profile=duplicati-builder --instance-ids $1 | python -c 'import sys, json; print json.load(sys.stdin)["StoppingInstances"][0]["CurrentState"]["Name"]'` echo "Instance state is now: ${STATE}" } ssh_connect_to_instance() { local DNSNAME=`aws ec2 describe-instances --profile=duplicati-builder --instance-ids $1 | python -c 'import sys, json; print json.load(sys.stdin)["Reservations"][0]["Instances"][0]["PublicDnsName"]'` local IPADDR=`aws ec2 describe-instances --profile=duplicati-builder --instance-ids $1 | python -c 'import sys, json; print json.load(sys.stdin)["Reservations"][0]["Instances"][0]["PublicIpAddress"]'` if [ -d "./tmp" ]; then rm -rf "./tmp" fi mkdir "./tmp" echo "${DNSNAME},${IPADDR} ecdsa-sha2-nistp256 $3" > "./tmp/known_hosts" SSH_HOST="$2@${DNSNAME}" ssh ${SSH_OPTIONS} "${SSH_HOST}" "cd" > /dev/null local EXITCODE=$? if [ ! "${EXITCODE}" -eq 0 ]; then echo -n "Server did not allow login, waiting .." while [ ! "${EXITCODE}" -eq 0 ]; do echo -n "." sleep 5 ssh ${SSH_OPTIONS} "${SSH_HOST}" "cd" > /dev/null local EXITCODE=$? done echo "" fi } ssh_upload_file() { scp ${SSH_OPTIONS} "$1" "${SSH_HOST}:" } ssh_run_commands() { cat "$1" | ssh ${SSH_OPTIONS} "${SSH_HOST}" } build_file_signatures() { if [ "z${GPGID}" != "z" ]; then echo "$GPGKEY" | "${GPG}" "--passphrase-fd" "0" "--batch" "--yes" "--default-key=${GPGID}" "--output" "$2.sig" "--detach-sig" "$1" echo "$GPGKEY" | "${GPG}" "--passphrase-fd" "0" "--batch" "--yes" "--default-key=${GPGID}" "--armor" "--output" "$2.sig.asc" "--detach-sig" "$1" fi md5 "$1" | awk -F ' ' '{print $NF}' > "$2.md5" shasum -a 1 "$1" | awk -F ' ' '{print $1}' > "$2.sha1" shasum -a 256 "$1" | awk -F ' ' '{print $1}' > "$2.sha256" } if [ -f "${GPG_KEYFILE}" ]; then if [ "z${KEYFILE_PASSWORD}" == "z" ]; then echo -n "Enter keyfile password: " read -s KEYFILE_PASSWORD echo fi GPGDATA=`"${MONO}" "BuildTools/AutoUpdateBuilder/bin/Debug/SharpAESCrypt.exe" d "${KEYFILE_PASSWORD}" "${GPG_KEYFILE}"` if [ ! $? -eq 0 ]; then echo "Decrypting GPG keyfile failed" exit 1 fi GPGID=`echo "${GPGDATA}" | head -n 1` GPGKEY=`echo "${GPGDATA}" | head -n 2 | tail -n 1` else echo "No GPG keyfile found, skipping gpg signatures" fi # Pre-boot instances to keep the waiting to a minimun aws ec2 start-instances --profile=duplicati-builder --instance-ids "${DEBIAN_INSTANCE_ID}" &> /dev/null aws ec2 start-instances --profile=duplicati-builder --instance-ids "${FEDORA_INSTANCE_ID}" &> /dev/null aws ec2 start-instances --profile=duplicati-builder --instance-ids "${WINDOWS_INSTANCE_ID}" &> /dev/null # Then do the local build to mask the waiting a little more echo "" echo "" echo "Building OSX package locally ..." echo "" echo "Enter local sudo password..." cd Installer/OSX bash "make-dmg.sh" "../../$1" mv "Duplicati.dmg" "../../${UPDATE_TARGET}/${DMGNAME}" mv "Duplicati.pkg" "../../${UPDATE_TARGET}/${PKGNAME}" cd ../.. echo "" echo "" echo "Building Synology package locally ..." cd Installer/Synology bash "make-binary-package.sh" "../../$1" mv "${SPKNAME}" "../../${UPDATE_TARGET}/" cd ../.. echo "" echo "" echo "Starting Debian build instance" start_aws_instance "${DEBIAN_INSTANCE_ID}" ssh_connect_to_instance "${DEBIAN_INSTANCE_ID}" "ubuntu" "${DEBIAN_PUBKEY}" echo "Instance has started, uploading binary package ..." ssh_upload_file "$1" echo "Running build script on server ..." cat > "./tmp/debian-commands.sh" < "./tmp/fedora-commands.sh" < "./tmp/windows-commands.sh" < "./tmp/latest-installers.json" process_installer() { if [ "$2" != "zip" ]; then aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/$1" "s3://updates.duplicati.com/${BUILDTYPE}/$1" fi local MD5=`md5 ${UPDATE_TARGET}/$1 | awk -F ' ' '{print $NF}'` local SHA1=`shasum -a 1 ${UPDATE_TARGET}/$1 | awk -F ' ' '{print $1}'` local SHA256=`shasum -a 256 ${UPDATE_TARGET}/$1 | awk -F ' ' '{print $1}'` cat >> "./tmp/latest-installers.json" <> "./tmp/latest-installers.json" <> "./tmp/latest-installers.js" echo ";" >> "./tmp/latest-installers.js" aws --profile=duplicati-upload s3 cp "./tmp/latest-installers.json" "s3://updates.duplicati.com/${BUILDTYPE}/latest-installers.json" aws --profile=duplicati-upload s3 cp "./tmp/latest-installers.js" "s3://updates.duplicati.com/${BUILDTYPE}/latest-installers.js" if [ -d "./tmp" ]; then rm -rf "./tmp" fi mkdir tmp mkdir "./tmp/duplicati-${BUILDTAG_RAW}-signatures" for FILE in "${SPKNAME}" "${RPMNAME}" "${DEBNAME}" "${DMGNAME}" "${PKGNAME}" "${MSI32NAME}" "${MSI64NAME}" "${ZIPFILE}"; do build_file_signatures "${UPDATE_TARGET}/${FILE}" "./tmp/duplicati-${BUILDTAG_RAW}-signatures/${FILE}" done if [ "z${GPGID}" != "z" ]; then echo "${GPGID}" > "./tmp/duplicati-${BUILDTAG_RAW}-signatures/sign-key.txt" echo "https://pgp.mit.edu/pks/lookup?op=get&search=${GPGID}" >> "./tmp/duplicati-${BUILDTAG_RAW}-signatures/sign-key.txt" fi cd tmp zip -r9 "./duplicati-${BUILDTAG_RAW}-signatures.zip" "./duplicati-${BUILDTAG_RAW}-signatures/" cd .. rm -rf "./tmp/duplicati-${BUILDTAG_RAW}-signatures" aws --profile=duplicati-upload s3 cp "./tmp/duplicati-${BUILDTAG_RAW}-signatures.zip" "s3://updates.duplicati.com/${BUILDTYPE}/duplicati-${BUILDTAG_RAW}-signatures.zip" GITHUB_TOKEN=`cat "${GITHUB_TOKEN_FILE}"` if [ "x${GITHUB_TOKEN}" == "x" ]; then echo "No GITHUB_TOKEN found in environment, you can manually upload the binaries" else github-release upload \ --tag "v${VERSION}-${BUILDTAG_RAW}" \ --name "duplicati-${BUILDTAG_RAW}-signatures.zip" \ --repo "duplicati" \ --user "duplicati" \ --security-token "${GITHUB_TOKEN}" \ --file "./tmp/duplicati-${BUILDTAG_RAW}-signatures.zip" for FILE in "${SPKNAME}" "${RPMNAME}" "${DEBNAME}" "${DMGNAME}" "${PKGNAME}" "${MSI32NAME}" "${MSI64NAME}"; do github-release upload \ --tag "v${VERSION}-${BUILDTAG_RAW}" \ --name "${FILE}" \ --repo "duplicati" \ --user "duplicati" \ --security-token "${GITHUB_TOKEN}" \ --file "${UPDATE_TARGET}/${FILE}" done fi rm -rf "./tmp"