Skip to content

Instantly share code, notes, and snippets.

@farhad-taran
Last active September 7, 2020 08:32
Show Gist options
  • Save farhad-taran/d6203eaf7b14d7d2eb5e852b689c7b0b to your computer and use it in GitHub Desktop.
Save farhad-taran/d6203eaf7b14d7d2eb5e852b689c7b0b to your computer and use it in GitHub Desktop.
Automatically Running custom git hooks in DotNet Solutions

Add the custom git-hooks described further down in the page to the folder ./scripts/git-hooks relative to the root of the repository.

If you are using a linux based machine, make sure that the hooks are executable, chmod +x "$f" before you commit them to your git history. you can achieve that by running the following script.

for f in ./scripts/git-hooks
do 
   chmod +x "$f"
done

Add the following code to the main .csproj of your solution. The following dotnet pre-build task will run before building the project and will only copy files that have been changed since the last build. this will allow you to keep a copy and history of your custom git-hooks along with the solution and will make sure that any subsequent contributors to the solution will automatically benefit from the custom git hooks.

<Target Name="CopyGitHooks" AfterTargets="BeforeBuild">
    <ItemGroup>
        <GIT-HOOKS Include="$(SolutionDir)\scripts\git-hooks\*.*" />
    </ItemGroup>
    <Copy SourceFiles="@(GIT-HOOKS)" DestinationFolder="$(SolutionDir)\.git\hooks" SkipUnchangedFiles="true" />
</Target>

Pre-Commit Hook to Run Code Formatter

The dotnet code formatter is a dotnet tool that needs to be installed once prior to running the git-hooks. you can install the code formatter using the snippet below.

dotnet tool install -g dotnet-format

Add a common .editorconfig to the root of your repository, this file will allow for common coding standards across different projects and IDEs.

Add the following pre-commit git hook to the custom git-hooks folder, this will run the code formatter based on the .editorconfig prior to a git commit.

This step might cause new unstaged changes due to formatting of the files, which will require a new commit.

#!/bin/sh

# run code formatter
preFormatChanges=$(git status -s -uno | wc -l)

dotnet format --verbosity diagnostic

postFormatChanges=$(git status -s -uno | wc -l)

GREEN='\033[1;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color

if [ "$preFormatChanges" -ne "$postFormatChanges" ];
then 
    echo "${RED} ${postFormatChanges} extra files changed after formatting code!${NC}";
else
    echo "${GREEN}No extra file changes detected after formatting code!${NC}";
fi;

Pre-Push Hook To Run Unit Tests

Add the following pre-push git hook to the custom git-hooks folder. This custom git hook will be run every time a push is made to a branch and will run all the tests in the solution, if any test fails then the push is cancelled.

#!/bin/sh

# run tests
protected_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
RED='\033[0;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# only run this if you are pushing to master

echo -e "${YELLOW}Running pre push to branch check...${NC}"

echo -e "${YELLOW}Trying to build tests project...${NC}"

#Let's speed things up a little bit
DOTNET_CLI_TELEMETRY_OPTOUT=1
DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1

# build the project
dotnet build

# $? is a shell variable which stores the return code from what we just ran
rc=$?
if [[ $rc != 0 ]] ; then
    echo -e "${RED}Failed to build the project, please fix this and push again${NC}"
    echo ""
    exit $rc
fi

echo -e "${YELLOW}Running unit tests...${NC}"
echo ""

# run the unit tests
dotnet test

# $? is a shell variable which stores the return code from what we just ran
rc=$?
if [[ $rc != 0 ]] ; then
    # A non-zero return code means an error occurred, so tell the user and exit
    echo -e "${RED}Unit tests failed, please fix and push again${NC}"
    echo ""
    exit $rc
fi

# Everything went OK so we can exit with a zero
echo ""
echo -e "${GREEN}Pre push check passed!${NC}"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment