Grunt dist with git and multiple servers - angularjs

I am about to start using Yeoman with Angular.js for a project that has PHP as the backend. I know I can use Grunt to minify all my files and get it ready for production. My question is, how do I handle that properly with Git?
Right now I have three servers (development, staging, production) and instead of uploading files with FTP, I just pull from my Github repository. This works fine, but with Yeoman and Grunt, I don't want all the files that is brings along for development, I just want the distribution files on my staging and production servers.
Is there a way to do this with Git?

The git subtree command is an option that should accomplish what you want.
Check out this page for more information and a few other options for deployment of the production code.

Related

How to publish Angular project?

I maked angular project. I used this generator:
https://github.com/swiip/generator-gulp-angular#readme
I have serwer and domain. My question is: How publish this working project on serwer? Should I use Apache http?
Since you used Gulp, you can check its docs to find out exactly you can build your Gulp application and deploy it to server.
On your command line run this in your working directory of the app
gulp //to build an optimized files to be deployed on to the server
Now in your dist folder in your root of your working directory, you'll find all the files and folders that have been created by gulp task default.
Now you can deploy this on with Apache or node or Nginx or any other server you want. Simply paste all the files to the to the
path/of/the/root/on/server
You can also preview your app the browser and watching for files changing and auto-reloading the browser to review changes by running
gulp serve
More grunt tasks here.

Should we push the package.json, bower.json, gulpfile.js to production server

I am using gulp, bower, stylus for an angularjs application.
I am not using any Continuous Integration technology, git pulling code from repo manually when git push are made to master branch on bitbucket, considering this scenario :
Is it a good practice to include bower.json, package.json and
gulpfile.js on the production server and install dependencies
manually by npm install or bower install on server?
Is it safe to include gulpfile.js on the server?
Also, if using any Continuous Integration technology, what would be the best practice?
My .gitignore file is as follows :
node_modules
dist
.tmp
.sass-cache
bower_components
private.xml
nbproject
gruntfile.js
gulpfile.js
package.json
Add package.json and bower.json files to keep the track of dependencies that are being used on production server. However you should skip uploading gulp or grunt files as they are for local use only. They are not needed to be uploaded on production server.
EDIT :
If you use grunt/gulp for restarting your node server as well, like using nodemon from grunt/gulp, You may upload grunt/gulp file. In the end if you have structured your node server properly there is no harm putting grunt/gulp file on server, as these interact with your system before server starts.
You can use gulp or grunt task runner which pulls all the external dependencies such as Angular, JQuery and bundles them together. Then use the bundled file on production server. It will also reduce number of requests your browser needs to make to get those resources. For more info, read this article:
https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js#javascript-concat-and-minify

AngularJS Continuous Deployment Tools

I have been trying out Codeship and Heroku for continuous deployment of an AngularJS application I writing at the moment. The app was created using Yeoman and uses bower and grunt. Initially I thought this seemed like a really good setup as Codeship was free to use and I was quickly able to configure this to build my AngularJS project and it offered the ability to add a deployment step after the build. There were even many PaaS providers to choose from (Heroku, S3, Google App Engine etc). However I seem to have become a bit stuck with getting the app to run on Heroku.
The problem started from the fact that all the documentation suggested that I remove the /dist path from my .gitignore so that this directory is published to Heroku post build. This was mainly from documentation that talked about publishing to Heroku from a local machine, but I figure this is all Codeship is doing under the hood anyway. I didn't want to do this as I don't believe I should be checking build output into source control. The /dist folder was added to .gitignore for a good reason. Furthermore, this kind of defeats the point of having a CI server somewhat, as I might as well just push the latest build from my machine.
After some more digging around I found out that I could add a postinstall step to my packages.json file such as bower install && grunt build which would re-run the build on Heroku and hence repopulate all the bower dependencies (something else they wanted me to check in to source control!) and the dist directory.
After giving this a try it became apparent that I would need to add bower and grunt as dependencies in packages.json, which meant moving them from devDependencies which is where they should belong!
So I now seem to be stuck. All I want to do is publish my build artefacts (/dist) the dependencies (/bower_components) and the server.js file that will run the site. Does anyone know how to achieve this with Heroku and Codeship? Alternatively has anyone had any success with this using different tools. I am looking for something that is free and I am willing to accept that it will not be production stable (won't scale to multiple servers etc), but this is fine for now as all I want to do is continuously deploy the app for internal testing and to be able to share the output with non-technical members of my team so we can discuss features we'd like to prioritise etc.
Any advice would be greatly appreciated.
Thanks
Ahoy, Marko from the Codeship crew here. Did you already send us an in app message about this? I'm sure we can get your application building on Codeship and deploying to Heroku successfully.
As a very short answer, the easiest way to get this running would be to add both bower and grunt to your dependencies in the package.json. Another possibility would be to look for a custom buildpack with both tools already installed.
And finally you could also run the tools on Codeship, add the newly installed files to the repository, commit the changes and push this new commit to Heroku. If you want to use this, you'd very probably need to force push the changes though.
Feel free to reach out to me via the in app messenger (lower right corner of the site) and I'd be happy to help you get this working!
I found two ways to get this to work.
Heroku Node Custom Buildpack
Use the mbuchetics Heroku build pack. This works by basically re-building the app once it has been pushed to Heroku.
There were a few tricks I had to employ still to make this work. In Gruntfile.jstwo new tasks needed to be configured called heroku:production and heroku:development. This is what the buildpack executes to build the app. I initially just aliased the main build task, but found that the either the buildpack or Heroku had a problem with running jshint so in the end I copied the build task and took out the parts that I didn't need.
Also in packages.json I had to add this:
"scripts": {
"postinstall": "bower cache clean && bower install"
}
This made sure the bower_components were available in Heroku.
Pros
This allowed me to keep the .gitignore file in tact so that the 'binaries' in the dist directory and the dependencies in the bower_components directory were not committed into source control.
Cons
This is basically re-building the app once it is on Heroku and I generally prefer to use the same 'binaries' throughout the entire build and deployment pipeline. That way I know that the same code that was built, is the same code that was tested and is the same code that was deployed.
It also slows down the deployment as you have to wait for the app to build twice.
CodeShip Custom Script Deployment
Not being satisfied with the fact I was building my app twice, I tried using a Custom Script pipeline in CodeShip instead of the pre-existing Heroku one. The script basically modified the .gitignore file to allow the dist folder to be committed and then pushed to the Heroku remote (which leaves the code on the origin remote unaffected by the change).
I ended up with the following bash script:
#!/bin/bash
gitRemoteName="heroku_$APP_NAME"
gitRemoteUrl="git#heroku.com:$APP_NAME.git"
# Configure git remote
git config --global user.email "you-email#example.com"
git config --global user.name "Build"
git remote add $gitRemoteName $gitRemoteUrl
# Allow dist to be pushed to heroku remote repo
echo '!dist' >> .gitignore
# Also make sure any other exclusions dont apply to that directory
echo '!dist/*' >> .gitignore
# Commit build output
git add -A .
herokuCommitMessage="Build $CI_BUILD_NUMBER for branch $CI_BRANCH. Commited by $CI_COMMITTER_NAME. Commit hash $CI_COMMIT_ID"
echo $herokuCommitMessage
git commit -m "$herokuCommitMessage"
# Must merge the last build in Heroku remote, but always chose new files in merge
git fetch $gitRemoteName
git merge "$gitRemoteName/master" -X ours -m "Merge last build and overwrite with new build"
# Branch is in detached mode so must reference the commit hash to push
git push $gitRemoteName $(git rev-parse HEAD):refs/heads/master
Pros
This only require a single build of the app and deploys the same binaries that were tested during the test phase.
Cons
I've used this script quite a few times now and it seems relatively stable. However one issue I know of is that when a new pipeline is created there will be no code on the master branch so this script fails when it tries to do the merge from the heroku remote. At the moment I get around this by doing an initial push of the master branch to Heroku before kicking off a build, but I imagine there is probably a better Git command I could run along the lines of; 'only merge this branch if it already exists'.

git deploy minified assets only

How can I create a simple deployment process using git where only my minified/concatenated js/css files are on the production server?
I am building an angularjs/laravel app with bootstrap-sass and ideally don't want to deploy any un-minified (source) files if possible. I am using bower and gulp tools as well if that helps.
The idea is to have 2 sections in your code base:
All the files you use for development - js, css, htmls etc (with their folder structure)
A folder called 'Dist' (stand for distributed)
And have a grunt task (let's call it 'grunt build') that perform set of tasks over your development code base: minified, uglified, image compression, removes unnecessary file and put the output in Dist.
Once grunt build is done, you need to deploy the Dist folder to production, that can be done in many ways (holding a separate git repo for production is and every new commit is a new version is a good option)

Using Git for Angular App

I'm using Yeoman to generate out an angular app. Once I'm happy with my app, I run grunt which creates a production-ready version of my application in a folder called /dist at the root of my project.
I've then initialised this /dist directory as a Git repository with git init and pushed the files up to Bitbucket, where they currently sit right now.
What I'm asking is do I have to compile my production-ready app with grunt every time I want to make a commit? It seems I have to. I'm thinking this setup might not be the most productive way to do this?
Am I missing something, is there an easier and more productive way to handling this?
That workflow is odd.
Only source code should be in your git repository. Not the compiled/minified files. Source code is what matters.
When you colaborate with somebody else, they should run grunt tasks on their own.
Dist package should be created before deploy to production. Or on regular basis by the continuous integration server.

Resources