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!
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.
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.
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.
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.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With