One commit and you’re hooked
Here is a tutorial on how to make Git on a local machine run a script automatically in response to git commands.
How Git Hooks work
Every Git repository is created with a hooks folder.
Git looks into the
.git/hooks folder for scripts when events occur.
PROTIP: In your GitHub repository, create a “hooks” folder containing script files
that a new repo setup script copies into the
Navigate into any Git repository you want to automate.
Each Git repository folder is created with a set of sample automation files.
applypatch-msg.sample commit-msg.sample post-update.sample pre-applypatch.sample pre-commit.sample pre-push.sample pre-rebase.sample pre-receive.sample prepare-commit-msg.sample update.sample
These files have a weird “.sample” in the file name so that it won’t run. Git automatically runs files renamed with no file extension, such as “pre-commit”.
PROTIP: A longer list is at Matthew Hudson’s githooks.com, along with projects others have done with hooks. The canonical documentation is at https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
PROTIP: You may delete these sample files because I’ve added links to each file listed above to the source of the files at:
Hooks by Event
There are two types of hooks: client and server.
On the client, upon
git commit, the hooks are executed in this order:
- pre-commit (to run unit tests, look for console messages, etc.)
- commit-msg (send email)
- pre-rebase is run before Git executes
- applypatch-msg is run before Git executes
On the server:
- post-receive (send email)
Before we get into manual instllation steps, you need to know that there are automated options available.
IntelliJ IDE Automation
IntelliJ IDEA from Jetbrains, the free Community Edition, provides check-boxes to activate Git hooks.
PROTIP: We don’t see how to get to Version Control in IntelliJ on videos because it’s often accessed via a hotkey - apple 9 on macs and Alt+9 on Windows.
See https://www.youtube.com/watch?v=V8KSaQKgR1Y for VCS improvements in IntelliJ 2016.3.
Let’s use a sample project that already has .idea folder containing files that define configurations for IntelliJ.
But Andrew Krug’s Java example also has integration with testing utilities.
One-liner to install and run
Open a Terminal shell window to where you would like to add a script. One example on a Mac is a folder under your home directory, such as:
Copy this script to your Clipboard and paste it on the Terminal command line.
`sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/Basic-Selenium-Java/master/mac-bootstrap.sh)"`
(Press Enter to run).
The script downloadloads all pre-requisites before running the test.
Step through the automation
Use Finder to look at the repo.
The target being developed/tested is the Java source code under folder /src/test/java/localbrowsers.
Each “.java” program is a unit test to simply retrieve a website in a browser.
The “memory-leak.java” source file intentionally creates a memory leak when run.
Install internet browsers used by running the shell script:
chmod +x mac_install_browsers.sh && ./mac_install_browsers.sh
Installed are browser add-ins for testing (with cask being used for GUI apps). Links to websites have been added:
- brew install geckodriver
- brew cask install firefox
- brew install chromedriver
- brew cask install google-chrome
- brew install phantomjs (a “headless” browser)
- Safari doesn’t need to be installed because it comes with Apple Macs.
If you get this error, rerun:
curl: (56) SSLRead() return error -9806
Use Finder to look at the pom.xml file specifying Java stuff to be downloaded:
maven-surefire-plugin from http://maven.apache.org/components/surefire/maven-surefire-plugin/ to execute tests. https://www.youtube.com/watch?v=R2ok6mKU0TI
jacoco-maven-plugin (http://www.jacoco.org/) for determines code coverage. (It was written for running in Eclipse, but IntelliJ uses it too.)
coveralls-maven-plugin from https://github.com/trautonen/coveralls-maven-plugin to track code coverage over time
Look at the configuration files:
codecov.yml is read by javaco.io ???
.travis.yml for using the Travis on-line service ???
Run the repo’s installation script implementing the pom.xml file specifying Java stuff to be downloaded:
Run manually on a Mac:
mvn test -Dsurefire.suiteXmlFiles=mac-only.xml
This opens up several browser programs. In each, go to the same URL, checks if the correct title in HTML was received. Browser windows are closed after each test.
The browsers are Firefox, Chrome, PhantomJS. Not Safari yet.
travis server > browsers > clean test mac-only > codecov parallel with sonar > reports to codecov history
Resultsshould be no Failures or Errors:
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
Git knows whether the test passed by looking at environment variable. If it is zero, Git continues. Any other number, Git stops.
Scroll back up to see the run times, like this:
Total time: 19.101 s
Verify hook execution
No error message is issued if there is an error.
cd into your repo’s .git/hooks folder and execute the files:
The most common problem reported is not having the correct permissions set by
chmod +x git-commit
Use a text editor to create in the hooks folder a “pre-rebase” containing this text described in YouTube video Life’s better with Git hooks - Grumpy Gits [17:58] Nov 16, 2015 by Deepank Vora.
#!/bin/sh echo "Custom rebasing message." exit 1
(Unlike Windows, Linux defines file handling in the first line inside the file).
PROTIP: Non-zero finish aborts the commit.
Enable the new script:
chmod +x pre-rebase
This would avoid messages such as:
-bash: ./pre-rebase: No such file or directory
Run the new script to make sure it works:
Open another Terminal shell window to the working directory of the repo to run the
git rebase mastercommand.
You should see the custom message.
QUESTION: If instead you see:
Current branch master is up to date.
Use a text editor Set to always open .sample files with a text editor.
#!/bin/shat the top of the file means that it’s a Bash shell script.
(Author Junio C Hamano is the primary developer of Git, now works at Google.)
Scripts by language
Git will run any script that can run on the command line:
Bash shell is the default
To have Git run a PowerShell script on pre-commit, try to create a shell script
#!/bin/sh # pre-commit (no file extension) c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe \ -ExecutionPolicy RemoteSigned -Command .\.git\hooks\pre-commit.ps1
To test, put this
pre-commit.ps1 script in the folder:
023 Introduction to Git Hooks by Dan Gitschooldude
gated-commit with git pre-commit [12:41] by fullstack
Andrew Burgess for Tuts [7:28] June 28, 2012 describes run of mocha test processed by a Bash script.
More on DevOps
This is one of a series on DevOps:
- Choices for DevOps Technologies
- Java DevOps Workflow
- AWS DevOps (CodeCommit, CodePipeline, CodeDeploy)
- Digital Ocean
- Cloud regions
- AWS Virtual Private Cloud
- Git and GitHub vs File Archival
- Git Commands and Statuses
- Data Security GitHub
- Git Commit, Tag, Push
- Git Utilities
- Jenkins Server Setup
- Jenkins Plug-ins
- Jenkins Freestyle jobs
- Dockerize apps
- Docker Setup
- Powershell Ecosystem
- Powershell on MacOS
- API Management Microsoft
- Scenarios for load