Continuous Deployment - ruby-on-rails

I am trying to setup continuous deployment for my Rails project. So far I have done following steps:
My app is on Github.
I have setup Travis CI.
I have created staging environment. (www.staging.myappname.com)
I have created prod environment. (www.myappname.com)
I have integrated Travis CI and Github.
What I am trying to achieve.
Someone creates a pull request.
Travis CI runs the build against pull request. (this part is done)
Once Pull request is merged into master branch then Travis CI run the test again. (this part is done)
If test is green then deploy master branch to staging environment. ( I can do this by adding deploy section to .travis.yml file.
Run test against staging environment, if test passes then deploy master branch to Production environment. ( I don't know how to achieve this part )
I am not sure if this is a right way to do it or not. I read couple of blog post and I noticed people creating different git branch for staging and production. Is this approach needed?
Also I can easily push my code to staging environment using Travis CI but I don't know how to run test again on staging environment and push code to production. What type of test shall I run against staging environment? Shall I only focus on selenium test for staging environment?
I can used tool like codeship but they offer only 100 build/month for free plan where as in Travis I can get unlimited build for free plan. This is the main reason for choosing Travis over codeship.
So my question:
Am I on right track?
What type of test shall I run against staging server?
how to deploy from staging to production using Travis CI?
Do I need staging.rb file in my rails app? If yes then how will it differ from production.rb file?
Do I need to create different git branch for staging and production? Currently I have only master branch which I am trying to deploy to both staging and production.

Usually people have 2 branches, one for staging/development which deploys on the staging server and one for production which deploys to the production branch
once your staging branch is tested and ready for deployment on production, you could create a pull request from staging to master (or just merge it locally and push it) and then the CI server should detect a new version on the master branch and then deploys it to the production server.

Related

Jenkins Pipeline procedure

When I check in my gitlab code from dev, it triggers Jenkins to build this dev branch and deploy the application on the staging server 1. I have selenium automated testing to run against this deployed application (eg Test UI & API etc).
Question:
If the test all passes, Jenkins should deploy a production code on server 2. Can and should Jenkins make a merge request from dev to master in order to do the build?
Theese are possible.
1.You need conditional steps in jenkins.
2.You need conditional steps again and you must use git commands.(git commit,git push etc.)

Deploying Different Images for Staging and Production Environment using Kubernetes and Gitlab

I want to have two separate deployments for Staging and Production branches. I am using Kubernetes cluster in AWS. I have integrated the kubernetes cluster with gitlab. Right now I have setup only one environment which works fine by setting the -only parameter to staging in the .gilab-ci.yml file. Now I want to setup the production environment which will build from the master branch.
Will setting the -only parameter to master work or do I need to make additional changes as well in gitlab?
Also will separate images be created for the two branches or do I need to explicitly create two separate images for the master and staging branch. and if so what are the steps?

Build once deploy many with Jenkins and Github (specific branching workflow)

Im creating Jenkins pipeline for building and deploying our app.
I want to have the same build for the staging and production environment(buld-once-deploy-many approach).
Merging feature branch into staging branch would build an app for both staging and production, but it will deploy it only to staging bucket.
After testing, it would be good that developers merge the staging branch into master which will take the previous staging build and deploy it to production.
Alternative would be to have one branch, and devs would manually trigger another job on Jenkins that would deploy the build to production.
I want to avoid devs going into jenkins and triggering build, since most of them find it intimidating, there are also some nasty vpn configuration steps they need to go through to have access to Jenkins etc.
Would this be a bad practice? Do you have any suggestions how to achieve something like this?
Thanks
This is more of a devops question than a Jenkins question, but here is my take...
I can't decide if you are saying that you would re-build from the master branch, or only use the commit to the master branch to trigger a deployment of the original staging artifact. So I'll address both.
For this situation:
If you build an artifact in a staging branch, and test it. Everything looks green on the tests. So you merge those changes to another branch, re-build, and deploy to production.
The problem: Can you be 100% sure that there was nothing else in the master branch that is not different than what was built AND tested in staging?
You are risking the jello view anti-pattern because unknown and untested changes could sneak into your production artifact. It becomes terribly difficult to troubleshoot why it worked fine it staging, but now fails in production.
For the second situation:
If you are saying that you wouldn't rebuild from the master branch, then merging back to master doesn't buy you anything except a trigger to kick off a new build, because you are never generating an artifact from Master.
If you are going to to it this way, I think you could commit to a single branch, and then tag a release that is meant to go to production, then trigger off of the tag.
Either way, this seems like a strange pattern, and would be difficult to accomplish in an automated fashion in Jenkins. Somehow the newly triggered build would have to find the previously built artifact and deploy that to production.
Possible solution:
There are a few ways to solve this, but one of the easiest is to build once and deploy the same artifact all the way down the line, as you mentioned as an alternative option. But this would likely require some approvals or additional triggering in Jenkins.
If you don't want developers to have to touch Jenkins, then the more likely solution is to build and run your unit tests and smoke tests on the staging environment. Then when a developer wants to promote a build to production, they commit it to the master branch, where the same build is kicked off, and testing is all performed again, in addition to more advanced integration, functional, and acceptance testing. If it doesn't pass, it doesn't go to production.
Your initial tests in staging give the developer quick feedback, but don't serve as the official tests, which only run on the production build.
With a pipeline script, you could easily accomplish this with a single Jenkinsfile and single multibranch pipeline job with stages that are only run when the branch pattern matches.
stage ("Acceptance Testing" ) {
when { branch "master" }
echo "Do testing here"
}

Deploy from build history

I have configured a multi-branch pipeline for my Bitbucket repository. My configuration is the staging branch gets automatically triggered and deploy to staging environment.
Now I want to implement a use case where I should be able to select one build from ‘Build history’ and deploy that build to production. Can any one give a suggestion on how to solve it?

How to have Heroku build my development branch on a staging server?

I have a production application on master branch running all fine on heroku. I would like to run a second Heroku application but 'fed' from a local staging branch. These are the commands that i've run in my failed attempt to do this:
git checkout -b develop
heroku create --remote staging
git push staging develop
But because i'm pushing from a 'non master' branch it doesn't build the app;
remote: Pushed to non-master branch, skipping build.
I have read the managing multiple environments doc here; https://devcenter.heroku.com/articles/multiple-environments but it does not seem to address what I'm trying to achieve, rather merging develop branch into master first then pushing master to remote staging. I want to push my develop branch to a staging app and have it running live in RAILS_ENV=production mode, iteratively push to this live 'staging/testing' app then when i'm really comfy with what i'm going i'll merge the develop branch code into the master branch and push to the primary mast app.
Can anyone help me with how to achieve this?
as per heroku doc
git push staging develop:master
as per Git documentaion
git push <REMOTENAME> <LOCALBRANCHNAME>:<REMOTEBRANCHNAME>
so
git push heroku staging:master
means
push my staging local branch to master remote heroku branch
Its not as close to the most direct command line - but my DevOps pipeline using Codeship makes this much easier for commits on different branches.
I have Codeship automatically deploy anything to the dev branch to one Heroku app, anything in the staging branch to another, and anything to master to the live branch.
Not the direct solution you were probably looking for - but something that shows the benefits of a good CI setup!

Resources