Skip to content

Commit 80786a4

Browse files
committed
Adding OpenShift hosting with 'yo angular-fullstack:deploy openshift'
1 parent fa15bdc commit 80786a4

File tree

5 files changed

+210
-28
lines changed

5 files changed

+210
-28
lines changed

deploy/index.js

Lines changed: 167 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,32 @@ var Generator = module.exports = function Generator() {
1111
util.inherits(Generator, ScriptBase);
1212

1313
Generator.prototype.checkInstallation = function checkInstallation() {
14-
if(this.name.toLowerCase() != "heroku") return;
1514
var done = this.async();
16-
15+
this.rhcInstalled = false;
1716
this.herokuInstalled = false;
18-
exec('heroku --version', function (err) {
19-
if (err) {
20-
this.log.error('You don\'t have the Heroku Toolbelt installed. ' +
21-
'Grab it from https://toolbelt.heroku.com/');
22-
} else {
23-
this.herokuInstalled = true;
24-
}
17+
if(this.name.toLowerCase() == "openshift" ){
18+
exec('rhc --version', function (err) {
19+
if (err) {
20+
this.log.error('OpenShift\'s rhc command line interface is not available. ' +
21+
'You can install it via RubyGems with: gem install rhc');
22+
} else {
23+
this.rhcInstalled = true;
24+
}
25+
done();
26+
}.bind(this));
27+
}else if(this.name.toLowerCase() == 'heroku') {
28+
exec('heroku --version', function (err) {
29+
if (err) {
30+
this.log.error('You don\'t have the Heroku Toolbelt installed. ' +
31+
'Grab it from https://toolbelt.heroku.com/');
32+
} else {
33+
this.herokuInstalled = true;
34+
}
35+
done();
36+
}.bind(this));
37+
}else{
2538
done();
26-
}.bind(this));
39+
}
2740
};
2841

2942
Generator.prototype.copyProcfile = function copyProcfile() {
@@ -32,27 +45,167 @@ Generator.prototype.copyProcfile = function copyProcfile() {
3245
};
3346

3447
Generator.prototype.gruntBuild = function gruntBuild() {
35-
if(this.name.toLowerCase() != "heroku") return;
48+
if(this.name.toLowerCase() != "heroku" &&
49+
this.name.toLowerCase() != "openshift" ) return;
3650
var done = this.async();
3751

3852
console.log(chalk.bold('Building dist folder, please wait...'));
3953
exec('grunt build', function (err, stdout) {
4054
console.log('stdout: ' + stdout);
41-
4255
if (err) {
4356
this.log.error(err);
4457
}
4558
done();
4659
}.bind(this));
4760
};
4861

62+
Generator.prototype.enableOpenShiftHotDeploy = function enableOpenshiftHotDeploy() {
63+
if(this.name.toLowerCase() != "openshift") return;
64+
this.log("enabling HotDeploy for OpenShift")
65+
this.template('../deploy/openshift/hot_deploy', 'dist/.openshift/markers/hot_deploy');
66+
};
67+
4968
Generator.prototype.gitInit = function gitInit() {
50-
if(this.name.toLowerCase() != "heroku") return;
5169
var done = this.async();
70+
if(this.name.toLowerCase() == "heroku"){
71+
exec('git init && git add -A && git commit -m "Initial commit"', { cwd: 'dist' }, function (err) {
72+
if (err) {
73+
this.log.error(err);
74+
}
75+
done();
76+
}.bind(this));
77+
}else if(this.name.toLowerCase() == "openshift"){
78+
exec('git init && git add -A && git commit -m "Generating a fresh angular-fullstack application"', { cwd: 'dist' }, function (err, stdout, stderr) {
79+
this.log(stdout);
80+
if (stdout.search('nothing to commit') >= 0) {
81+
this.log('Re-pushing the existing "dist" build...');
82+
} else if (err) {
83+
this.log.error(err);
84+
}
85+
done();
86+
}.bind(this));
87+
}else{
88+
done();
89+
}
90+
};
5291

53-
exec('git init && git add -A && git commit -m "Initial commit"', { cwd: 'dist' }, function (err) {
92+
Generator.prototype.gitRemoteCheck = function gitRemoteCheck() {
93+
this.openshift_remote_exists = false;
94+
if(this.name.toLowerCase() != "openshift" || typeof this.dist_repo_url != 'undefined') return;
95+
var done = this.async();
96+
97+
this.log("Checking for an existing git remote named 'openshift'...")
98+
exec('git remote -v', { cwd: 'dist' }, function (err, stdout, stderr) {
99+
var lines = stdout.split('\n')
100+
var dist_repo = ''
101+
this.log('stdout: ' + stdout);
54102
if (err) {
55103
this.log.error(err);
104+
} else {
105+
var repo_url_finder = /openshift[ ]*/
106+
lines.forEach(function(line){
107+
if(line.search(repo_url_finder) == 0 && dist_repo == ''){
108+
var dist_repo_detailed = line.slice(line.match(repo_url_finder)[0].length)
109+
dist_repo = dist_repo_detailed.slice(0, dist_repo_detailed.length - 7)
110+
}})
111+
if (dist_repo != ''){
112+
console.log("Found an existing git remote for this app: "+dist_repo)
113+
this.dist_repo_url = dist_repo
114+
this.openshift_remote_exists = true;
115+
}
116+
}
117+
done();
118+
}.bind(this));
119+
};
120+
121+
Generator.prototype.rhcAppShow = function rhcAppShow() {
122+
if(this.name.toLowerCase() != "openshift" || typeof this.dist_repo_url != 'undefined') return;
123+
var done = this.async();
124+
125+
this.log("Checking for an existing OpenShift hosting evironment...")
126+
exec('rhc app show '+this.appname+' --noprompt', { cwd: 'dist' }, function (err, stdout, stderr) {
127+
var lines = stdout.split('\n')
128+
var dist_repo = ''
129+
if (stdout.search('Not authenticated') >= 0 || stdout.search('Invalid characters found in login') >= 0) {
130+
this.log.error('Error: Not authenticated. Run "rhc setup" to login to your OpenShift account and try again.');
131+
} else if (err) {
132+
this.log.error(err);
133+
} else {
134+
this.log(stdout);
135+
var repo_url_finder = / *Git URL: */
136+
lines.forEach(function(line){
137+
if(line.search(repo_url_finder) == 0){
138+
dist_repo = line.slice(line.match(repo_url_finder)[0].length)
139+
console.log("Found an existing git remote for this app: "+dist_repo)
140+
}})
141+
if (dist_repo != '') this.dist_repo_url = dist_repo
142+
}
143+
done();
144+
}.bind(this));
145+
};
146+
147+
Generator.prototype.rhcAppCreate = function rhcAppCreate() {
148+
if(this.name.toLowerCase() != "openshift" || typeof this.dist_repo_url != 'undefined') return;
149+
var done = this.async();
150+
this.log("Creating your OpenShift hosting evironment...")
151+
exec('rhc app create '+this.appname+' nodejs-0.10 mongodb-2.4 -s --noprompt --no-git NODE_ENV=production', { cwd: 'dist' }, function (err, stdout, stderr) {
152+
var lines = stdout.split('\n')
153+
this.log(stdout);
154+
if (stdout.search('Not authenticated') >= 0 || stdout.search('Invalid characters found in login') >= 0) {
155+
this.log.error('Error: Not authenticated. Run "rhc setup" to login to your OpenShift account and try again.');
156+
} else if (err) {
157+
this.log.error(err);
158+
} else {
159+
var dist_repo = ''
160+
var repo_url_finder = / *Git remote: */
161+
lines.forEach(function(line){
162+
if(line.search(repo_url_finder) == 0){
163+
dist_repo = line.slice(line.match(repo_url_finder)[0].length)
164+
}})
165+
166+
if (dist_repo != '') this.dist_repo_url = dist_repo
167+
this.log("New remote git repo at: "+this.dist_repo_url)
168+
}
169+
done();
170+
}.bind(this));
171+
};
172+
173+
Generator.prototype.gitRemoteAdd = function gitRemoteAdd() {
174+
if(this.name.toLowerCase() != "openshift" || typeof this.dist_repo_url == 'undefined' || this.openshift_remote_exists) return;
175+
var done = this.async();
176+
this.log("Adding remote repo url: "+this.dist_repo_url)
177+
178+
exec('git remote add openshift '+this.dist_repo_url, { cwd: 'dist' }, function (err, stdout, stderr) {
179+
if (err) {
180+
this.log.error(err);
181+
} else {
182+
this.log('stdout: ' + stdout);
183+
this.openshift_remote_exists = true;
184+
}
185+
done();
186+
}.bind(this));
187+
};
188+
189+
Generator.prototype.gitForcePush = function gitForcePush() {
190+
if(this.name.toLowerCase() != "openshift" || !this.openshift_remote_exists ) return;
191+
var done = this.async();
192+
this.log(chalk.green("Uploading your initial application code.\n This may take "+chalk.bold('several minutes')+" depending on your connection speed..."))
193+
194+
exec('git push -f openshift master', { cwd: 'dist' }, function (err, stdout, stderr) {
195+
if (err) {
196+
this.log.error(err);
197+
} else {
198+
var host_url = '';
199+
this.log('stdout: ' + stdout);
200+
var before_hostname = 'ssh://xxxxxxxxxxxxxxxxxxxxxxxx@'.length;
201+
var after_hostname = this.dist_repo_url.length - ( this.appname.length + 12 )
202+
host_url = 'http://' + this.dist_repo_url.slice(before_hostname, after_hostname)
203+
204+
this.log(chalk.green('You\'re all set! Your app should now be live at \n\t' + chalk.bold(host_url)));
205+
this.log(chalk.yellow('After app modification run\n\t' + chalk.bold('grunt build') +
206+
'\nThen enter the dist folder to commit these updates:\n\t' + chalk.bold('cd dist && git commit -am "describe your changes here"')));
207+
this.log(chalk.green('Finally, deploy your updated build to OpenShift with\n\t' + chalk.bold('git push openshift master')));
208+
this.openshift_host_url = host_url;
56209
}
57210
done();
58211
}.bind(this));

readme.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ Alternatively to skip tests and jshint, use:
7575
grunt build
7676
```
7777

78+
### OpenShift Deployment
79+
Deploying to OpenShift can be done in just a few steps:
80+
81+
1. `mkdir myapp && cd myapp`
82+
2. `yo angular-fullstack myapp`
83+
3. `yo angular-fullstack:deploy openshift`
84+
85+
A live application URL will be available in the output.
86+
7887
### Heroku Deployment
7988

8089
We provide an extremely simplifed deployment process for heroku.
@@ -124,25 +133,40 @@ Read more on the angular sub-generators from the offical [generator angular docu
124133
## Fullstack sub-generators
125134

126135
### Deploy
127-
Initalizes a heroku app and generates a `dist` folder which is ready to push to heroku.
136+
Initalizes a remote Heroku or OpenShift application, generates a `dist` folder, and sets up a `git remote` to enable subsequent deployments.
128137

129-
To do the same manually, you need to:
138+
OpenShift Example:
139+
```bash
140+
yo angular-fullstack:deploy openshift
141+
```
130142

131-
1. Build a dist folder
143+
Or, for Heroku:
144+
```bash
145+
yo angular-fullstack:deploy heroku
146+
```
147+
148+
To do the same manually with heroku, you'd need to:
149+
150+
1. Build a dist folder `grunt build`
132151
2. Create a Procfile in the dist folder
133152
3. Create a repository: `git init && git add -A && git commit -m "Initial commit"`
134-
4. Create a heroku app: `heroku apps:create && heroku config:set NODE_ENV=production`
153+
4. Create an app: `heroku apps:create && heroku config:set NODE_ENV=production`
135154

136-
Example:
155+
#### Pushing updates
156+
For any platform, when you're ready to ship changes to your live app, run the following to generate a new build for deployment:
137157
```bash
138-
yo angular-fullstack:deploy heroku
158+
grunt build
139159
```
140160

141-
After app modifications run:
161+
Then commit and push the resulting build, located in your `dist` folder:
142162
```bash
143-
grunt build
163+
cd dist &&
164+
git push openshift master
165+
```
166+
Or, for Heroku:
167+
```bash
168+
git push heroku master
144169
```
145-
then commit and push the dist folder.
146170

147171
## Options
148172
In general, these options can be applied to any generator, though they only affect generators that produce scripts.

templates/deploy/openshift/hot_deploy

Whitespace-only changes.
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
'use strict';
22

33
module.exports = {
4-
env: 'production'<% if (mongo) { %>,
4+
env: 'production',
5+
ip: process.env.OPENSHIFT_NODEJS_IP ||
6+
'127.0.0.1',
7+
port: process.env.OPENSHIFT_NODEJS_PORT ||
8+
8080<% if (mongo) { %>,
59
mongo: {
610
uri: process.env.MONGOLAB_URI ||
711
process.env.MONGOHQ_URL ||
12+
process.env.OPENSHIFT_MONGODB_DB_URL+process.env.OPENSHIFT_APP_NAME ||
813
'mongodb://localhost/fullstack'
914
}<% } %>
10-
};
15+
};

templates/express/server.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ require('./lib/config/express')(app);
4141
require('./lib/routes')(app);
4242

4343
// Start server
44-
app.listen(config.port, function () {
45-
console.log('Express server listening on port %d in %s mode', config.port, app.get('env'));
44+
app.listen(config.port, config.ip, function () {
45+
console.log('Express server listening on %s:%d, in %s mode', config.ip, config.port, app.get('env'));
4646
});
4747

4848
// Expose app
49-
exports = module.exports = app;
49+
exports = module.exports = app;

0 commit comments

Comments
 (0)