Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert git revision number into files during deployment

Tags:

git

fabric

What I'm doing I think should be fairly simple, but I can't seem to figure out how to make it work.

I want to embed a unique version number in html and javascript files, for two reasons. The first reason is that I want to ensure that when the javascript file is loaded, the system doesn't attempt to use the cache if there is a new version, but if I could call it using something like

 <script src="/app.js?v1.0.1-1-95425234"></script>

I could almost certainly ensure this never happens. The second reason is for my remote error logging, it would be good to know what version of the system is having errors so that I can look into fixing it appropriately, but without having to update this version number manually on every deployment.

I came across git describe along the way, and I think that it's output value would be really well suited for this.

Basically I want to take a key in my javascript and html files like GIT-CURRENT-VERSION and replace it with the output of git describe

I'm using fabric for my deployment method, so this would make a lot of sense to do on the server side, after we have grabbed the latest version of git.

I suspect some combination of sed and grep would do the trick here, and if I could figure out a one liner for this, it would be really easy to add to my deployment script.

Thanks in advance!

like image 837
Jamie Starke Avatar asked Oct 13 '12 19:10

Jamie Starke


People also ask

How do I keep git versioning?

As you say, versioning issues are usually solved in git using branch and tags (like semantic versioning pattern). The better way is to use git to track only changes in the codebase, ignoring (using . gitignore file) builds files and maintaining a clean repository.

How to add all files git add?

To add and commit files to a Git repository Create your new files or edit existing files in your local project directory. Enter git add --all at the command line prompt in your local project directory to add the files or changes to the repository.

Is revision same as commit?

So: a commit designates one of the git objects (others are blobs, tree, tags, notes), a revision is a way to reference a git object.


3 Answers

I have never heard of fabric, but if fabric uses (or calls) git archive, then you can use gitattributes. That is, you can can have your HTML files with something like:

<script src="/app.js?$Format:%H$"></script>

And in .gitattributes on top of the repository:

*.html    export-subst

Then, whenever you create an archive with git-archive, $Format:%H$ will be replaced by the hash of the commit. You can use whatever is available with --pretty-format in git-log.

Check the manual of gitattributes, or much better: the chapter "8.2 Customizing Git - Git Attributes" of Pro Git book to get more ideas.

like image 153
gpoo Avatar answered Oct 19 '22 09:10

gpoo


You could do something like the following from the root of your deployed git tree:

export VERSION="$(git describe)"
find . -type f -print0 | xargs -0 sed -i "s/GIT-CURRENT-VERSION/$VERSION/g"

(That's only had cursory testing - use with caution.)

Note that that will leave your tree with local modifications.

like image 28
Mark Longair Avatar answered Oct 19 '22 10:10

Mark Longair


Along guettli's comment, I thought I post the final result that I had. Here's my solution, based on Mark Longair's solution above.

export DESCRIPTION="$(git describe)"
find [PATH] -regextype posix-extended -regex ".*\.(js|html)" -type f -print0 | xargs -0 sed -i "s/CURRENT-GIT-DESCRIPTION/$DESCRIPTION/g"

I'll give a little explanation of what I'm doing here.

export DESCRIPTION="$(git describe)" Gets the current description of current state of the git repository. For more information, check out the git describe Manual Page.

Next, find [PATH] -regextype posix-extended -regex ".*\.(js|html)" -type f -print0 you can replace with the [PATH] with the path to your repository. -regextype posix-extended -regex ".*\.(js|html)" descends through your directories and finds all of the files matching the regex defined by ".*\.(js|html)". In my case, I know that I only want the replacements to occur in javascript or html files. Finally xargs -0 sed -i "s/CURRENT-GIT-DESCRIPTION/$DESCRIPTION/g" tells the system to replace the CURRENT-GIT-DESCRIPTION with the value defined by git describe above.

In my case, this works pretty well, as I'm using fabric for deploying to the server, and because I want the changes to occur real time, what I do is update the repository, and then copy it into a new deployment of the system. Once the system is ready to go, I get rid of the git data files, leaving this as just a regular data structure. Now I can just tell the system to use use the new build, and everything is ready to go.

Hope that helps other people looking to achieve something similar!

like image 21
Jamie Starke Avatar answered Oct 19 '22 09:10

Jamie Starke