balena-supervisor/automation/deploy-to-resin.js
Pablo Carranza Velez 60a8ab85f4 Add a deploy-to-resin.js and automatically deploy to the Resin API on master builds
Also, make all of the arch builds part of the Circle workflow.

Change-Type: patch
Signed-off-by: Pablo Carranza Velez <pablo@resin.io>
2017-07-20 21:22:25 -03:00

92 lines
2.4 KiB
JavaScript

// Deploy a supervisor image as a supervisor_release in the Resin API
//
// Environment variables:
// This program deploys only for device types where the architecture matches $ARCH.
// It deploys to the API specified by $API_ENDPOINT and using a provided $API_TOKEN or $API_KEY
// (if both are set, API_TOKEN is preferred).
// The tag to deploy must be passed as $TAG.
//
const PineJsClient = require('pinejs-client');
const Promise = require('bluebird');
const _ = require('lodash');
const url = require('url');
const apiEndpoint = process.env.API_ENDPOINT;
const apikey = process.env.API_KEY;
const arch = process.env.ARCH;
const tag = process.env.TAG;
const apiToken = process.env.API_TOKEN;
if (_.isEmpty(apikey) && _.isEmpty(apiToken)) {
console.error('Skipping deploy due to empty API_KEY and API_TOKEN');
process.exit(0);
}
if (_.isEmpty(apiEndpoint)) {
console.error('Please set a valid $API_ENDPOINT');
process.exit(1);
}
if (_.isEmpty(tag)) {
console.error('Please set a $TAG to deploy');
process.exit(1);
}
const supportedArchitectures = [ 'amd64', 'rpi', 'aarch64', 'armel', 'i386', 'armv7hf' ];
if (_.isEmpty(arch) || !_.includes(supportedArchitectures, arch)) {
console.error('Invalid architecture ' + arch);
process.exit(1);
}
const requestOpts = {
gzip: true,
timeout: 30000
};
if (!_.isEmpty(apiToken)) {
requestOpts.headers = {
Authorization: 'Bearer ' + apiToken
};
}
const apiEndpointWithPrefix = url.resolve(apiEndpoint, '/v2/')
const resinApi = new PineJsClient({
apiPrefix: apiEndpointWithPrefix,
passthrough: requestOpts
});
resinApi._request(_.extend({
url: apiEndpoint + '/config/device-types',
method: 'GET'
}, resinApi.passthrough))
.then( (deviceTypes) => {
// This is a critical step so we better do it serially
return Promise.mapSeries(deviceTypes, (deviceType) => {
if (deviceType.arch === arch) {
const customOptions = {};
if (_.isEmpty(apiToken)) {
customOptions.apikey = apikey;
}
console.log(`Deploying ${supervisor_version} for ${device_type}`);
return resinApi.post({
resource: 'supervisor_release',
body: {
image_name: `registry.resinstaging.io/resin/${arch}-supervisor`,
supervisor_version: tag,
device_type: deviceType.slug,
is_public: true
},
customOptions
});
}
});
})
.then( () => {
process.exit(0);
})
.catch( (err) => {
console.error(`Error when deploying the supervisor to ${apiEndpoint}`, err, err.stack);
process.exit(1);
});