Automating git pull process on dev/QA server on commit - ruby

I have my rails application hosted on github. Whenever a commit happens on 'dev' branch I would like to do git pull on the dev box and also invoke '/etc/init.d/apache2 restart' command. Is this something I can do with Capistrano deployment or I can write some kind of custom shell script and somehow hook in my rails app to call that shell script?

You will need a post-receive hook on the git server that causes a git pull on the dev box. A quick DAFS for "git deploy with post-receive" found quite a few resources, like http://ryanflorence.com/deploying-websites-with-a-tiny-git-hook
I would personally prefer using a build system like Jenkins for this as it gives you more control and visibility. We have set up a continuous deployment system using Jenkins and github post-receive hooks with relatively little fuss. Another advantage is that you can run your tests before automatically deploying (if they pass) by chaining jobs.

Related

GitHub post-receive hook not triggered on Windows

I'm trying to use a post-receive git-hook to automate the deploy of a simple maven project by triggering a Jenkins pipeline I set up. The source is hosted on a GitHub repo while Jenkins on a container running on my PC. So far, the hook is not triggered after I push to master branch.
Thing is if I try and run the script manually it just works! I also tried setting chmod +x with Git Bash (after all I'm on Windows) to the post-receive file, unfortunately without success: the hook still does not get triggered. What might be the issue?
I already tried looking for answers on similar topics here on stackoverflow, but nothing solved my issue. FYI, below the post-receive script (nothing fancy, as you can see):
#!/bin/bash
JENKINS_URL="http://localhost:8080"
JOB="deploy-to-slave-pipeline"
JENKINS_CREDENTIALS="theuser:11d422ee679503eeb328c5b1998327cc7f"
echo "Triggering Jenkins job..."
crumb=$(curl -u "$JENKINS_CREDENTIALS" -s '$JENKINS_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -u $JENKINS_CREDENTIALS -H "$crumb" -X POST "$JENKINS_URL/job/$JOB/build?delay=0sec"
EDIT
As pointed out by #bk2204 post-receive is a server-side hook. What I needed was a webhook, which can be set in the Settings/Webhook page of your GitHub repo. Just configure it as below where Payload URL is your Jenkins URL followed by /github-webhook/:
Then all you have to do is set your Jenkins job to get triggered by GitHub, by checking the related option on the Build Triggers section as below:
And then you're good to go! Also, if you're running your Jenkins instance locally, you could use ngrok to expose it and test your CI/CD pipeline!
[ref. https://dzone.com/articles/adding-a-github-webhook-in-your-jenkins-pipeline]
A post-receive hook is run on the server side, not on the client side. That means that it's run at GitHub, assuming you're pushing to GitHub, ant not on your local machine.
Normally, you'd want a GitHub webhook to notify you of the push event, but you cannot use one here because the machine is running on localhost and such an event has to be able to on a public IP address since GitHub has to send an HTTP request to it.

Ignore warning when pushing to heroku git master

I'm deploying an app to Heroku, which means pushing to their git repo. When do git push heroku master (or the equivalent remote alias) I get this warning:
WARNING: You're about to push to master, is that what you intended? [y|n]
Which is kinda annoying but not a big deal. However, I'm now scripting deployments so I don't want to have interact with the script - how I do get my bash script to answer y automatically?
I tried doing yes | git push heroku master but that doesn't work.
Agree with #bk2204, I would check if a git hook is being used that you are unaware of.
Git hooks are not version controlled, so make sure you are searching for this at the machine where you get this error.
The git hook may live elsewhere other than the .git directory. Check if git config core.hooksPath is set and if so, it will point to the directory where your git hook is.
The hook file that you are looking for will most likely have the name pre-push. The solution in this case is to remove or rename this hook file, and git won't run it before push.
Nope, no such file
And yet, this is exactly what a .git/hooks/pre-push would do, like this one.
To rule that out, activate (with your local Git 2.25+) trace2.
That will allow you to see what is used on the client side (your PC) by Git:
git config --global trace2.normalTarget ~/log.normal
Try your push, type 'n' (to abort), and check ~/log.normal for clues.
Just another way to solve the problem of automating responses to the prompts. You can use expect to take care of interactive warnings/ prompts.
After writing the deployment script deploy.sh, you can write a expect script and spawn the deploy script in it, for response to
WARNING: You're about to push to master, is that what you intended? [y|n]
message, you can send 'y' from expect.
The following snippet can be taken as example
#!/usr/bin/expect -f
spawn bash ./deploy.sh
expect "WARNING: You're about to push to master, is that what you intended? [y|n]\r"
send -- "y\r"

Issues getting Git working with VSCode and files on web host

Until now I have always used FileZilla for transferring my local files to my host for changing a site Im working on. I want to change that and learn how to git gud! So basically the ideal situation would be to be able to work in VSCode on a directory which is mirrored from my web host and from there be able to make changes locally and then commit and change files on my web host when I want to - this has to be possible right?
I have been able to use Git Bash to connect to my host and files using ssh. I have created both an init --bare and init since Im not sure which one to use, but I do have the .git folder created there. I can also using the Bash and the command git status see all the files waiting for to be committed (?).
As I understand I have to initialize the repository, then commit them to "track" these files and have them visible in VSCode to work with, is this right?
But when I try to git commit following error message is displayed.
Waiting for your editor to close the file... code --wait: code: command not found.
This points to that the relative pathing to vscode and/or git is not working, but it is. When I start-up the bash I can use for example code --help and git config --global -e to launch a window of VSCode. So my git config --global core.editor "code --wait" is probably working as it should.
Although AFTER I have connected to my web host using ssh, neither of these command work anymore. Why is this?
And also, am Im on the right way right now in thinking on how to make this "connection" between VSCode, git and my web host (one.com)?
Im thinking that I have to create a local repository in the folder where I today have a duplicate of my web host-files and a remote repository at the actual web host and then make some kind of connection between them two and VSCode. Im not quite sure how yet.
Thanks in advance
I think you might be a little confused with what Git is and how you should be using it for what you want to do. Let's clear some stuff up.
Simply put, Git is a version control system for tracking changes to files over time. You create or edit your files, git add them to a "staging area" and then git commit them with a commit message. If you edit the files after committing them, then git can detect changes to the files and you can add and commit them again, or discard them depending on what you want. However the most important part to understand is that these changes are local at this point. If you want to share them with anyone (or have another system pull them down), then you will need to establish a remote repository.
This is what Github/GitLab are for. Log in/create an account on either site (gitLab provides free private repos) and create a repository named appropriately. Then once you have created a remote repo, follow the instructions to add it as a "remote" to your local repo, then git push your changes up to that remote one. Now, on your server, you will git clone the remote repo and that will pull down your changes. From then on, if you push new changes to the remote repo, you can pull the changes down to the server by doing git pull. This is a very basic and barebones approach to deploying code on the server and there are more sophisticated ways of doing it but I will keep it simple in this answer.
Git is completely separate from VSCode (although VSCode has some git integration and plugins). I would not recommend changing the core.editor to VSCode. What that setting controls is the editor that is used to author commit messages. Loading up VSCode takes too long for that...I recommend that you stick with the default Vim or use nano. Or, in most cases, specify a message when committing: git commit -m "added foobar".
So, the git repo that is on your server (the one that you init'd with --bare) is junk and should be instead created by git cloneing from a remote repo. Hopefully this makes sense!

How to automatically git pull and rebuild app on remote server when required?

When i want to update my app running on server, i should ssh to server, cd to app folder, execute git pull, then i should run npm build, next i should restart the server. How to automate this with bash script or something? Is it the case for which jenkins stands for (or some other tools)?.
But how to do this with simple bash script or something?
I dont need the rebuilding of an app every time i push to git, only when i need to update and restart everything.
Also it there a way if build take a lot of time notify me by email that build success?
For now eery time i do update for remote app, i should wait with open terminal when it builded and only then i can close the sshed terminal. Some time builds take a lot of time.
You can simply script those commands, and put that script on your server.
That way, all you need to do is to ssh to that server and call that script, which will execute those commands on demand.
Is it the case for which jenkins stands for (or some other tools)?
Not in this case, since it is purely on demand: you can execute the script through a simple ssh call, no need for Jenkins.

What is a good way to run a task whenever a Heroku app restarts?

Use case is to bust the cache.
What is a good way to run given code (or rake task) whenever a Ruby Heroku app is restarted (or deployed)?
There's no way to do this via the Heroku API far as I know. The Heroku Platform API doesn't support this.
What you can do (if you're fast, however!) is listen for a SIGTERM message in your code (that's what Heroku sends to your application process when it attempts to restart it) -- you can then fire off your script quickly.
Here's more information on SIGTERM on Heroku: https://devcenter.heroku.com/articles/dynos#graceful-shutdown-with-sigterm
If you're using some sort of CI, you can probably configure it there. Heres how to do it with CircleCI:
deployment:
production:
branch: production
commands:
- git push git#heroku.com:foo-bar-123.git $CIRCLE_SHA1:master
- heroku run rake <your task> --app <your app name>
If you're not using a CI you can still whip together a script that first does the git push to Heroku and then executes your cache busting task through heroku run (the app's bin/ folder would be an obvious place to put it).
Note: you can also use heroku run:detached, which will send output to your logs instead of stdout.
You can use "release" feature that allows you to run any command before a new release is deployed. https://devcenter.heroku.com/articles/release-phase
Define the command that should be run in your Procfile.
release: rake db:migrate
From documentation:
The release command is run immediately after a release is created, but before the release is deployed to the app’s dyno formation. That means it will be run after an event that creates a new release.

Resources