Skip to content

Commit 445830d

Browse files
djanhjoscraswell
authored andcommitted
support for deploying to services/ui_api release APIs (#45)
1 parent 3443a85 commit 445830d

3 files changed

Lines changed: 64 additions & 24 deletions

File tree

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,27 @@
22

33
# ember-cli-deploy-rest
44

5-
An ember-cli-deploy plugin to upload index.html files to a REST API. This is useful if you wrap your Ember app in a traditional web app, such as Rails.
5+
A modified ember-cli-deploy plugin to upload index.html files to a REST API. This is useful if you wrap your Ember app in a traditional web app, such as Rails.
66

77
## API requirements
88

9-
Your REST API should follow the spec below. Note that the base URL is configurable; for these examples we assume it's `https://yourapp.com/ember-revisions`.
9+
Your REST API should follow the spec below. Note that the base URL is configurable.
10+
11+
The original implementation assumes an example base URL of `https://yourapp.com/ember-revisions`.
1012

1113
- Authenticate with basic auth (please use HTTPS!)
1214
- `GET /ember-revisions`: returns a JSON array of objects for the stored revisions. Fields are `id` (revision key), `created_at` (upload timestamp), `revision_data` (usually contains revision metadata) and `current` (boolean)
1315
- `POST /ember-revisions`: expects a JSON body with fields `id` (revision key) and `body` (the index.html contents)
1416
- `PUT /ember-revisions/<id>`: activates the revision with key `id`
1517

18+
Our Customer.io implementation has slightly different endpoints and parameters.
19+
20+
- Authenticate with basic auth (please use HTTPS!), utilizing the prefix `Bearer`
21+
- `GET /`: returns a JSON array of objects for all apps (ONLY ON HYDRA, NOT SERVICES)
22+
- `GET /<app_name>`: returns a JSON array of objects for the specified app
23+
- `POST /<app_name>`: expects a JSON body with the fields `version` (revision key) and `body` (the index.html contents)
24+
- `PUT /<app_name>/<version>/activate`: activates the specified app with the specified version
25+
1626
## Quick Start
1727

1828
To get up and running quickly, do the following:

index.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ module.exports = {
2121

2222
// eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects
2323
defaultConfig: {
24+
appName: 'journeys',
2425
useHydra: false,
26+
useServices: false,
2527
useBearerToken: false,
2628
bearer: undefined,
2729
filePattern: 'index.html',
@@ -64,6 +66,7 @@ module.exports = {
6466

6567
upload: function () {
6668
var useHydra = this.readConfig('useHydra');
69+
var useServices = this.readConfig('useServices');
6770
var restClient = this.readConfig('restClient');
6871
var revisionKey = this.readConfig('revisionKey');
6972
var distDir = this.readConfig('distDir');
@@ -77,7 +80,15 @@ module.exports = {
7780

7881
if (useHydra) {
7982
return this._readFileContents(filePath)
80-
.then(restClient.uploadAppRelease.bind(restClient, keyPrefix, revisionKey, appName))
83+
.then(restClient.uploadReleaseToHydra.bind(restClient, keyPrefix, revisionKey, appName))
84+
.then(this._uploadSuccessMessage.bind(this))
85+
.then(function (key) {
86+
return { key: key };
87+
})
88+
.catch(this._errorMessage.bind(this));
89+
} else if (useServices) {
90+
return this._readFileContents(filePath)
91+
.then(restClient.updateReleaseToServices.bind(restClient, keyPrefix, revisionKey, appName))
8192
.then(this._uploadSuccessMessage.bind(this))
8293
.then(function (key) {
8394
return { key: key };
@@ -97,9 +108,11 @@ module.exports = {
97108
willActivate: function (/* context */) {
98109
var restClient = this.readConfig('restClient');
99110
var keyPrefix = this.readConfig('keyPrefix');
111+
var appName = this.readConfig('appName');
100112
var useHydra = this.readConfig('useHydra');
113+
var useServices = this.readConfig('useServices');
101114

102-
var revisionKey = restClient.activeRevision(keyPrefix, useHydra);
115+
var revisionKey = restClient.activeRevision(keyPrefix, appName, useHydra || useServices, useHydra);
103116

104117
return {
105118
revisionData: {
@@ -112,12 +125,14 @@ module.exports = {
112125
var restClient = this.readConfig('restClient');
113126
var revisionKey = this.readConfig('revisionKey');
114127
var keyPrefix = this.readConfig('keyPrefix');
128+
var appName = this.readConfig('appName');
115129
var useHydra = this.readConfig('useHydra');
130+
var useServices = this.readConfig('useServices');
116131

117132
this.log('Activating revision `' + revisionKey + '`', {
118133
verbose: true,
119134
});
120-
return Promise.resolve(restClient.activate(keyPrefix, revisionKey, useHydra))
135+
return Promise.resolve(restClient.activate(keyPrefix, revisionKey, appName, useHydra || useServices, useHydra))
121136
.then(this.log.bind(this, '✔ Activated revision `' + revisionKey + '`', {}))
122137
.then(function () {
123138
return {
@@ -139,12 +154,14 @@ module.exports = {
139154
fetchInitialRevisions: function (/* context */) {
140155
var restClient = this.readConfig('restClient');
141156
var keyPrefix = this.readConfig('keyPrefix');
157+
var appName = this.readConfig('appName');
142158
var useHydra = this.readConfig('useHydra');
159+
var useServices = this.readConfig('useServices');
143160

144161
this.log('Listing initial revisions for key: `' + keyPrefix + '`', {
145162
verbose: true,
146163
});
147-
return Promise.resolve(restClient.fetchRevisions(keyPrefix, useHydra))
164+
return Promise.resolve(restClient.fetchRevisions(keyPrefix, appName, useHydra || useServices, useHydra))
148165
.then(function (revisions) {
149166
return {
150167
initialRevisions: revisions,
@@ -156,10 +173,14 @@ module.exports = {
156173
fetchRevisions: function (/* context */) {
157174
var restClient = this.readConfig('restClient');
158175
var keyPrefix = this.readConfig('keyPrefix');
176+
var appName = this.readConfig('appName');
159177
var useHydra = this.readConfig('useHydra');
178+
var useServices = this.readConfig('useServices');
160179

161180
this.log('Listing revisions for key: `' + keyPrefix + '`');
162-
return restClient.fetchRevisions(keyPrefix, useHydra).catch(this._errorMessage.bind(this));
181+
return restClient
182+
.fetchRevisions(keyPrefix, appName, useHydra || useServices, useHydra)
183+
.catch(this._errorMessage.bind(this));
163184
},
164185

165186
_readFileContents: function (path) {

lib/rest-client.js

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module.exports = CoreObject.extend({
2727
});
2828
},
2929

30-
uploadAppRelease: function (keyPrefix, revisionKey, appName, value) {
30+
uploadReleaseToHydra: function (keyPrefix, revisionKey, appName, value) {
3131
var version = this._uploadKey(keyPrefix, revisionKey);
3232

3333
var requestBody = {
@@ -41,15 +41,15 @@ module.exports = CoreObject.extend({
4141
});
4242
},
4343

44-
uploadHydraRelease: function (keyPrefix, revisionKey, value) {
44+
updateReleaseToServices: function (keyPrefix, revisionKey, appName, value) {
4545
var version = this._uploadKey(keyPrefix, revisionKey);
4646

4747
var requestBody = {
4848
id: version,
4949
body: value,
5050
};
5151

52-
return denodeify(this._request.post)({ body: requestBody }).then(function () {
52+
return denodeify(this._request.post)({ uri: appName, body: requestBody }).then(function () {
5353
return version;
5454
});
5555
},
@@ -71,22 +71,22 @@ module.exports = CoreObject.extend({
7171
});
7272
},
7373

74-
activate: function (keyPrefix, revisionKey, useHydra) {
75-
return this._listRevisions(keyPrefix, useHydra)
74+
activate: function (keyPrefix, revisionKey, appName, useReleaseEndpoint, isSummaryEndpoint) {
75+
return this._listRevisions(keyPrefix, appName, useReleaseEndpoint, isSummaryEndpoint)
7676
.then(this._validateRevisionKey.bind(this, keyPrefix, revisionKey))
77-
.then(this._activateRevision.bind(this, keyPrefix, revisionKey, useHydra));
77+
.then(this._activateRevision.bind(this, keyPrefix, revisionKey, useReleaseEndpoint));
7878
},
7979

80-
fetchRevisions: function (keyPrefix, useHydra) {
81-
return this._listRevisions(keyPrefix, useHydra).then(function (revisions) {
80+
fetchRevisions: function (keyPrefix, appName, useReleaseEndpoint, isSummaryEndpoint) {
81+
return this._listRevisions(keyPrefix, appName, useReleaseEndpoint, isSummaryEndpoint).then(function (revisions) {
8282
return {
8383
revisions: revisions,
8484
};
8585
});
8686
},
8787

88-
activeRevision: function (keyPrefix, useHydra) {
89-
return this._listRevisions(keyPrefix, useHydra).then(function (revisions) {
88+
activeRevision: function (keyPrefix, appName, useReleaseEndpoint, isSummaryEndpoint) {
89+
return this._listRevisions(keyPrefix, appName, useReleaseEndpoint, isSummaryEndpoint).then(function (revisions) {
9090
var i;
9191

9292
for (i = 0; i < revisions.length; i++) {
@@ -97,15 +97,24 @@ module.exports = CoreObject.extend({
9797
});
9898
},
9999

100-
_listRevisions: function (keyPrefix, useHydra) {
100+
_listRevisions: function (keyPrefix, appName, useReleaseEndpoint, isSummaryEndpoint) {
101101
var qs = {};
102-
103102
if (keyPrefix) {
104103
qs.prefix = keyPrefix;
105104
}
106105

107-
return denodeify(this._request.get)({ qs: qs }).then(function (response) {
108-
var responseBody = useHydra ? response.body.filter((rev) => rev.app === 'journeys') : response.body;
106+
var uri = '';
107+
if (useReleaseEndpoint && !isSummaryEndpoint) {
108+
uri = appName;
109+
}
110+
111+
return denodeify(this._request.get)({ uri, qs: qs }).then(function (response) {
112+
var responseBody =
113+
useReleaseEndpoint && isSummaryEndpoint ? response.body.filter((rev) => rev.app === appName) : response.body;
114+
115+
if (response.statusCode == 404) {
116+
return [];
117+
}
109118

110119
return responseBody.map(function (revision) {
111120
// ember-cli-deploy-display-revisions expects the timestamp to be either
@@ -118,7 +127,7 @@ module.exports = CoreObject.extend({
118127
}
119128

120129
return {
121-
revision: revision.id,
130+
revision: useReleaseEndpoint && !isSummaryEndpoint ? revision.version : revision.id,
122131
revisionData: revisionData,
123132
timestamp: new Date(revision.created_at * 1000),
124133
active: revision.current,
@@ -136,10 +145,10 @@ module.exports = CoreObject.extend({
136145
return isPresent ? Promise.resolve() : Promise.reject('`' + uploadKey + '` is not a valid revision key');
137146
},
138147

139-
_activateRevision: function (keyPrefix, revisionKey, useHydra) {
148+
_activateRevision: function (keyPrefix, revisionKey, useReleaseEndpoint) {
140149
var uri = this._uploadKey(keyPrefix, revisionKey);
141150

142-
if (useHydra) {
151+
if (useReleaseEndpoint) {
143152
uri = `journeys/${uri}/activate`;
144153
}
145154

0 commit comments

Comments
 (0)