Jump to Content
Developers & Practitioners

Push your code and see your builds happening in your terminal with "git deploy"

September 13, 2021
Katie McLaughlin

Senior Developer Relations Engineer

If you have used hosting services like Heroku before, you might be familiar with the user workflow where you run "git push heroku main", and you see your code being pushed, built, and deployed. When your code is received by the remote git server, your build is started. 

With source-based build triggers in Cloud Build, the same effect happens: you "git push" your code, and this triggers a build. However, you don't see this happen in the same place you ran your git push command. 

Could you have just one command that you run to give you that Heroku-like experience? 

Yes, you can. Introducing git deploy: a small Python script that lets you push your code and see it build in one command. 

You can get the code here: https://github.com/glasnt/git-deploy

This code doesn't actually do anything; it just shows you what's already going on in Cloud Build.  

Explaining what this code doesn't do requires some background knowledge about how git works, and how Cloud Build triggers work.

git hooks

Hooks are custom scripts that are launched when various actions occur in git, and come in two categories: client-side, and server-side. You could set up client-side hooks to do, for example lint checks before you write your commit message, by creating a .git/hooks/pre-commit file that runs your linter of choice. 

For server-side hooks, however, those need to be stored on the server. You can see server-side hooks running when git returns logs with the "remote: " prefix. Heroku uses server-side hooks to start deployments. GitHub also uses server-side hooks when you push a branch to a repo, returning the link you can use to create a pull request on your branch (for example: remote: Create a pull request for 'mytopic' on GitHub by visiting). 

However, since you as a developer do not have control over GitHub's git server, you cannot create server-side hooks, so that solution isn't possible in this instance. Instead, you can extend git on your machine.

git extensions

Writing extensions for git is remarkably simple: you don't actually change git at all, git just finds your script. 

When you run a command in git, it will first check if the command is one of it's internal built-in functions. If the command is not built-in, it will check if there is an external command in its 'namespace' and run that. Specifically, if there is an executable on your system PATH that starts with "git-" (e.g. git-deploy), it will run that script when you call "git deploy". This elegance means that you can extend git's workflow to do anything you want while still 'feeling' like you're in git (because you are. Kinda.)

Inspecting Cloud Build in the command line

Cloud Build has a rich user interface of its own in the Cloud console, and native integration into services like Cloud Run. But it also has a rich interface in gcloud, the Google Cloud command line. One of those functions is gcloud builds logs --stream, which allows you to view the progress of your build as it happens, much the same as if you were to view the build in the Google Cloud console. 

You can also use gcloud to list Cloud Build triggers, filtering by it's GitHub owner, name, and branch. With that unique trigger ID, you can view what builds are currently running, and stream them. You can get the GitHub identifying information by inspecting git's configured remote origin and branch.

Putting it all together

Given all the background, we can now explain what the git deploy script does. Based on what folder you are currently in, it detects what branch and remote origin you have configured. It then runs the code push for you. It then checks to see what Cloud Build triggers are connected to that remote origin, and then waits until a build for that trigger has been started. Once it has, it just streams the logs to the terminal. 

Suffice to say that this script doesn't actually do anything that's not already being done, but it just shows you it all happening in the terminal. ✨

(The choice to use Python for this script was mostly due to the fact I did not want to have to write regex parsers in bash. And even if I did, it wouldn't work for users who use other shells. Git extensions can be written in any language, though!)

Posted in