Implement cross-platform build scripts (#395)

With the addition of native addons to Etcher, its no longer possible to
package the application for all operating system in a single host.

Given we need to build on Windows, we're creating cross-platform bash
and batch scripts and deprecating the original Makefile.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
Juan Cruz Viotti 2016-05-10 16:07:18 -04:00
parent 52a77160e3
commit d36509d995
7 changed files with 658 additions and 326 deletions

277
Makefile
View File

@ -1,277 +0,0 @@
ELECTRON_PACKAGER=./node_modules/.bin/electron-packager
ELECTRON_BUILDER=./node_modules/.bin/electron-builder
ELECTRON_OSX_SIGN=./node_modules/.bin/electron-osx-sign
ELECTRON_IGNORE=$(shell node scripts/packageignore.js)
ELECTRON_VERSION=$(shell node -e "console.log(require('./package.json').devDependencies['electron-prebuilt'])")
ETCHER_VERSION=$(shell node -e "console.log(require('./package.json').version)")
APPLICATION_NAME=$(shell node -e "console.log(require('./package.json').displayName)")
APPLICATION_DESCRIPTION=$(shell node -e "console.log(require('./package.json').description)")
APPLICATION_COPYRIGHT=$(shell node -e "console.log(require('./package.json').copyright)")
COMPANY_NAME="Resinio Ltd"
SIGN_IDENTITY_OSX="Developer ID Application: Rulemotion Ltd (66H43P8FRG)"
S3_BUCKET="resin-production-downloads"
sign-win32 = osslsigncode sign \
-certs certificate.crt.pem \
-key certificate.key.pem \
-h sha1 \
-t http://timestamp.comodoca.com \
-n "$(APPLICATION_NAME) - $(ETCHER_VERSION)"\
-in $(1) \
-out $(dir $(1))Signed.exe \
&& mv $(dir $(1))Signed.exe $(1)
etcher-release/Etcher-darwin-x64: .
$(ELECTRON_PACKAGER) . $(APPLICATION_NAME) \
--platform=darwin \
--arch=x64 \
--version=$(ELECTRON_VERSION) \
--ignore="$(ELECTRON_IGNORE)" \
--asar \
--app-copyright="$(APPLICATION_COPYRIGHT)" \
--app-version="$(ETCHER_VERSION)" \
--build-version="$(ETCHER_VERSION)" \
--helper-bundle-id="io.resin.etcher-helper" \
--app-bundle-id="io.resin.etcher" \
--app-category-type="public.app-category.developer-tools" \
--icon="assets/icon.icns" \
--overwrite \
--out=$(dir $@)
rm $@/LICENSE
rm $@/LICENSES.chromium.html
rm $@/version
etcher-release/Etcher-linux-x86: .
$(ELECTRON_PACKAGER) . $(APPLICATION_NAME) \
--platform=linux \
--arch=ia32 \
--version=$(ELECTRON_VERSION) \
--ignore="$(ELECTRON_IGNORE)" \
--asar \
--app-version="$(ETCHER_VERSION)" \
--build-version="$(ETCHER_VERSION)" \
--overwrite \
--out=$(dir $@)
mv $(dir $@)Etcher-linux-ia32 $@
mv $@/Etcher $@/etcher
chmod a+x $@/*.so*
upx -9 $@/etcher $@/libnode.so
etcher-release/Etcher-linux-x64: .
$(ELECTRON_PACKAGER) . $(APPLICATION_NAME) \
--platform=linux \
--arch=x64 \
--version=$(ELECTRON_VERSION) \
--ignore="$(ELECTRON_IGNORE)" \
--asar \
--app-version="$(ETCHER_VERSION)" \
--build-version="$(ETCHER_VERSION)" \
--overwrite \
--out=$(dir $@)
mv $@/Etcher $@/etcher
chmod a+x $@/*.so*
upx -9 $@/etcher $@/*.so*
etcher-release/Etcher-win32-x86: .
$(ELECTRON_PACKAGER) . $(APPLICATION_NAME) \
--platform=win32 \
--arch=ia32 \
--version=$(ELECTRON_VERSION) \
--ignore="$(ELECTRON_IGNORE)" \
--icon="assets/icon.ico" \
--asar \
--app-copyright="$(APPLICATION_COPYRIGHT)" \
--app-version="$(ETCHER_VERSION)" \
--build-version="$(ETCHER_VERSION)" \
--version-string.CompanyName=$(COMPANY_NAME) \
--version-string.FileDescription="$(APPLICATION_NAME)" \
--version-string.OriginalFilename=$(notdir $@) \
--version-string.ProductName="$(APPLICATION_NAME) -- $(APPLICATION_DESCRIPTION)" \
--version-string.InternalName="$(APPLICATION_NAME)" \
--overwrite \
--out=$(dir $@)
mv $(dir $@)Etcher-win32-ia32 $@
$(call sign-win32,$@/Etcher.exe)
upx -9 $@/*.dll
etcher-release/Etcher-win32-x64: .
$(ELECTRON_PACKAGER) . $(APPLICATION_NAME) \
--platform=win32 \
--arch=x64 \
--version=$(ELECTRON_VERSION) \
--ignore="$(ELECTRON_IGNORE)" \
--icon="assets/icon.ico" \
--asar \
--app-copyright="$(APPLICATION_COPYRIGHT)" \
--app-version="$(ETCHER_VERSION)" \
--build-version="$(ETCHER_VERSION)" \
--version-string.CompanyName=$(COMPANY_NAME) \
--version-string.FileDescription="$(APPLICATION_NAME)" \
--version-string.OriginalFilename=$(notdir $@) \
--version-string.ProductName="$(APPLICATION_NAME) -- $(APPLICATION_DESCRIPTION)" \
--version-string.InternalName="$(APPLICATION_NAME)" \
--overwrite \
--out=$(dir $@)
$(call sign-win32,$@/Etcher.exe)
upx -9 $@/*.dll
sign-osx = $(ELECTRON_OSX_SIGN) $(1) --platform darwin --verbose --identity $(SIGN_IDENTITY_OSX) \
&& codesign --verify --deep --display --verbose=4 $(1) \
&& spctl --ignore-cache --no-cache --assess --type execute --verbose=4 $(1)
etcher-release/installers/Etcher-darwin-x64.zip: etcher-release/Etcher-darwin-x64 package.json
mkdir -p $(dir $@)
$(call sign-osx,$</$(APPLICATION_NAME).app)
pushd $< && zip -r -9 $(notdir $@) $(APPLICATION_NAME).app && popd
mv $</$(notdir $@) $@
etcher-release/installers/Etcher-darwin-x64.dmg: etcher-release/Etcher-darwin-x64 package.json
# Create temporal read-write DMG image
hdiutil create \
-srcfolder $< \
-volname "$(APPLICATION_NAME)" \
-fs HFS+ \
-fsargs "-c c=64,a=16,e=16" \
-format UDRW \
-size 600M $<.dmg
# Mount temporal DMG image, so we can modify it
hdiutil attach $<.dmg -readwrite -noverify
# Wait for a bit to ensure the image is mounted
sleep 2
# Link to /Applications within the DMG
pushd /Volumes/$(APPLICATION_NAME) && ln -s /Applications && popd
# Symlink MacOS/Etcher to MacOS/Electron since for some reason, the Electron
# binary tries to be ran in some systems.
# See https://github.com/Microsoft/vscode/issues/92
cp -p /Volumes/$(APPLICATION_NAME)/$(APPLICATION_NAME).app/Contents/MacOS/Etcher /Volumes/$(APPLICATION_NAME)/$(APPLICATION_NAME).app/Contents/MacOS/Electron
# Set the DMG icon image
# Writing this hexadecimal buffer to the com.apple.FinderInfo
# extended attribute does the trick.
# See https://github.com/LinusU/node-appdmg/issues/14#issuecomment-29080500
cp assets/icon.icns /Volumes/$(APPLICATION_NAME)/.VolumeIcon.icns
xattr -wx com.apple.FinderInfo "0000000000000000040000000000000000000000000000000000000000000000" /Volumes/$(APPLICATION_NAME)
# Configure background image.
# We use tiffutil to create a "Multirepresentation Tiff file".
# This allows us to show the retina and non-retina image when appropriate.
mkdir /Volumes/$(APPLICATION_NAME)/.background
tiffutil -cathidpicheck assets/osx/installer.png assets/osx/installer@2x.png \
-out /Volumes/$(APPLICATION_NAME)/.background/installer.tiff
# This AppleScript performs the following tasks
# - Set the window basic properties.
# - Set the window size and position.
# - Set the icon size.
# - Arrange the icons.
echo ' \
tell application "Finder" \n\
tell disk "$(APPLICATION_NAME)" \n\
open \n\
set current view of container window to icon view \n\
set toolbar visible of container window to false \n\
set statusbar visible of container window to false \n\
set the bounds of container window to {400, 100, 944, 530} \n\
set viewOptions to the icon view options of container window \n\
set arrangement of viewOptions to not arranged \n\
set icon size of viewOptions to 110 \n\
set background picture of viewOptions to file ".background:installer.tiff" \n\
set position of item "$(APPLICATION_NAME).app" of container window to {140, 225} \n\
set position of item "Applications" of container window to {415, 225} \n\
close \n\
open \n\
update without registering applications \n\
delay 2 \n\
close \n\
end tell \n\
end tell \n\
' | osascript
sync
$(call sign-osx,/Volumes/$(APPLICATION_NAME)/$(APPLICATION_NAME).app)
# Unmount temporal DMG image.
hdiutil detach /Volumes/$(APPLICATION_NAME)
# Convert temporal DMG image into a production-ready
# compressed and read-only DMG image.
mkdir -p $(dir $@)
hdiutil convert $<.dmg \
-format UDZO \
-imagekey zlib-level=9 \
-o $@
# Cleanup temporal DMG image.
rm $<.dmg
app-dir-create = mkdir -p $(2)/usr/bin \
&& cp ./scripts/AppRun-$(1) $(2)/AppRun \
&& cp ./Etcher.desktop $(2) \
&& cp ./assets/icon.png $(2) \
&& cp -rf $</* $(2)/usr/bin \
&& cp ./scripts/desktopintegration $(2)/usr/bin/etcher.wrapper
app-image-create = ./scripts/AppImageAssistant-$(1) $(2) $(3)
etcher-release/installers/Etcher-linux-x64.AppImage: etcher-release/Etcher-linux-x64
$(call app-dir-create,x64,$(dir $<)Etcher-linux-x64.AppDir)
mkdir -p $(dir $@)
$(call app-image-create,x64,$(dir $<)Etcher-linux-x64.AppDir,$@)
etcher-release/installers/Etcher-linux-x86.AppImage: etcher-release/Etcher-linux-x86
$(call app-dir-create,x86,$(dir $<)Etcher-linux-x86.AppDir)
mkdir -p $(dir $@)
$(call app-image-create,x86,$(dir $<)Etcher-linux-x86.AppDir,$@)
etcher-release/installers/Etcher-win32-x64.exe: etcher-release/Etcher-win32-x64 package.json
$(ELECTRON_BUILDER) $< \
--platform=win \
--out=$(dir $@)win32-x64
mv $(dir $@)win32-x64/Etcher\ Setup.exe $@
rmdir $(dir $@)win32-x64
$(call sign-win32,$@)
etcher-release/installers/Etcher-win32-x86.exe: etcher-release/Etcher-win32-x86 package.json
$(ELECTRON_BUILDER) $< \
--platform=win \
--out=$(dir $@)win32-x86
mv $(dir $@)win32-x86/Etcher\ Setup.exe $@
rmdir $(dir $@)win32-x86
$(call sign-win32,$@)
package-osx: etcher-release/Etcher-darwin-x64
package-linux: etcher-release/Etcher-linux-x86 etcher-release/Etcher-linux-x64
package-win32: etcher-release/Etcher-win32-x86 etcher-release/Etcher-win32-x64
package-all: package-osx package-linux package-win32
installer-osx: etcher-release/installers/Etcher-darwin-x64.dmg
installer-linux: etcher-release/installers/Etcher-linux-x64.AppImage etcher-release/installers/Etcher-linux-x86.AppImage
installer-win32: etcher-release/installers/Etcher-win32-x64.exe etcher-release/installers/Etcher-win32-x86.exe
installer-all: installer-osx installer-linux installer-win32
s3-upload = aws s3api put-object \
--bucket $(S3_BUCKET) \
--acl public-read \
--key etcher/$(ETCHER_VERSION)/$(notdir $(1)) \
--body $(1)
upload-linux-x64: etcher-release/installers/Etcher-linux-x64.AppImage
$(call s3-upload,$<)
upload-linux-x86: etcher-release/installers/Etcher-linux-x86.AppImage
$(call s3-upload,$<)
upload-win32-x64: etcher-release/installers/Etcher-win32-x64.exe
$(call s3-upload,$<)
upload-win32-x86: etcher-release/installers/Etcher-win32-x86.exe
$(call s3-upload,$<)
upload-osx: etcher-release/installers/Etcher-darwin-x64.dmg etcher-release/installers/Etcher-darwin-x64.zip
$(call s3-upload,$<)
$(call s3-upload,$(word 2,$^))
upload-linux: upload-linux-x64 upload-linux-x86
upload-win32: upload-win32-x64 upload-win32-x86
upload-all: upload-osx upload-linux upload-win32
release:
rm -rf node_modules/
npm install --force
make upload-all
clean:
rm -rf etcher-release/

View File

@ -3,31 +3,17 @@ Publishing Etcher
This is a small guide to package and publish Etcher to all supported operating systems.
Prequisites
-----------
Common Pre-requisites
---------------------
- [NodeJS](https://nodejs.org)
- [GNU Make](https://www.gnu.org/software/make/)
- [wine (for Windows)](https://www.winehq.org)
- [nsis (for Windows)](http://nsis.sourceforge.net/Main_Page)
- [XCode (for OS X)](https://developer.apple.com/xcode://developer.apple.com/xcode/)
- [AWS CLI (for uploading packages)](https://aws.amazon.com/cli://aws.amazon.com/cli/)
- [osslsigncode (for signing the Windows installers)](https://sourceforge.net/projects/osslsigncode/)
Make sure you're running the exact same NodeJS version as the one included with the current Electron build being used by Etcher to avoid any strange native dependencies issues.
- [Bower](http://bower.io)
- [UPX](http://upx.sourceforge.net)
- [Python](https://www.python.org)
If you're going to generate installers for another platform than the one you're currently running, make sure you force-install all NPM dependencies, so optional dependencies marked for a certain operating system get installed regardless of the host operating system
```sh
npm install --force
```
You can run the following command at any time to start from a fresh state:
```sh
make clean
```
Signing
-------
@ -43,44 +29,59 @@ The application will be signed automatically using this certificate when packagi
1. Get access to our code signing certificate and decryption key as a Resin.io employee by asking for it to the relevant people.
2. Place the cert and key in the root of the Etcher repository naming them `certificate.crt.pem` and `certificate.key.pem`, respectively.
The application and installer will be signed automatically using these certificates when packaging for Windows.
2. Place the certificate in the root of the Etcher repository naming it `certificate.p12`.
Packaging
---------
Run the following command to make installers for all supported operating systems:
```sh
make installer-all
```
You can replace `all` with `osx`, `linux` or `win32` to only generate installers for those platforms:
```sh
make installer-osx
make installer-linux
make installer-win32
```
The resulting installers will be saved to `etcher-release/installers`.
Uploading
---------
### Windows
Pre-requisites:
- [NSIS](http://nsis.sourceforge.net/Main_Page)
- [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx)
- [Rimraf](https://github.com/isaacs/rimraf)
- [asar](https://github.com/electron/asar)
Run the following command from the *Developer Command Prompt for VS2013*, to ensure all Visual Studio command utilities are available in the `%PATH%`:
```sh
> .\scripts\build\windows.bat <arch>
```
### OS X
Pre-requisites:
- [XCode](https://developer.apple.com/xcode://developer.apple.com/xcode/)
Run the following command:
```sh
$ ./scripts/build/darwin.sh
```
### GNU/Linux
Run the following command:
```sh
$ ./scripts/build/linux.sh <arch>
```
Publishing
----------
- [AWS CLI](https://aws.amazon.com/cli://aws.amazon.com/cli/)
Make sure you have the [AWS CLI tool](https://aws.amazon.com/cli://aws.amazon.com/cli/) installed and configured to access Resin.io's production downloads S3 bucket.
Run the following command to upload all installers:
> The publishing script only runs on UNIX based operating systems for now. You can use something like [Cygwin](https://cygwin.com) to run it on Windows.
Run the following command:
```sh
make upload-all
```
As with the `installer` rule, you can replace `all` with `osx`, `linux` or `win32` to only publish those platform's installers:
```sh
make upload-osx
make upload-linux
make upload-win32
./scripts/publish.sh <file>
```

View File

@ -20,6 +20,7 @@
"LICENSE",
"Makefile",
"(.*)\\.pem",
"(.*)\\.p12",
"(.*)\\.log",
"assets/osx",
"appveyor.yml",

193
scripts/build/darwin.sh Executable file
View File

@ -0,0 +1,193 @@
#!/bin/bash
###
# Copyright 2016 Resin.io
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###
# See http://www.davidpashley.com/articles/writing-robust-shell-scripts/
set -u
set -e
set -x
OS=`uname`
if [[ "$OS" != "Darwin" ]]; then
echo "This script is only meant to be run in OS X" 1>&2
exit 1
fi
if ! command -v bower 2>/dev/null; then
echo "Dependency missing: bower" 1>&2
exit 1
fi
ELECTRON_OSX_SIGN=./node_modules/.bin/electron-osx-sign
ELECTRON_PACKAGER=./node_modules/.bin/electron-packager
SIGN_IDENTITY_OSX="Developer ID Application: Rulemotion Ltd (66H43P8FRG)"
ELECTRON_VERSION=`node -e "console.log(require('./package.json').devDependencies['electron-prebuilt'])"`
APPLICATION_NAME=`node -e "console.log(require('./package.json').displayName)"`
APPLICATION_COPYRIGHT=`node -e "console.log(require('./package.json').copyright)"`
APPLICATION_VERSION=`node -e "console.log(require('./package.json').version)"`
function install {
rm -rf node_modules bower_components
npm install --build-from-source
bower install
}
function package {
output_directory=$1
$ELECTRON_PACKAGER . $APPLICATION_NAME \
--platform=darwin \
--arch=x64 \
--version=$ELECTRON_VERSION \
--ignore="`node scripts/packageignore.js`" \
--asar \
--app-copyright="$APPLICATION_COPYRIGHT" \
--app-version="$APPLICATION_VERSION" \
--build-version="$APPLICATION_VERSION" \
--helper-bundle-id="io.resin.etcher-helper" \
--app-bundle-id="io.resin.etcher" \
--app-category-type="public.app-category.developer-tools" \
--icon="assets/icon.icns" \
--overwrite \
--out=$output_directory
rm $output_directory/Etcher-darwin-x64/LICENSE
rm $output_directory/Etcher-darwin-x64/LICENSES.chromium.html
rm $output_directory/Etcher-darwin-x64/version
}
function sign {
source_application=$1
$ELECTRON_OSX_SIGN $source_application --platform darwin --verbose --identity "$SIGN_IDENTITY_OSX"
codesign --verify --deep --display --verbose=4 $source_application
spctl --ignore-cache --no-cache --assess --type execute --verbose=4 $source_application
}
function installer_zip {
source_directory=$1
output_directory=$2
mkdir -p $output_directory
sign $source_directory/$APPLICATION_NAME.app
pushd $source_directory
zip -r -9 Etcher-darwin-x64.zip $APPLICATION_NAME.app
popd
mv $source_directory/Etcher-darwin-x64.zip $output_directory
}
function installer_dmg {
source_directory=$1
output_directory=$2
temporal_dmg=$source_directory.dmg
volume_directory=/Volumes/$APPLICATION_NAME
volume_app=$volume_directory/$APPLICATION_NAME.app
# Make sure any previous DMG was unmounted
hdiutil detach $volume_directory || true
# Create temporal read-write DMG image
hdiutil create \
-srcfolder $source_directory \
-volname "$APPLICATION_NAME" \
-fs HFS+ \
-fsargs "-c c=64,a=16,e=16" \
-format UDRW \
-size 600M $temporal_dmg
# Mount temporal DMG image, so we can modify it
hdiutil attach $temporal_dmg -readwrite -noverify
# Wait for a bit to ensure the image is mounted
sleep 2
# Link to /Applications within the DMG
pushd $volume_directory
ln -s /Applications
popd
# Symlink MacOS/Etcher to MacOS/Electron since for some reason, the Electron
# binary tries to be ran in some systems.
# See https://github.com/Microsoft/vscode/issues/92
cp -p $volume_app/Contents/MacOS/Etcher $volume_app/Contents/MacOS/Electron
# Set the DMG icon image
# Writing this hexadecimal buffer to the com.apple.FinderInfo
# extended attribute does the trick.
# See https://github.com/LinusU/node-appdmg/issues/14#issuecomment-29080500
cp assets/icon.icns $volume_directory/.VolumeIcon.icns
xattr -wx com.apple.FinderInfo \
"0000000000000000040000000000000000000000000000000000000000000000" $volume_directory
# Configure background image.
# We use tiffutil to create a "Multirepresentation Tiff file".
# This allows us to show the retina and non-retina image when appropriate.
mkdir $volume_directory/.background
tiffutil -cathidpicheck assets/osx/installer.png assets/osx/installer@2x.png \
-out $volume_directory/.background/installer.tiff
# This AppleScript performs the following tasks
# - Set the window basic properties.
# - Set the window size and position.
# - Set the icon size.
# - Arrange the icons.
echo '
tell application "Finder"
tell disk "'${APPLICATION_NAME}'"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {400, 100, 944, 530}
set viewOptions to the icon view options of container window
set arrangement of viewOptions to not arranged
set icon size of viewOptions to 110
set background picture of viewOptions to file ".background:installer.tiff"
set position of item "'${APPLICATION_NAME}.app'" of container window to {140, 225}
set position of item "Applications" of container window to {415, 225}
close
open
update without registering applications
delay 2
close
end tell
end tell
' | osascript
sync
sign $volume_app
# Unmount temporal DMG image.
hdiutil detach $volume_directory
# Convert temporal DMG image into a production-ready
# compressed and read-only DMG image.
mkdir -p $output_directory
hdiutil convert $temporal_dmg \
-format UDZO \
-imagekey zlib-level=9 \
-o $output_directory/Etcher-darwin-x64.dmg
# Cleanup temporal DMG image.
rm $temporal_dmg
}
install
package etcher-release
installer_dmg etcher-release/Etcher-darwin-x64 etcher-release/installers
installer_zip etcher-release/Etcher-darwin-x64 etcher-release/installers

157
scripts/build/linux.sh Executable file
View File

@ -0,0 +1,157 @@
#!/bin/bash
###
# Copyright 2016 Resin.io
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###
# See http://www.davidpashley.com/articles/writing-robust-shell-scripts/
set -u
set -e
set -x
OS=`uname`
if [[ "$OS" != "Linux" ]]; then
echo "This script is only meant to be run in GNU/Linux" 1>&2
exit 1
fi
if ! command -v bower 2>/dev/null; then
echo "Dependency missing: bower" 1>&2
exit 1
fi
if ! command -v upx 2>/dev/null; then
echo "Dependency missing: upx" 1>&2
exit 1
fi
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <arch>" 1>&2
exit 1
fi
ARCH=$1
if [ "$ARCH" != "x64" ] && [ "$ARCH" != "x86" ]; then
echo "Unknown architecture: $ARCH" 1>&2
exit 1
fi
ELECTRON_PACKAGER=./node_modules/.bin/electron-packager
ELECTRON_VERSION=`node -e "console.log(require('./package.json').devDependencies['electron-prebuilt'])"`
APPLICATION_NAME=`node -e "console.log(require('./package.json').displayName)"`
APPLICATION_COPYRIGHT=`node -e "console.log(require('./package.json').copyright)"`
APPLICATION_VERSION=`node -e "console.log(require('./package.json').version)"`
function install {
# Can be either "x64" or "ia32"
architecture=$1
# Ensure native addons are compiled with the correct headers
# See https://github.com/electron/electron/blob/master/docs/tutorial/using-native-node-modules.md
export npm_config_disturl=https://atom.io/download/atom-shell
export npm_config_target=$ELECTRON_VERSION
export npm_config_arch=$architecture
export npm_config_runtime=electron
rm -rf node_modules bower_components
npm install --build-from-source
bower install
}
function package_x86 {
output_directory=$1
output_package=$output_directory/Etcher-linux-x86
$ELECTRON_PACKAGER . $APPLICATION_NAME \
--platform=linux \
--arch=ia32 \
--version=$ELECTRON_VERSION \
--ignore="`node scripts/packageignore.js`" \
--asar \
--app-version="$APPLICATION_VERSION" \
--build-version="$APPLICATION_VERSION" \
--overwrite \
--out=$output_directory
# Change ia32 suffix to x86 for consistency
mv $output_directory/Etcher-linux-ia32 $output_package
mv $output_package/Etcher $output_package/etcher
chmod a+x $output_package/*.so*
# UPX fails for some reason with some other so libraries
# other than libnode.so in the x86 build
upx -9 $output_package/etcher $output_package/libnode.so
}
function package_x64 {
output_directory=$1
output_package=$output_directory/Etcher-linux-x64
$ELECTRON_PACKAGER . $APPLICATION_NAME \
--platform=linux \
--arch=x64 \
--version=$ELECTRON_VERSION \
--ignore="`node scripts/packageignore.js`" \
--asar \
--app-version="$APPLICATION_VERSION" \
--build-version="$APPLICATION_VERSION" \
--overwrite \
--out=$output_directory
mv $output_package/Etcher $output_package/etcher
chmod a+x $output_package/*.so*
upx -9 $output_package/etcher $output_package/*.so*
}
function app_dir_create {
source_directory=$1
architecture=$2
output_directory=$3
mkdir -p $output_directory/usr/bin
cp ./scripts/AppRun-$architecture $output_directory/AppRun
cp ./Etcher.desktop $output_directory
cp ./assets/icon.png $output_directory
cp -rf $source_directory/* $output_directory/usr/bin
cp ./scripts/desktopintegration $output_directory/usr/bin/etcher.wrapper
}
function installer {
source_directory=$1
architecture=$2
output_directory=$3
appdir_temporary_location=$output_directory/Etcher-linux-$architecture.AppDir
output_file=$output_directory/Etcher-linux-$architecture.AppImage
mkdir -p $output_directory
app_dir_create $source_directory $architecture $appdir_temporary_location
./scripts/AppImageAssistant-$architecture $appdir_temporary_location $output_file
rm -rf $appdir_temporary_location
}
if [ "$ARCH" == "x86" ]; then
install ia32
package_x86 etcher-release
fi
if [ "$ARCH" == "x64" ]; then
install x64
package_x64 etcher-release
fi
installer etcher-release/Etcher-linux-$ARCH $ARCH etcher-release/installers

217
scripts/build/windows.bat Normal file
View File

@ -0,0 +1,217 @@
@echo off
::::
:: Copyright 2016 Resin.io
::
:: Licensed under the Apache License, Version 2.0 (the "License");
:: you may not use this file except in compliance with the License.
:: You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing, software
:: distributed under the License is distributed on an "AS IS" BASIS,
:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
:: See the License for the specific language governing permissions and
:: limitations under the License.
::::
set arch=%1
set output_build_directory=etcher-release
set output_directory=%output_build_directory%\installers
set certificate_file=certificate.p12
set certificate_pass=1234
set timestamp_server_url=http://timestamp.comodoca.com
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Validate arguments
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if "%arch%"=="" (
echo Usage: %0 [arch] 1>&2
exit /b 1
)
:: Batch conditionals don't support logical operators.
:: Simulate "and" with nested conditions.
if not "%arch%"=="x86" (
if not "%arch%"=="x64" (
echo Unknown architecture: %arch% 1>&2
exit /b 1
)
)
:: Check that rimraf is installed.
:: We make use of this command line tool to clear
:: saved dependencies since doing so with `del`
:: might return errors due to long paths.
where rimraf >nul 2>nul
if %ERRORLEVEL% neq 0 (
echo Dependency missing: rimraf 1>&2
exit /b 1
)
:: Check that signtool is installed.
where signtool >nul 2>nul
if %ERRORLEVEL% neq 0 (
echo Dependency missing: signtool 1>&2
exit /b 1
)
:: Check that bower is installed.
where bower >nul 2>nul
if %ERRORLEVEL% neq 0 (
echo Dependency missing: bower 1>&2
exit /b 1
)
:: Check that makensis is installed.
where makensis >nul 2>nul
if %ERRORLEVEL% neq 0 (
echo Dependency missing: nsis 1>&2
exit /b 1
)
:: Check that upx is installed.
where upx >nul 2>nul
if %ERRORLEVEL% neq 0 (
echo Dependency missing: upx 1>&2
exit /b 1
)
:: Check that asar is installed.
where asar >nul 2>nul
if %ERRORLEVEL% neq 0 (
echo Dependency missing: asar 1>&2
exit /b 1
)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Global variables
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set electron_packager=.\node_modules\.bin\electron-packager.cmd
set electron_builder=.\node_modules\.bin\electron-builder.cmd
set company_name="Resinio Ltd"
if "%arch%"=="x86" (
set electron_arch=ia32
)
if "%arch%"=="x64" (
set electron_arch=x64
)
set package_name=Etcher-win32-%arch%
for /f %%i in (' "node -e ""console.log(require('./package.json').devDependencies['electron-prebuilt'])""" ') do (
set electron_version=%%i
)
for /f %%i in (' "node -e ""console.log(require('./package.json').displayName)""" ') do (
set application_name=%%i
)
for /f "delims=" %%i in (' "node -e ""console.log(require('./package.json').description)""" ') do (
set application_description=%%i
)
for /f %%i in (' "node -e ""console.log(require('./package.json').copyright)""" ') do (
set application_copyright=%%i
)
for /f %%i in (' "node -e ""console.log(require('./package.json').version)""" ') do (
set etcher_version=%%i
)
for /f %%i in (' "node .\scripts\packageignore.js" ') do (
set electron_ignore="%%i"
)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Configure NPM to build native addons for Electron correctly
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: We require Visual Studio 2013 specifically since newer versions
:: lack command line build tools such as `lib.exe` and `cl.exe`.
set GYP_MSVS_VERSION=2013
set npm_config_disturl=https://atom.io/download/atom-shell
set npm_config_runtime=electron
set npm_config_target=%electron_version%
set npm_config_arch=%electron_arch%
set HOME=%homedrive%%homepath%\.electron-gyp
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Install dependencies
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
call rimraf node_modules bower_components
call npm install --build-from-source
call bower install
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Package application
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
call %electron_packager% . %application_name%^
--platform=win32^
--arch=%electron_arch%^
--version=%electron_version%^
--ignore=%electron_ignore%^
--icon="assets/icon.ico"^
--app-copyright=%application_copyright%^
--app-version=%etcher_version%^
--build-version=%etcher_version%^
--version-string.CompanyName=%company_name%^
--version-string.FileDescription=%application_name%^
--version-string.OriginalFilename=%package_name%^
--version-string.ProductName="%application_name% -- %application_description%"^
--version-string.InternalName=%application_name%^
--overwrite^
--out=%output_build_directory%
set package_output=%output_build_directory%\%package_name%
if not "%arch%"=="%electron_arch%" (
move %output_build_directory%\Etcher-win32-%electron_arch% %package_output%
)
:: Omit *.dll and *.node files from the asar package, otherwise
:: `process.dlopen` and `module.require` can't load them correctly.
call asar pack %package_output%\resources\app %package_output%\resources\app.asar^
--unpack "{*.dll,*.node}"
call rimraf %package_output%\resources\app
signtool sign^
/t %timestamp_server_url%^
/d "%application_name% - %etcher_version%"^
/f %certificate_file%^
/p %certificate_pass%^
%package_output%\Etcher.exe
signtool verify /pa /v %package_output%\Etcher.exe
upx -9 %package_output%\*.dll
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Generate installer
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set installer_tmp_output=%output_build_directory%\win32-%arch%-tmp-installer
set installer_output=%output_directory%\Etcher-win32-%arch%.exe
call %electron_builder% %package_output%^
--platform=win^
--out=%installer_tmp_output%
mkdir "%output_directory%"
move "%installer_tmp_output%\%application_name% Setup.exe" "%installer_output%"
rd /s /q "%installer_tmp_output%"
signtool sign^
/t %timestamp_server_url%^
/d "%application_name% - %etcher_version%"^
/f %certificate_file%^
/p %certificate_pass%^
%installer_output%
signtool verify /pa /v %installer_output%

40
scripts/publish.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/bash
###
# Copyright 2016 Resin.io
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###
# See http://www.davidpashley.com/articles/writing-robust-shell-scripts/
set -u
set -e
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <file>" 1>&2
exit 1
fi
if ! command -v aws 1>/dev/null 2>/dev/null; then
echo "Dependency missing: aws cli" 1>&2
exit 1
fi
ETCHER_VERSION=`node -e "console.log(require('./package.json').version)"`
S3_BUCKET="resin-production-downloads"
aws s3api put-object \
--bucket $S3_BUCKET \
--acl public-read \
--key etcher/$ETCHER_VERSION/`basename $1` \
--body $1