Git Hooks for iOS
Introduction
In this blog, we talk a lot about Continuous Integration (CI) and how it can help you to automate your development process. But what if you don’t want to set up a CI server? What if you just want to run some scripts before you commit your code? That’s where Git hooks come in. Git hooks are scripts that run automatically at certain points in the Git workflow. They can be used to enforce coding standards, run tests, or even send notifications. In this blog post, I’ll show you my favorite Git hooks that I use in my iOS projects. You can use them to make your life easier without a CI server. Let’s get started!
Pre-commit Hook
The pre-commit hook is run before a commit is made. This is a great place to run tests or check for coding standards.
I use mine to run SwiftLint
and SwiftFormat
to check for coding standards and format my code. Here’s how I set it up:
#!/bin/bash
# Pre-commit hook to run SwiftLint and SwiftFormat
# Check if SwiftLint is installed, if it's not - install it.
if ! command -v swiftlint &> /dev/null
then
echo "SwiftLint could not be found, installing..."
brew install swiftlint
fi
# Check if SwiftFormat is installed, if it's not - install it.
if ! command -v swiftformat &> /dev/null
then
echo "SwiftFormat could not be found, installing..."
brew install swiftformat
fi
# Run SwiftFormat first, as it might fix the linting issues
swiftformat .
# Run SwiftLint
swiftlint
# Check the exit code of SwiftLint
if [ $? -ne 0 ]; then
echo "SwiftLint failed, please fix the issues before committing."
exit 1
fi
echo "SwiftLint passed, ready to commit!"
Let’s break it down a bit, as you might not be familiar with all the commands or with bash scripts:
command -v swiftlint &> /dev/null
: This checks ifswiftlint
is installed. If it’s not, it installs it using Homebrew.swiftformat .
: This runsSwiftFormat
on the current directory. It will format your code according to the rules you have set up.swiftlint
: This runsSwiftLint
on your code. If there are any issues, it will return a non-zero exit code.if [ $? -ne 0 ]; then ...
: This checks the exit code of the last command. If it’s not zero, it means there were issues withSwiftLint
, and we exit with a non-zero code to prevent the commit.echo "SwiftLint passed, ready to commit!"
: If everything went well, we print a success message.
Pre-push Hook
The pre-push hook is run before you push your code to the remote repository. This is a great place to run tests or do some heavier things that you don’t want to run on every commit but still want checked, such as unit tests or integration tests. I use mine to run my unit tests before I push my code, using Fastlane. Here’s how I set it up:
#!/bin/bash
# Pre-push hook to run unit tests
# Check if Fastlane is installed, if it's not - install it.
if ! command -v fastlane &> /dev/null
then
echo "Fastlane could not be found, installing..."
gem install fastlane
fi
# Run Fastlane
fastlane test
# Check the exit code of Fastlane
if [ $? -ne 0 ]; then
echo "Unit tests failed, please fix the issues before pushing."
exit 1
fi
echo "Unit tests passed, ready to push!"
Again, let’s break it down a bit:
command -v fastlane &> /dev/null
: This checks iffastlane
is installed. If it’s not, it installs it using RubyGems.fastlane test
: This runs thetest
lane in your Fastlane setup. You can customize this to run any tests you want, or any lane that you’d like.
Adding the Hooks to Your Project
To add the hooks to your project, you need to create a directory called hooks
in your .git
directory. Inside this directory, create two files: pre-commit
and pre-push
. Make sure to make them executable:
chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/pre-push
Now, every time you commit or push your code, the hooks will run automatically. You can customize them to fit your needs.
Conclusion
These might seem like small things, but they can save you a lot of time and headaches in the long run. By using Git hooks, you can automate your workflow and make sure that your code is always in a good state before you commit or push it. I hope you found this blog post helpful! If you have any questions or suggestions, feel free to reach out to me on Twitter or leave a comment below.