diff --git a/dev-app-update.yml b/dev-app-update.yml
new file mode 100644
index 00000000..41f67598
--- /dev/null
+++ b/dev-app-update.yml
@@ -0,0 +1,4 @@
+owner: balena-io
+repo: etcher
+provider: github
+updaterCacheDirName: balena-etcher-updater
diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js
index 303fbe0e..897f00c1 100644
--- a/lib/gui/app/app.js
+++ b/lib/gui/app/app.js
@@ -27,24 +27,18 @@ var angular = require('angular')
/* eslint-enable no-var */
const electron = require('electron')
-const Bluebird = require('bluebird')
const sdk = require('etcher-sdk')
const _ = require('lodash')
-const semver = require('semver')
const uuidV4 = require('uuid/v4')
const EXIT_CODES = require('../../shared/exit-codes')
const messages = require('../../shared/messages')
-const s3Packages = require('../../shared/s3-packages')
-const release = require('../../shared/release')
const store = require('./models/store')
-const errors = require('../../shared/errors')
const packageJSON = require('../../../package.json')
const flashState = require('./models/flash-state')
const settings = require('./models/settings')
const windowProgress = require('./os/window-progress')
const analytics = require('./modules/analytics')
-const updateNotifier = require('./components/update-notifier')
const availableDrives = require('./models/available-drives')
const selectionState = require('./models/selection-state')
const driveScanner = require('./modules/drive-scanner')
@@ -134,84 +128,6 @@ app.run(() => {
version: currentVersion,
applicationSessionUuid
})
-
- const shouldCheckForUpdates = updateNotifier.shouldCheckForUpdates({
- currentVersion,
- lastSleptUpdateNotifier: settings.get('lastSleptUpdateNotifier'),
- lastSleptUpdateNotifierVersion: settings.get('lastSleptUpdateNotifierVersion')
- })
-
- const isStableRelease = release.isStableRelease(currentVersion)
- const updatesEnabled = settings.get('updatesEnabled')
-
- if (!shouldCheckForUpdates || !updatesEnabled) {
- analytics.logEvent('Not checking for updates', {
- shouldCheckForUpdates,
- updatesEnabled,
- stable: isStableRelease,
- applicationSessionUuid
- })
-
- return Bluebird.resolve()
- }
-
- const updateSemverRange = packageJSON.updates.semverRange
- const includeUnstableChannel = settings.get('includeUnstableUpdateChannel')
-
- analytics.logEvent('Checking for updates', {
- currentVersion,
- stable: isStableRelease,
- updateSemverRange,
- includeUnstableChannel,
- applicationSessionUuid
- })
-
- return s3Packages.getLatestVersion(release.getReleaseType(currentVersion), {
- range: updateSemverRange,
- includeUnstableChannel
- }).then((latestVersion) => {
- if (semver.gte(currentVersion, latestVersion || '0.0.0')) {
- analytics.logEvent('Update notification skipped', {
- reason: 'Latest version',
- applicationSessionUuid
- })
- return Bluebird.resolve()
- }
-
- // In case the internet connection is not good and checking the
- // latest published version takes too long, only show notify
- // the user about the new version if he didn't start the flash
- // process (e.g: selected an image), otherwise such interruption
- // might be annoying.
- if (selectionState.hasImage()) {
- analytics.logEvent('Update notification skipped', {
- reason: 'Image selected',
- applicationSessionUuid
- })
- return Bluebird.resolve()
- }
-
- analytics.logEvent('Notifying update', {
- latestVersion,
- applicationSessionUuid
- })
-
- return updateNotifier.notify(latestVersion, {
- allowSleepUpdateCheck: isStableRelease
- })
-
- // If the error is an update user error, then we don't want
- // to bother users each time they open the app.
- // See: https://github.com/resin-io/etcher/issues/1525
- }).catch((error) => {
- return errors.isUserError(error) && error.code === 'UPDATE_USER_ERROR'
- }, (error) => {
- analytics.logEvent('Update check user error', {
- title: errors.getTitle(error),
- description: errors.getDescription(error),
- applicationSessionUuid
- })
- }).catch(exceptionReporter.report)
})
app.run(() => {
diff --git a/lib/gui/app/components/update-notifier.js b/lib/gui/app/components/update-notifier.js
deleted file mode 100644
index 4911818a..00000000
--- a/lib/gui/app/components/update-notifier.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.
- */
-
-'use strict'
-
-const electron = require('electron')
-const Bluebird = require('bluebird')
-const _ = require('lodash')
-const store = require('../models/store')
-const settings = require('../models/settings')
-const analytics = require('../modules/analytics')
-const units = require('../../../shared/units')
-const release = require('../../../shared/release')
-const packageJSON = require('../../../../package.json')
-
-/**
- * @summary The number of days the update notifier can be put to sleep
- * @constant
- * @private
- * @type {Number}
- */
-exports.UPDATE_NOTIFIER_SLEEP_DAYS = packageJSON.updates.sleepDays
-
-/**
- * @summary The current Electron browser window
- * @constant
- * @private
- * @type {Object}
- */
-const currentWindow = electron.remote.getCurrentWindow()
-
-/**
- * @summary Determine if it's time to check for updates
- * @function
- * @public
- *
- * @param {Object} options - options
- * @param {Number} [options.lastSleptUpdateNotifier] - last slept update notifier time
- * @param {String} [options.lastSleptUpdateNotifierVersion] - last slept update notifier version
- * @param {String} options.currentVersion - current version
- * @returns {Boolean} should check for updates
- *
- * @example
- * if (updateNotifier.shouldCheckForUpdates({
- * lastSleptUpdateNotifier: Date.now(),
- * lastSleptUpdateNotifierVersion: '1.0.0',
- * currentVersion: '1.0.0'
- * })) {
- * console.log('We should check for updates!');
- * }
- */
-exports.shouldCheckForUpdates = (options) => {
- if (settings.get('resinUpdateLock')) {
- return false
- }
-
- _.defaults(options, {
- lastSleptUpdateNotifierVersion: options.currentVersion
- })
-
- if (_.some([
- !options.lastSleptUpdateNotifier,
- !release.isStableRelease(options.currentVersion),
- options.currentVersion !== options.lastSleptUpdateNotifierVersion
- ])) {
- return true
- }
-
- return Date.now() - options.lastSleptUpdateNotifier > units.daysToMilliseconds(exports.UPDATE_NOTIFIER_SLEEP_DAYS)
-}
-
-/**
- * @summary Open the update notifier widget
- * @function
- * @public
- *
- * @param {String} version - version
- * @param {Object} [options] - options
- * @param {Boolean} [options.allowSleepUpdateCheck=true] - allow sleeping the update check
- * @returns {Promise}
- *
- * @example
- * updateNotifier.notify('1.0.0-beta.16', {
- * allowSleepUpdateCheck: true
- * });
- */
-exports.notify = (version, options = {}) => {
- const BUTTONS = [
- 'Download',
- 'Skip'
- ]
-
- const BUTTON_CONFIRMATION_INDEX = _.indexOf(BUTTONS, _.first(BUTTONS))
- const BUTTON_REJECTION_INDEX = _.indexOf(BUTTONS, _.last(BUTTONS))
-
- const dialogOptions = {
- type: 'info',
- buttons: BUTTONS,
- defaultId: BUTTON_CONFIRMATION_INDEX,
- cancelId: BUTTON_REJECTION_INDEX,
- title: 'New Update Available!',
- message: `Etcher ${version} is available for download`
- }
-
- if (_.get(options, [ 'allowSleepUpdateCheck' ], true)) {
- _.merge(dialogOptions, {
- checkboxLabel: `Remind me again in ${exports.UPDATE_NOTIFIER_SLEEP_DAYS} days`,
- checkboxChecked: false
- })
- }
-
- return new Bluebird((resolve) => {
- electron.remote.dialog.showMessageBox(currentWindow, dialogOptions, (response, checkboxChecked) => {
- return resolve({
- agreed: response === BUTTON_CONFIRMATION_INDEX,
- sleepUpdateCheck: checkboxChecked || false
- })
- })
- }).tap((results) => {
- // Only update the last slept update timestamp if the
- // user ticked the "Remind me again in ..." checkbox,
- // but didn't agree.
- if (results.sleepUpdateCheck && !results.agreed) {
- return Bluebird.all([
- settings.set('lastSleptUpdateNotifier', Date.now()),
- settings.set('lastSleptUpdateNotifierVersion', packageJSON.version)
- ])
- }
-
- return Bluebird.resolve()
- }).then((results) => {
- analytics.logEvent('Close update modal', {
- sleepUpdateCheck: results.sleepUpdateCheck,
- notifyVersion: version,
- currentVersion: packageJSON.version,
- agreed: results.agreed,
- applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
- flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
- })
-
- if (results.agreed) {
- electron.shell.openExternal('https://etcher.io?ref=etcher_update')
- }
- })
-}
diff --git a/lib/gui/app/models/settings.js b/lib/gui/app/models/settings.js
index 371922b2..5f3dcd89 100644
--- a/lib/gui/app/models/settings.js
+++ b/lib/gui/app/models/settings.js
@@ -24,7 +24,6 @@ const _ = require('lodash')
const Bluebird = require('bluebird')
const localSettings = require('./local-settings')
const errors = require('../../../shared/errors')
-const release = require('../../../shared/release')
const packageJSON = require('../../../../package.json')
const debug = require('debug')('etcher:models:settings')
@@ -39,7 +38,6 @@ const DEFAULT_SETTINGS = {
unmountOnSuccess: true,
validateWriteOnSuccess: true,
updatesEnabled: packageJSON.updates.enabled && !_.includes([ 'rpm', 'deb' ], packageJSON.packageType),
- includeUnstableUpdateChannel: !release.isStableRelease(packageJSON.version),
lastSleptUpdateNotifier: null,
lastSleptUpdateNotifierVersion: null,
desktopNotifications: true
diff --git a/lib/gui/app/modules/analytics.js b/lib/gui/app/modules/analytics.js
index 340fec55..7a8072f0 100644
--- a/lib/gui/app/modules/analytics.js
+++ b/lib/gui/app/modules/analytics.js
@@ -20,10 +20,8 @@ const _ = require('lodash')
const resinCorvus = require('resin-corvus/browser')
const packageJSON = require('../../../../package.json')
const settings = require('../models/settings')
-const { hasProps } = require('../../../shared/utils')
+const { getConfig, hasProps } = require('../../../shared/utils')
-const Bluebird = require('bluebird')
-const request = Bluebird.promisifyAll(require('request'))
const sentryToken = settings.get('analyticsSentryToken') ||
_.get(packageJSON, [ 'analytics', 'sentry', 'token' ])
const mixpanelToken = settings.get('analyticsMixpanelToken') ||
@@ -73,16 +71,6 @@ const initConfig = async () => {
initConfig()
-/**
- * @summary Get etcher configs stored online
- * @param {String} - url where config.json is stored
- */
-// eslint-disable-next-line
-function getConfig(url) {
- return request.getAsync(url, { json: true })
- .get('body')
-}
-
/**
* @summary Check that the client is eligible for analytics
* @param {Object} - config
diff --git a/lib/gui/app/pages/settings/templates/settings.tpl.html b/lib/gui/app/pages/settings/templates/settings.tpl.html
index 48b11f71..313c2cc2 100644
--- a/lib/gui/app/pages/settings/templates/settings.tpl.html
+++ b/lib/gui/app/pages/settings/templates/settings.tpl.html
@@ -43,14 +43,14 @@
-
+
diff --git a/lib/gui/etcher.js b/lib/gui/etcher.js
index 374aa74c..db2350e8 100644
--- a/lib/gui/etcher.js
+++ b/lib/gui/etcher.js
@@ -18,14 +18,41 @@
const electron = require('electron')
const path = require('path')
+const _ = require('lodash')
+const { autoUpdater } = require('electron-updater')
+const Bluebird = require('bluebird')
const EXIT_CODES = require('../shared/exit-codes')
const buildWindowMenu = require('./menu')
const settings = require('./app/models/settings')
-
+const analytics = require('./app/modules/analytics')
+const { getConfig } = require('../shared/utils')
/* eslint-disable lodash/prefer-lodash-method */
const config = settings.getDefaults()
+const configUrl = settings.get('configUrl') || 'http://balena.io/etcher/static/config.json'
+
+/**
+ *
+ * @param {Number} interval - interval to wait to check for updates
+ * @example checkForUpdates()
+ */
+const checkForUpdates = async (interval) => {
+ // We use a while loop instead of a setInterval to preserve
+ // async execution time between each function call
+ while (true) {
+ try {
+ const release = await autoUpdater.checkForUpdates()
+ if (release.updateInfo.stagingPercentage) {
+ await autoUpdater.downloadUpdate()
+ }
+ } catch (err) {
+ analytics.logException(err)
+ }
+ await Bluebird.delay(interval)
+ }
+}
+
/**
* @summary Create Etcher's main window
* @example
@@ -83,6 +110,28 @@ const createMainWindow = () => {
} else {
mainWindow.loadURL(`file://${path.join(__dirname, 'app', 'index.html')}`)
}
+
+ const page = mainWindow.webContents
+
+ page.once('did-frame-finish-load', async () => {
+ autoUpdater.on('error', (err) => {
+ analytics.logException(err)
+ })
+ if (settings.get('updatesEnabled')) {
+ try {
+ const onlineConfig = await getConfig(configUrl)
+ const autoUpdaterConfig = _.get(onlineConfig, [ 'autoUpdates', 'autoUpdaterConfig' ], {
+ autoDownload: false
+ })
+ _.merge(autoUpdater, autoUpdaterConfig)
+ // eslint-disable-next-line no-magic-numbers
+ const checkForUpdatesTimer = _.get(onlineConfig, [ 'autoUpdates', 'checkForUpdatesTimer' ], 300000)
+ checkForUpdates(checkForUpdatesTimer)
+ } catch (err) {
+ analytics.logException(err)
+ }
+ }
+ })
}
electron.app.on('window-all-closed', electron.app.quit)
diff --git a/lib/shared/release.js b/lib/shared/release.js
deleted file mode 100644
index 39bcf2c1..00000000
--- a/lib/shared/release.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-'use strict'
-
-const _ = require('lodash')
-const semver = require('semver')
-
-/**
- * @summary Application release types
- * @namespace RELEASE_TYPE
- * @public
- */
-exports.RELEASE_TYPE = {
-
- /**
- * @property {String} PRODUCTION
- * @memberof RELEASE_TYPE
- * @description
- * Production release type
- */
- PRODUCTION: 'PRODUCTION',
-
- /**
- * @property {String} SNAPSHOT
- * @memberof RELEASE_TYPE
- * @description
- * Snapshot release type
- */
- SNAPSHOT: 'SNAPSHOT',
-
- /**
- * @property {String} UNKNOWN
- * @memberof RELEASE_TYPE
- * @description
- * Unknown release type
- */
- UNKNOWN: 'UNKNOWN'
-
-}
-
-/**
- * @summary Get the release type from a version string
- * @function
- * @public
- *
- * @param {String} version - application version
- * @returns {RELEASE_TYPE} release type
- *
- * @example
- * const version = require('../../package.json').version;
- * const releaseType = release.getReleaseType(version);
- *
- * if (releaseType === release.RELEASE_TYPE.PRODUCTION) {
- * console.log('This is a production release!');
- * }
- */
-exports.getReleaseType = (version) => {
- const GIT_HASH_REGEX = /^[0-9a-f]{7,40}$/
- const buildNumber = _.get(semver.parse(version), [ 'build' ])
-
- if (!_.isNil(buildNumber)) {
- if (_.isEmpty(buildNumber)) {
- return exports.RELEASE_TYPE.PRODUCTION
- }
-
- if (GIT_HASH_REGEX.test(_.first(buildNumber))) {
- return exports.RELEASE_TYPE.SNAPSHOT
- }
- }
-
- return exports.RELEASE_TYPE.UNKNOWN
-}
-
-/**
- * @summary Check if a version is a stable release
- * @function
- * @public
- *
- * @param {String} version - version
- * @returns {Boolean} whether the version is a stable release
- *
- * @example
- * if (release.isStableRelease('1.0.0')) {
- * console.log('This is a stable release');
- * }
- */
-exports.isStableRelease = (version) => {
- const parsedVersion = semver.parse(version)
- return _.every([
- _.isEmpty(_.get(parsedVersion, [ 'prerelease' ])),
- _.isEmpty(_.get(parsedVersion, [ 'build' ]))
- ])
-}
diff --git a/lib/shared/s3-packages.js b/lib/shared/s3-packages.js
deleted file mode 100644
index 949e4044..00000000
--- a/lib/shared/s3-packages.js
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-'use strict'
-
-const _ = require('lodash')
-const semver = require('semver')
-const Bluebird = require('bluebird')
-const request = Bluebird.promisifyAll(require('request'))
-const xml = Bluebird.promisifyAll(require('xml2js'))
-const release = require('./release')
-const errors = require('./errors')
-
-/**
- * @summary Etcher S3 bucket URLs
- * @namespace BUCKET_URL
- * @public
- */
-exports.BUCKET_URL = {
-
- /**
- * @property {String} PRODUCTION
- * @memberof BUCKET_URL
- * @description
- * Etcher production S3 bucket URL
- */
- PRODUCTION: 'https://resin-production-downloads.s3.amazonaws.com',
-
- /**
- * @property {String} SNAPSHOT
- * @memberof BUCKET_URL
- * @description
- * Etcher snapshot S3 bucket URL
- */
- SNAPSHOT: 'https://resin-nightly-downloads.s3.amazonaws.com'
-
-}
-
-/**
- * @summary Etcher S3 package name
- * @constant
- * @private
- * @type {String}
- */
-const S3_PACKAGE_NAME = 'etcher'
-
-/**
- * @summary Number of packages per Etcher version
- * @constant
- * @private
- * @type {Number}
- */
-const NUMBER_OF_PACKAGES = 8
-
-/**
- * @summary Get the correct S3 bucket url from a release type
- * @function
- * @private
- *
- * @param {RELEASE_TYPE} releaseType - release type
- * @returns {?String} S3 bucket url
- *
- * @example
- * const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.PRODUCTION);
- *
- * if (bucketUrl) {
- * console.log(bucketUrl);
- * }
- */
-exports.getBucketUrlFromReleaseType = (releaseType) => {
- if (releaseType === release.RELEASE_TYPE.PRODUCTION) {
- return exports.BUCKET_URL.PRODUCTION
- }
-
- if (releaseType === release.RELEASE_TYPE.SNAPSHOT) {
- return exports.BUCKET_URL.SNAPSHOT
- }
-
- return null
-}
-
-/**
- * @summary Get all remote versions from an S3 bucket
- * @function
- * @private
- *
- * @description
- * We memoize based on the assumption that the received latest version
- * number will not increase while the application is running.
- *
- * @param {String} bucketUrl - s3 bucket url
- * @fulfil {String[]} - remote versions
- * @returns {Promise}
- *
- * @example
- * s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
- * _.each(versions, (version) => {
- * console.log(version);
- * });
- * });
- */
-exports.getRemoteVersions = _.memoize((bucketUrl) => {
- if (_.isNil(bucketUrl)) {
- return Bluebird.reject(new Error(`Invalid bucket url: ${bucketUrl}`))
- }
-
- /* eslint-disable lodash/prefer-lodash-method */
-
- return request.getAsync(bucketUrl)
-
- /* eslint-enable lodash/prefer-lodash-method */
-
- .get('body')
- .then(xml.parseStringAsync)
- .get('ListBucketResult')
- .then((bucketResult) => {
- return _.get(bucketResult, [ 'Contents' ], [])
- })
- .reduce((accumulator, entry) => {
- const [ name, version ] = _.split(_.first(entry.Key), '/')
-
- if (name === S3_PACKAGE_NAME) {
- if (_.isNil(accumulator[version])) {
- accumulator[version] = 1
- } else {
- accumulator[version] += 1
- }
- }
-
- return accumulator
- }, [])
- .then((versions) => {
- return _.keys(_.pickBy(versions, (occurrences) => {
- return occurrences >= NUMBER_OF_PACKAGES
- }))
- })
- .catch({
- code: 'ENOTFOUND'
- }, {
- code: 'ECONNRESET'
- }, {
- code: 'ECONNREFUSED'
- }, {
- code: 'EACCES'
- }, {
- code: 'ETIMEDOUT'
- }, {
- code: 'EHOSTDOWN'
- }, {
- code: 'EAI_AGAIN'
- }, {
-
- // May happen when behind a proxy
- code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'
-
- }, {
-
- // May happen when behind a proxy
- code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
-
- }, (error) => {
- throw errors.createUserError({
- title: 'Unable to check for updates',
- description: `We got an ${error.code} error in response`,
- code: 'UPDATE_USER_ERROR'
- })
- })
-})
-
-/**
- * @summary Check if a version satisfies a semver range
- * @function
- * @private
- *
- * @description
- * This function is a wrapper around `semver.satisfies`
- * to make it work fine with pre-release versions.
- *
- * @param {String} version - semver version
- * @param {String} range - semver range
- * @returns {Boolean} whether the version satisfies the range
- *
- * @example
- * if (semverSatisfies('1.0.0', '>=1.0.0')) {
- * console.log('The version satisfies the range');
- * }
- */
-const semverSatisfies = (version, range) => {
- // The `semver` module refuses to apply ranges to prerelease versions
- // As a workaround, we drop the prerelease tags, if any, apply the range
- // on that, and keep using the prerelease tag from then on.
- // See https://github.com/npm/node-semver#prerelease-tags
- const strippedVersion = `${semver.major(version)}.${semver.minor(version)}.${semver.patch(version)}`
-
- return semver.satisfies(strippedVersion, range)
-}
-
-/**
- * @summary Get the latest available version for a given release type
- * @function
- * @public
- *
- * @param {String} releaseType - release type
- * @param {Object} [options] - options
- * @param {String} [options.range] - semver range
- * @param {Boolean} [options.includeUnstableChannel=false] - include unstable channel
- * @fulfil {(String|undefined)} - latest version
- * @returns {Promise}
- *
- * @example
- * s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- * range: '>=2.0.0',
- * includeUnstableChannel: true
- * }).then((latestVersion) => {
- * console.log(`The latest version is: ${latestVersion}`);
- * });
- */
-exports.getLatestVersion = (releaseType, options = {}) => {
- // For manual testing purposes
- const ETCHER_FAKE_S3_LATEST_VERSION = process.env.ETCHER_FAKE_S3_LATEST_VERSION
- if (!_.isNil(ETCHER_FAKE_S3_LATEST_VERSION)) {
- if (release.getReleaseType(ETCHER_FAKE_S3_LATEST_VERSION) === releaseType) {
- return Bluebird.resolve(ETCHER_FAKE_S3_LATEST_VERSION)
- }
-
- return Bluebird.resolve()
- }
-
- const bucketUrl = exports.getBucketUrlFromReleaseType(releaseType)
- if (_.isNil(bucketUrl)) {
- return Bluebird.reject(new Error(`No bucket URL found for release type: ${releaseType}`))
- }
-
- /* eslint-disable lodash/prefer-lodash-method */
- return exports.getRemoteVersions(bucketUrl).filter((version) => {
- /* eslint-enable lodash/prefer-lodash-method */
- if (_.some([
-
- // This check allows us to ignore snapshot builds in production
- // buckets, and viceversa, which could have been uploaded by mistake.
- release.getReleaseType(version) !== releaseType,
-
- !release.isStableRelease(version) && !options.includeUnstableChannel
- ])) {
- return false
- }
-
- return semverSatisfies(version, options.range || '*')
- }).then((versions) => {
- return _.last(versions.sort(semver.compare))
- })
-}
diff --git a/lib/shared/utils.js b/lib/shared/utils.js
index fd6688de..c356da5f 100644
--- a/lib/shared/utils.js
+++ b/lib/shared/utils.js
@@ -17,6 +17,8 @@
'use strict'
const _ = require('lodash')
+const Bluebird = require('bluebird')
+const request = Bluebird.promisifyAll(require('request'))
const errors = require('./errors')
/**
@@ -156,3 +158,13 @@ exports.hasProps = (obj, props) => {
return _.has(obj, prop)
})
}
+
+/**
+* @summary Get etcher configs stored online
+* @param {String} - url where config.json is stored
+*/
+// eslint-disable-next-line
+exports.getConfig = (configUrl) => {
+ return request.getAsync(configUrl, { json: true })
+ .get('body')
+}
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index ec962006..0765f1eb 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -1639,7 +1639,6 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
"requires": {
"sprintf-js": "~1.0.2"
},
@@ -1647,8 +1646,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
}
}
},
@@ -2455,8 +2453,7 @@
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
- "dev": true
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
},
"buffer-xor": {
"version": "1.0.3",
@@ -2577,7 +2574,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
"requires": {
"ms": "^2.1.1"
}
@@ -4424,6 +4420,38 @@
"integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==",
"dev": true
},
+ "electron-updater": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.0.6.tgz",
+ "integrity": "sha512-JPGLME6fxJcHG8hX7HWFl6Aew6iVm0DkcrENreKa5SUJCHG+uUaAhxDGDt+YGcNkyx1uJ6eBGMvFxDTLUv67pg==",
+ "requires": {
+ "bluebird-lst": "^1.0.6",
+ "builder-util-runtime": "~8.1.0",
+ "fs-extra-p": "^7.0.0",
+ "js-yaml": "^3.12.0",
+ "lazy-val": "^1.0.3",
+ "lodash.isequal": "^4.5.0",
+ "pako": "^1.0.7",
+ "semver": "^5.6.0",
+ "source-map-support": "^0.5.9"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
+ "source-map-support": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
+ "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ }
+ }
+ },
"electron-window": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/electron-window/-/electron-window-0.8.1.tgz",
@@ -5194,8 +5222,7 @@
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"esquery": {
"version": "1.0.1",
@@ -5891,7 +5918,6 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
@@ -7070,7 +7096,6 @@
"version": "3.12.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz",
"integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==",
- "dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -7142,7 +7167,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
"requires": {
"graceful-fs": "^4.1.6"
}
@@ -7330,6 +7354,11 @@
"resolved": "https://registry.npmjs.org/lodash.frompairs/-/lodash.frompairs-4.0.1.tgz",
"integrity": "sha1-vE5SB/onV8E25XNhTpZkUGsrG9I="
},
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ },
"lodash.kebabcase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@@ -8972,8 +9001,7 @@
"pako": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz",
- "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==",
- "dev": true
+ "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA=="
},
"parallel-transform": {
"version": "1.1.0",
@@ -12576,8 +12604,7 @@
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
- "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
- "dev": true
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"unpipe": {
"version": "1.0.0",
diff --git a/package.json b/package.json
index 2c377c5e..dcc83cba 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,7 @@
},
"scripts": {
"test": "make lint test sanity-checks",
- "start": "electron lib/start.js",
+ "start": "./node_modules/.bin/electron .",
"configure": "node-gyp configure",
"build": "node-gyp build",
"install": "node-gyp rebuild",
@@ -49,6 +49,7 @@
"debug": "^3.1.0",
"electron-is-running-in-asar": "^1.0.0",
"etcher-sdk": "^2.0.1",
+ "electron-updater": "4.0.6",
"flexboxgrid": "^6.3.0",
"immutable": "^3.8.1",
"inactivity-timer": "^1.0.0",
diff --git a/tests/gui/components/update-notifier.spec.js b/tests/gui/components/update-notifier.spec.js
deleted file mode 100644
index a68af42d..00000000
--- a/tests/gui/components/update-notifier.spec.js
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-'use strict'
-
-const m = require('mochainon')
-const _ = require('lodash')
-const units = require('../../../lib/shared/units')
-const updateNotifier = require('../../../lib/gui/app/components/update-notifier')
-
-describe('Browser: updateNotifier', function () {
- describe('.UPDATE_NOTIFIER_SLEEP_DAYS', function () {
- it('should be an integer', function () {
- m.chai.expect(_.isInteger(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS)).to.be.true
- })
-
- it('should be greater than 0', function () {
- m.chai.expect(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS > 0).to.be.true
- })
- })
-
- describe('.shouldCheckForUpdates()', function () {
- const UPDATE_NOTIFIER_SLEEP_MS = units.daysToMilliseconds(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS)
-
- _.each([
-
- // Given the `lastSleptUpdateNotifier` was never updated
-
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: undefined,
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: undefined,
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: undefined,
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '1.0.0',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '1.0.0+6374412',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '1.0.0+foo',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: undefined,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
-
- // Given the `lastSleptUpdateNotifier` was very recently updated
-
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '1.0.0',
- currentVersion: '1.0.0'
- },
- expected: false
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+6374412',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+foo',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
-
- // Given the `lastSleptUpdateNotifier` was updated in the future
-
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '1.0.0',
- currentVersion: '1.0.0'
- },
- expected: false
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+6374412',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+foo',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
-
- // Given the `lastSleptUpdateNotifier` was updated far in the future
-
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '1.0.0',
- currentVersion: '1.0.0'
- },
- expected: false
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+6374412',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+foo',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
-
- // Given the `lastSleptUpdateNotifier` was updated long ago
-
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '1.0.0',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+6374412',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '1.0.0+foo',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '0.0.0',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+6374412'
- },
- expected: true
- },
- {
- options: {
- lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
- lastSleptUpdateNotifierVersion: '99.9.9',
- currentVersion: '1.0.0+foo'
- },
- expected: true
- }
-
- ], (testCase) => {
- it(_.join([
- `should return ${testCase.expected} if`,
- `lastSleptUpdateNotifier=${testCase.options.lastSleptUpdateNotifier},`,
- `lastSleptUpdateNotifierVersion=${testCase.options.lastSleptUpdateNotifierVersion}, and`,
- `currentVersion=${testCase.options.currentVersion}`
- ], ' '), function () {
- m.chai.expect(updateNotifier.shouldCheckForUpdates(testCase.options)).to.equal(testCase.expected)
- })
- })
- })
-})
diff --git a/tests/shared/release.spec.js b/tests/shared/release.spec.js
deleted file mode 100644
index 5c38fdbf..00000000
--- a/tests/shared/release.spec.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-'use strict'
-
-const m = require('mochainon')
-const _ = require('lodash')
-const release = require('../../lib/shared/release')
-
-describe('Shared: Release', function () {
- describe('.RELEASE_TYPE', function () {
- it('should be a plain object', function () {
- m.chai.expect(_.isPlainObject(release.RELEASE_TYPE)).to.be.true
- })
-
- it('should contain keys with different values', function () {
- const keys = _.keys(release.RELEASE_TYPE)
- const uniqueValues = _.uniq(_.values(release.RELEASE_TYPE))
- m.chai.expect(_.size(keys)).to.equal(_.size(uniqueValues))
- })
- })
-
- describe('.getReleaseType()', function () {
- it('should return the unknown release type if the version is not valid semver', function () {
- const releaseType = release.getReleaseType('foo.bar')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN)
- })
-
- describe('given the version has a short git commit hash build number', function () {
- it('should return the snapshot release type', function () {
- const releaseType = release.getReleaseType('1.0.0+6374412')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT)
- })
-
- it('should return the snapshot release type if the version has a pre release tag', function () {
- const releaseType = release.getReleaseType('1.0.0-beta.19+6374412')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT)
- })
- })
-
- describe('given the version has a long git commit hash build number', function () {
- it('should return the snapshot release type', function () {
- const releaseType = release.getReleaseType('1.0.0+6374412554b034799bfc6e13b4e39c3f5e6386e6')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT)
- })
-
- it('should return the snapshot release type if the version has a pre release tag', function () {
- const releaseType = release.getReleaseType('1.0.0-beta.19+6374412554b034799bfc6e13b4e39c3f5e6386e6')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT)
- })
- })
-
- describe('given the version has no build number', function () {
- it('should return the production release type', function () {
- const releaseType = release.getReleaseType('1.0.0')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION)
- })
-
- it('should return the production release type if the version has a pre release tag', function () {
- const releaseType = release.getReleaseType('1.0.0-beta.19')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION)
- })
- })
-
- describe('given a build number that is not a git commit hash', function () {
- it('should return the unknown release type', function () {
- const releaseType = release.getReleaseType('1.0.0+foo')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN)
- })
-
- it('should return the unknown release type if the version has a pre release tag', function () {
- const releaseType = release.getReleaseType('1.0.0-beta.19+foo')
- m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN)
- })
- })
- })
-
- describe('.isStableRelease()', function () {
- it('should return true if given a production stable version', function () {
- m.chai.expect(release.isStableRelease('1.0.0')).to.be.true
- })
-
- it('should return false if given a production release candidate version', function () {
- m.chai.expect(release.isStableRelease('1.0.0-rc.2')).to.be.false
- })
-
- it('should return false if given a production beta version', function () {
- m.chai.expect(release.isStableRelease('1.0.0-beta.1')).to.be.false
- })
-
- it('should return false if given a snapshot stable version', function () {
- m.chai.expect(release.isStableRelease('1.0.0+6374412')).to.be.false
- })
-
- it('should return false if given a snapshot release candidate version', function () {
- m.chai.expect(release.isStableRelease('1.0.0-rc.2+6374412')).to.be.false
- })
-
- it('should return false if given a snapshot beta version', function () {
- m.chai.expect(release.isStableRelease('1.0.0-beta.1+6374412')).to.be.false
- })
- })
-})
diff --git a/tests/shared/s3-packages.spec.js b/tests/shared/s3-packages.spec.js
deleted file mode 100644
index 1b00e500..00000000
--- a/tests/shared/s3-packages.spec.js
+++ /dev/null
@@ -1,1199 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-'use strict'
-
-const m = require('mochainon')
-const Bluebird = require('bluebird')
-const request = Bluebird.promisifyAll(require('request'))
-const nock = require('nock')
-const s3Packages = require('../../lib/shared/s3-packages')
-const release = require('../../lib/shared/release')
-const errors = require('../../lib/shared/errors')
-
-describe('Shared: s3Packages', function () {
- describe('.getBucketUrlFromReleaseType()', function () {
- it('should return the production URL if given a production release type', function () {
- const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.PRODUCTION)
- m.chai.expect(bucketUrl).to.equal(s3Packages.BUCKET_URL.PRODUCTION)
- })
-
- it('should return the snapshot URL if given a snapshot release type', function () {
- const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.SNAPSHOT)
- m.chai.expect(bucketUrl).to.equal(s3Packages.BUCKET_URL.SNAPSHOT)
- })
-
- it('should return null if given an unknown release type', function () {
- const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.UNKNOWN)
- m.chai.expect(bucketUrl).to.be.null
- })
- })
-
- describe('.getRemoteVersions()', function () {
- beforeEach(function () {
- s3Packages.getRemoteVersions.cache.clear()
- })
-
- it('should be rejected if url is null', function (done) {
- s3Packages.getRemoteVersions(null).catch((error) => {
- m.chai.expect(error).to.be.an.instanceof(Error)
- m.chai.expect(error.message).to.equal('Invalid bucket url: null')
- done()
- })
- })
-
- describe('given an empty bucket', function () {
- beforeEach(function () {
- nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
-
- resin-production-downloads
-
-
- 1000
- false
-
- `)
- })
-
- afterEach(function () {
- nock.cleanAll()
- })
-
- it('should resolve an empty array', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
- m.chai.expect(versions).to.deep.equal([])
- done()
- }).catch(done)
- })
- })
-
- describe('given many versions', function () {
- beforeEach(function () {
- nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
-
- resin-production-downloads
-
-
- 1000
- false
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-darwin-x64.dmg
- 2016-11-28T16:12:28.000Z
- "5818b791238e7a03c2128149cbcabfd6"
- 73532901
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-darwin-x64.zip
- 2016-11-28T16:52:26.000Z
- "e9b4e7350e352298de293bb44aa72e9c"
- 154896510
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-linux-x64.zip
- 2016-11-28T18:27:10.000Z
- "40e2b620d2aecb87e44c8675f2028d03"
- 71186664
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-linux-x86.zip
- 2016-11-28T17:56:56.000Z
- "e585bd96708d79845015cc57d86a3f60"
- 72576097
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x64.exe
- 2016-11-28T20:01:43.000Z
- "f6134fedb835af59db063810fb511ef0"
- 84717856
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x64.zip
- 2016-11-28T20:21:55.000Z
- "8c6db54d2210355563519c67c1618664"
- 82056508
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x86.exe
- 2016-11-28T20:39:43.000Z
- "fdcc21ec9a7312b781c03b8d469e843d"
- 74151760
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x86.zip
- 2016-11-28T20:57:31.000Z
- "992c2c021575d5909dbe77a759b67464"
- 71846504
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-darwin-x64.dmg
- 2017-01-17T00:58:49.000Z
- "81a1b5a330a230ca6d89db97b3399420"
- 58442097
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-darwin-x64.zip
- 2017-01-17T01:18:56.000Z
- "81b438a9f7b2d4c871cfbd5aedd96975"
- 139834277
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x64.zip
- 2017-01-17T02:01:01.000Z
- "35660b65233082a10c00828ea1e50c38"
- 55960697
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x86.zip
- 2017-01-17T02:18:20.000Z
- "1bafcc0d5d2c8d43bd2ce8948bb51a8b"
- 57331229
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.exe
- 2017-01-17T05:48:02.000Z
- "b0a6154ec79d17618632ac62eb30b44e"
- 84802632
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.zip
- 2017-01-17T06:14:46.000Z
- "f25c5dfa8378e608c25fafbe65e90162"
- 82235087
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x86.exe
- 2017-01-17T06:42:58.000Z
- "183b6eb648b0a78a1e99c9182f90194e"
- 74264232
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x86.zip
- 2017-01-17T07:05:55.000Z
- "d8d860013f038bed3f52534053b08382"
- 72042525
- STANDARD
-
-
- `)
- })
-
- afterEach(function () {
- nock.cleanAll()
- })
-
- it('should resolve all the available versions', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
- m.chai.expect(versions).to.deep.equal([
- '1.0.0-beta.17',
- '1.0.0-beta.18'
- ])
- done()
- }).catch(done)
- })
- })
-
- describe('given a version is being uploaded', function () {
- beforeEach(function () {
- nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
-
- resin-production-downloads
-
-
- 1000
- false
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-darwin-x64.dmg
- 2016-11-28T16:12:28.000Z
- "5818b791238e7a03c2128149cbcabfd6"
- 73532901
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-darwin-x64.zip
- 2016-11-28T16:52:26.000Z
- "e9b4e7350e352298de293bb44aa72e9c"
- 154896510
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-linux-x64.zip
- 2016-11-28T18:27:10.000Z
- "40e2b620d2aecb87e44c8675f2028d03"
- 71186664
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-linux-x86.zip
- 2016-11-28T17:56:56.000Z
- "e585bd96708d79845015cc57d86a3f60"
- 72576097
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x64.exe
- 2016-11-28T20:01:43.000Z
- "f6134fedb835af59db063810fb511ef0"
- 84717856
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x64.zip
- 2016-11-28T20:21:55.000Z
- "8c6db54d2210355563519c67c1618664"
- 82056508
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x86.exe
- 2016-11-28T20:39:43.000Z
- "fdcc21ec9a7312b781c03b8d469e843d"
- 74151760
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x86.zip
- 2016-11-28T20:57:31.000Z
- "992c2c021575d5909dbe77a759b67464"
- 71846504
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-darwin-x64.dmg
- 2017-01-17T00:58:49.000Z
- "81a1b5a330a230ca6d89db97b3399420"
- 58442097
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-darwin-x64.zip
- 2017-01-17T01:18:56.000Z
- "81b438a9f7b2d4c871cfbd5aedd96975"
- 139834277
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x64.zip
- 2017-01-17T02:01:01.000Z
- "35660b65233082a10c00828ea1e50c38"
- 55960697
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x86.zip
- 2017-01-17T02:18:20.000Z
- "1bafcc0d5d2c8d43bd2ce8948bb51a8b"
- 57331229
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.exe
- 2017-01-17T05:48:02.000Z
- "b0a6154ec79d17618632ac62eb30b44e"
- 84802632
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.zip
- 2017-01-17T06:14:46.000Z
- "f25c5dfa8378e608c25fafbe65e90162"
- 82235087
- STANDARD
-
-
- etcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x86.exe
- 2017-01-17T06:42:58.000Z
- "183b6eb648b0a78a1e99c9182f90194e"
- 74264232
- STANDARD
-
-
- `)
- })
-
- afterEach(function () {
- nock.cleanAll()
- })
-
- it('should resolve all the entirely available versions', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
- m.chai.expect(versions).to.deep.equal([
- '1.0.0-beta.17'
- ])
- done()
- }).catch(done)
- })
- })
-
- describe('given other programs in the bucket', function () {
- beforeEach(function () {
- nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
-
- resin-production-downloads
-
-
- 1000
- false
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-darwin-x64.dmg
- 2016-11-28T16:12:28.000Z
- "5818b791238e7a03c2128149cbcabfd6"
- 73532901
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-darwin-x64.zip
- 2016-11-28T16:52:26.000Z
- "e9b4e7350e352298de293bb44aa72e9c"
- 154896510
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-linux-x64.zip
- 2016-11-28T18:27:10.000Z
- "40e2b620d2aecb87e44c8675f2028d03"
- 71186664
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-linux-x86.zip
- 2016-11-28T17:56:56.000Z
- "e585bd96708d79845015cc57d86a3f60"
- 72576097
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x64.exe
- 2016-11-28T20:01:43.000Z
- "f6134fedb835af59db063810fb511ef0"
- 84717856
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x64.zip
- 2016-11-28T20:21:55.000Z
- "8c6db54d2210355563519c67c1618664"
- 82056508
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x86.exe
- 2016-11-28T20:39:43.000Z
- "fdcc21ec9a7312b781c03b8d469e843d"
- 74151760
- STANDARD
-
-
- etcher/1.0.0-beta.17/Etcher-1.0.0-beta.17-win32-x86.zip
- 2016-11-28T20:57:31.000Z
- "992c2c021575d5909dbe77a759b67464"
- 71846504
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-darwin-x64.dmg
- 2017-01-17T00:58:49.000Z
- "81a1b5a330a230ca6d89db97b3399420"
- 58442097
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-darwin-x64.zip
- 2017-01-17T01:18:56.000Z
- "81b438a9f7b2d4c871cfbd5aedd96975"
- 139834277
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x64.zip
- 2017-01-17T02:01:01.000Z
- "35660b65233082a10c00828ea1e50c38"
- 55960697
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x86.zip
- 2017-01-17T02:18:20.000Z
- "1bafcc0d5d2c8d43bd2ce8948bb51a8b"
- 57331229
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.exe
- 2017-01-17T05:48:02.000Z
- "b0a6154ec79d17618632ac62eb30b44e"
- 84802632
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.zip
- 2017-01-17T06:14:46.000Z
- "f25c5dfa8378e608c25fafbe65e90162"
- 82235087
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x86.exe
- 2017-01-17T06:42:58.000Z
- "183b6eb648b0a78a1e99c9182f90194e"
- 74264232
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x86.zip
- 2017-01-17T07:05:55.000Z
- "d8d860013f038bed3f52534053b08382"
- 72042525
- STANDARD
-
-
- `)
- })
-
- afterEach(function () {
- nock.cleanAll()
- })
-
- it('should not consider the other packages', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
- m.chai.expect(versions).to.deep.equal([
- '1.0.0-beta.17'
- ])
- done()
- }).catch(done)
- })
- })
-
- describe('given only other programs in the bucket', function () {
- beforeEach(function () {
- nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(200, `
-
- resin-production-downloads
-
-
- 1000
- false
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-darwin-x64.zip
- 2017-01-17T01:18:56.000Z
- "81b438a9f7b2d4c871cfbd5aedd96975"
- 139834277
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x64.zip
- 2017-01-17T02:01:01.000Z
- "35660b65233082a10c00828ea1e50c38"
- 55960697
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-linux-x86.zip
- 2017-01-17T02:18:20.000Z
- "1bafcc0d5d2c8d43bd2ce8948bb51a8b"
- 57331229
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.exe
- 2017-01-17T05:48:02.000Z
- "b0a6154ec79d17618632ac62eb30b44e"
- 84802632
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x64.zip
- 2017-01-17T06:14:46.000Z
- "f25c5dfa8378e608c25fafbe65e90162"
- 82235087
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x86.exe
- 2017-01-17T06:42:58.000Z
- "183b6eb648b0a78a1e99c9182f90194e"
- 74264232
- STANDARD
-
-
- notEtcher/1.0.0-beta.18/Etcher-1.0.0-beta.18-win32-x86.zip
- 2017-01-17T07:05:55.000Z
- "d8d860013f038bed3f52534053b08382"
- 72042525
- STANDARD
-
-
- `)
- })
-
- afterEach(function () {
- nock.cleanAll()
- })
-
- it('should resolve an empty array', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
- m.chai.expect(versions).to.deep.equal([])
- done()
- }).catch(done)
- })
- })
-
- describe('given an unsuccessful request', function () {
- beforeEach(function () {
- nock(s3Packages.BUCKET_URL.PRODUCTION).get('/').reply(500)
- })
-
- afterEach(function () {
- nock.cleanAll()
- })
-
- it('should be rejected with a non-user error', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(error).to.be.an.instanceof(Error)
- m.chai.expect(errors.isUserError(error)).to.be.false
- done()
- })
- })
- })
-
- describe('given ENOTFOUND', function () {
- beforeEach(function () {
- const error = new Error('ENOTFOUND')
- error.code = 'ENOTFOUND'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given ETIMEDOUT', function () {
- beforeEach(function () {
- const error = new Error('ETIMEDOUT')
- error.code = 'ETIMEDOUT'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given EHOSTDOWN', function () {
- beforeEach(function () {
- const error = new Error('EHOSTDOWN')
- error.code = 'EHOSTDOWN'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given EAI_AGAIN', function () {
- beforeEach(function () {
- const error = new Error('EAI_AGAIN')
- error.code = 'EAI_AGAIN'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given ECONNRESET', function () {
- beforeEach(function () {
- const error = new Error('ECONNRESET')
- error.code = 'ECONNRESET'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given ECONNREFUSED', function () {
- beforeEach(function () {
- const error = new Error('ECONNREFUSED')
- error.code = 'ECONNREFUSED'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given EACCES', function () {
- beforeEach(function () {
- const error = new Error('EACCES')
- error.code = 'EACCES'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given UNABLE_TO_GET_ISSUER_CERT_LOCALLY', function () {
- beforeEach(function () {
- const error = new Error('UNABLE_TO_GET_ISSUER_CERT_LOCALLY')
- error.code = 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
-
- describe('given UNABLE_TO_VERIFY_LEAF_SIGNATURE', function () {
- beforeEach(function () {
- const error = new Error('UNABLE_TO_VERIFY_LEAF_SIGNATURE')
- error.code = 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
-
- this.requestGetAsyncStub = m.sinon.stub(request, 'getAsync')
- this.requestGetAsyncStub.returns(Bluebird.reject(error))
- })
-
- afterEach(function () {
- this.requestGetAsyncStub.restore()
- })
-
- it('should be rejected with a user error with code UPDATE_USER_ERROR', function (done) {
- s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).catch((error) => {
- m.chai.expect(errors.isUserError(error)).to.be.true
- m.chai.expect(error.code).to.equal('UPDATE_USER_ERROR')
- done()
- })
- })
- })
- })
-
- describe('.getLatestVersion()', function () {
- describe('given a valid production ETCHER_FAKE_S3_LATEST_VERSION environment variable', function () {
- beforeEach(function () {
- process.env.ETCHER_FAKE_S3_LATEST_VERSION = '9.9.9'
- })
-
- afterEach(function () {
- Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION')
- })
-
- describe('given a production release type', function () {
- it('should resolve the variable', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('9.9.9')
- done()
- }).catch(done)
- })
- })
-
- describe('given a snapshot release type', function () {
- it('should resolve undefined', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => {
- m.chai.expect(latestVersion).to.be.undefined
- done()
- }).catch(done)
- })
- })
- })
-
- describe('given a valid snapshot ETCHER_FAKE_S3_LATEST_VERSION environment variable', function () {
- beforeEach(function () {
- process.env.ETCHER_FAKE_S3_LATEST_VERSION = '9.9.9+7b47334'
- })
-
- afterEach(function () {
- Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION')
- })
-
- describe('given a snapshot release type', function () {
- it('should resolve the variable', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('9.9.9+7b47334')
- done()
- }).catch(done)
- })
- })
-
- describe('given a production release type', function () {
- it('should resolve undefined', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
- m.chai.expect(latestVersion).to.be.undefined
- done()
- }).catch(done)
- })
- })
- })
-
- describe('given an invalid ETCHER_FAKE_S3_LATEST_VERSION environment variable', function () {
- beforeEach(function () {
- process.env.ETCHER_FAKE_S3_LATEST_VERSION = 'foo'
- })
-
- afterEach(function () {
- Reflect.deleteProperty(process.env, 'ETCHER_FAKE_S3_LATEST_VERSION')
- })
-
- it('should resolve undefined', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
- m.chai.expect(latestVersion).to.be.undefined
- done()
- }).catch(done)
- })
- })
-
- describe('given an invalid release type', function () {
- it('should be rejected with an error', function (done) {
- s3Packages.getLatestVersion('foobar').catch((error) => {
- m.chai.expect(error).to.be.an.instanceof(Error)
- m.chai.expect(error.message).to.equal('No bucket URL found for release type: foobar')
- done()
- })
- })
- })
-
- describe('given no remote versions', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should resolve undefined', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
- m.chai.expect(latestVersion).to.be.undefined
- done()
- }).catch(done)
- })
- })
-
- describe('given a single version', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([ '0.5.0' ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should resolve the version', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('0.5.0')
- done()
- }).catch(done)
- })
- })
-
- describe('given multiple versions', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '2.1.0',
- '1.0.0',
- '0.5.0',
- '0.4.0'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should resolve the latest version', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('2.1.0')
- done()
- }).catch(done)
- })
- })
-
- describe('given a greater production version in a snapshot bucket', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '1.0.0+abb6139',
- '2.0.0'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should ignore production versions if includeUnstableChannel is true', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, {
- includeUnstableChannel: true
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('1.0.0+abb6139')
- done()
- }).catch(done)
- })
-
- it('should return undefined if includeUnstableChannel is false', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, {
- includeUnstableChannel: false
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.be.undefined
- done()
- }).catch(done)
- })
- })
-
- describe('given a greater snapshot version in a production bucket', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '1.0.0',
- '2.0.0+abb6139'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should ignore snapshot versions', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('1.0.0')
- done()
- }).catch(done)
- })
- })
-
- describe('given production v1, v2, and v3 remote versions', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '3.0.1',
- '3.0.0',
- '2.1.1',
- '2.1.0',
- '2.0.0',
- '1.2.0',
- '1.1.0',
- '1.0.2',
- '1.0.1',
- '1.0.0'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should be able to resolve the latest v1 version with a semver range', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- range: '<2.0.0'
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('1.2.0')
- done()
- }).catch(done)
- })
-
- it('should be able to resolve the latest v2 version with a semver range', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- range: '>=2.0.0 <3.0.0'
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('2.1.1')
- done()
- }).catch(done)
- })
-
- it('should be able to resolve the latest v3 version with a semver range', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- range: '>=3.0.0'
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('3.0.1')
- done()
- }).catch(done)
- })
-
- it('should resolve the latest version if includeUnstableChannel is true', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- includeUnstableChannel: true
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('3.0.1')
- done()
- }).catch(done)
- })
-
- it('should resolve the latest version if includeUnstableChannel is false', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- includeUnstableChannel: false
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('3.0.1')
- done()
- }).catch(done)
- })
- })
-
- describe('given unstable and stable versions where the last version is stable', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '3.0.1',
- '3.0.0-beta.2',
- '3.0.0-beta.1',
- '2.1.1',
- '2.1.0-beta.15',
- '1.0.0'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should resolve the latest stable version if includeUnstableChannel is false', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- includeUnstableChannel: false
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('3.0.1')
- done()
- }).catch(done)
- })
-
- it('should resolve the latest stable version if includeUnstableChannel is true', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- includeUnstableChannel: true
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('3.0.1')
- done()
- }).catch(done)
- })
- })
-
- describe('given unstable and stable versions where the last version is unstable', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '3.0.2-beta.1',
- '3.0.1',
- '3.0.0-beta.2',
- '3.0.0-beta.1',
- '2.1.1',
- '2.1.0-beta.15',
- '1.0.0'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should resolve the latest stable version if includeUnstableChannel is false', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- includeUnstableChannel: false
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('3.0.1')
- done()
- }).catch(done)
- })
-
- it('should resolve the latest unstable version if includeUnstableChannel is true', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- includeUnstableChannel: true
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('3.0.2-beta.1')
- done()
- }).catch(done)
- })
- })
-
- describe('given pre-release production remote versions', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '2.0.0-beta.3',
- '2.0.0-beta.2',
- '2.0.0-beta.1',
- '2.0.0-beta.0',
- '1.0.0-beta.19',
- '1.0.0-beta.18',
- '1.0.0-beta.17',
- '1.0.0-beta.16'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should be able to resolve the latest v2 pre-release version with a non pre-release semver range', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- range: '>=2.0.0',
- includeUnstableChannel: true
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('2.0.0-beta.3')
- done()
- }).catch(done)
- })
-
- it('should resolve undefined if includeUnstableChannel is false', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
- includeUnstableChannel: false
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.be.undefined
- done()
- }).catch(done)
- })
- })
-
- describe('given pre-release snapshot remote versions', function () {
- beforeEach(function () {
- this.getRemoteVersionsStub = m.sinon.stub(s3Packages, 'getRemoteVersions')
- this.getRemoteVersionsStub.returns(Bluebird.resolve([
- '2.0.0-beta.3+5370ef2',
- '2.0.0-beta.2+ff495a4',
- '2.0.0-beta.1+07b6dd2',
- '2.0.0-beta.0+4cd8776',
- '1.0.0-beta.19+7b47334',
- '1.0.0-beta.18+7fe503c',
- '1.0.0-beta.17+76aa05f',
- '1.0.0-beta.16+802d9ab'
- ]))
- })
-
- afterEach(function () {
- this.getRemoteVersionsStub.restore()
- })
-
- it('should be able to resolve the latest v2 pre-release version with a non pre-release semver range', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, {
- range: '>=2.0.0',
- includeUnstableChannel: true
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.equal('2.0.0-beta.3+5370ef2')
- done()
- }).catch(done)
- })
-
- it('should resolve undefined if includeUnstableChannel is false', function (done) {
- s3Packages.getLatestVersion(release.RELEASE_TYPE.SNAPSHOT, {
- includeUnstableChannel: false
- }).then((latestVersion) => {
- m.chai.expect(latestVersion).to.be.undefined
- done()
- }).catch(done)
- })
- })
- })
-})