13

I have a meteor application that has different branches for different clients. This is because clients want special things. Of course right?

I would like to be able to place the git branch and tag/hash for the deployed version of the app for that client in the UI somewhere.

The question is how? Is there a way in Meteor to get this information and simply use it?

Thanks!

DigiLord
  • 1,014
  • 1
  • 10
  • 17

5 Answers5

11

In my production apps I solved this issue in this way:

Files

App/.git/hooks/post.commit

App/MeteorApp/hooks/post-commit-version

App structure:

App
  .git
     hooks
       post-commit (file)
  MeteorApp
    client
    server
    both
    private
      version.json
    hooks
      post-commit-version (file)

Whenever developer commits code .git/hooks/post-commit is executed which executes nodejs script stored in App/MeteorApp/hooks/post-commit-version.

Script post-commit-version generates version.json in App/MeteorApp/private dir in format:

{
  "timestamp": "29-08-2014 23:16",
  "branch": "master",
  "commit": "3332f6dcbde57105a8dc353e5e878651cab89856"
}

Everything stored in private is accessible to server on production.

How to display version.json in app ?

App/MeteorApp/both/collections/Version.js:

Version = new Meteor.Collection('version');

App/MeteorApp/server/startup.js

Meteor.startup(function(){
    if (Version.find().count() > 0){
        Version.remove({});
    }
    Version.insert(JSON.parse(Assets.getText("version.json")));
})

After application is deployed it will fire startup callbacks and version will be inserted to collection Version.

App/MeteorApp/server/publish/version.js:

Meteor.publish('version', function () {
  return Version.find();
});

App/MeteorApp/client/startup.js:

Meteor.startup(function(){
  Meteor.subscribe("version");
})

And then somewhere in template simply create helper:

Template.template_name.helpers({
  version:function(){
   return Version.findOne();
  }
})

In template_name you display version using {{version.commit}} {{version.branch}} {{version.timestamp}}.

Side note 1

Script post-commit-version don't have js extension, because I don't want meteor to include it in bundle or reload app in development every time I change this file. However it is possible to use post-commit-version.js when that file is stored in .dir (like App/MeteorApp/.hooks) as directories having . as first character are not processed by meteor.

Side note 2

Another possibility would be load version.json on server side Meteor.startup, parse json and attach to global variable like App.version. Later use it with Meteor.method:

Meteor.methods({
  getVersion:function(){
   return App.version;
  }
})

On client you simply call method:

Meteor.call("getVersion", function(error,version){
  if(error)  {
    throw new Error("Cannot get version");
    return;      
  }

  Session.set("version",version)
})

Some template's helper could use it :

Template.template_name.helpers({
  version:function(){
    return Session.get("version");
  }
})
Community
  • 1
  • 1
Kuba Wyrobek
  • 5,273
  • 1
  • 24
  • 26
  • Thanks for the idea, but I feel like your post-commit-version script is overly complex. I condensed it to [this version](https://gist.github.com/JcBernack/2a4471abb2e13d3ec0b7). Note that I replaced grep with findstr because I'm on windows. – Gigo Sep 22 '15 at 06:39
  • @Gigo your idea seems to be much simpler. Thank you ! – Kuba Wyrobek Sep 22 '15 at 06:47
  • I like this approach, but doesn't it result in the version.json always being one commit behind the last one? It did so for me, found the solution here: http://stackoverflow.com/questions/3284292/can-a-git-hook-automatically-add-files-to-the-commit (answer by bitluck) – pors Oct 08 '15 at 08:15
  • Not really... Of course `version.json` is generated in post-commit hook and it is not included in that commit ( it is impossible to eat cake and have cake, right), but when you deploy your app will include `version.json`, which contains actual data. I usually put `version.json` to new changelist ( called version ), so it is very rarely committed. – Kuba Wyrobek Oct 10 '15 at 06:34
  • I think the biggest drawback of this approach, and the reason we won't use it, is that the version is served in data from the server. I want to know which version of the **client** code the user has. So any methods or subscriptions won't work. I guess we'll use something similar but update a client side file. – chmac Dec 13 '15 at 10:55
  • @chmac good luck, it will be great to see how you are going to solve your issue. – Kuba Wyrobek Dec 14 '15 at 11:02
  • 1
    @KubaWyrobek I wrote up a gist, just for you... :-) https://gist.github.com/chmac/fcd6d3af33e8f19e116c – chmac Dec 14 '15 at 14:36
  • @chmac This is awesome, super simple ! Thanks – Kuba Wyrobek Dec 14 '15 at 20:22
  • @KubaWyrobek Having deployed this, I realise that it'd be better to declare the version number as a global variable and then render it into the UI. That would allow us to do stuff like report it to the server on startup, so we could get insights into which versions are deployed, where hot code reloading is behind, and so on. That'll probably be our next version... – chmac Dec 17 '15 at 08:57
5

I just wrote a package for that and published it on Atmosphere. The package comes with an Template-Helper to show your git commit hash, tag or branch just like this:

<div>
  <p>short hash: {{gitRev 'short'}}</p>
  <p>long hash: {{gitRev 'long'}}</p>
  <p>tag: {{gitRev 'tag'}}</p>
  <p>branch: {{gitRev 'branch'}}</p>
</div>

See atmospherejs.com/johdirr/meteor-git-rev for details.

johipsum
  • 101
  • 1
  • 5
  • I am having a dependency issue I think. I get: Exception in template helper: ReferenceError: check is not defined at .../johdirr_meteor-git-rev.js:70:3 – Turbo Dec 08 '16 at 04:59
2

For the most part I liked Kuba's answer and I actually tried to use his node script but ran in to problems with the promise library. Anyway, I wrote my own post-commit bash script and I think it's cleaner and easier like this.

ver=$(git describe --abbrev=0)
complete=$(git describe)
branch=$(git rev-parse --abbrev-ref HEAD)
commit=$(git rev-parse HEAD)
timestamp=$(git log -1 --date=short --pretty=format:%cd)
cat > private/version.json << EOF
{
    "basic": "$ver",
    "complete": "$complete",
    "branch": "$branch",
    "commit": "$commit",
    "timestamp": "$timestamp"
}
EOF

I agree with everything else in Kuba's answer on where to store the file and how to access it in the server.

Mark Lynch
  • 21
  • 2
1

I tried a different approach based on what I have seen here, and just in case anybody needs to get the version from the client too, here's a windows based answer:

pre-commit file

#!/bin/sh

node auto-version
RETVAL=$?

if [ $RETVAL -ne 0 ]
then 
 exit 1
fi
exec git add ./pathTo/_version.js

auto-version file

var execSync = require("child_process").execSync;
var path = require("path");
var fs = require("fs");
var outputFile = path.normalize(__dirname + "/pathTo/_version.js");
var currentVersion = JSON.parse(fs.readFileSync('./pathTo/_version.js', 'utf8').replace("myVar =" , ""));

function parse(cmd) {
    var stdout = execSync(cmd, { encoding: "utf8" });
    return stdout.replace("* ", "").replace("\n", "");
}

try {
    console.log("vers",currentVersion);    
    var myVar = JSON.stringify(
    {
        version: currentVersion.version+0.01,
        timestamp: new Date(),
        branch: parse('git branch | findstr "*"'),
        pre_commit: parse("git rev-parse HEAD")
    },null,2);

    fs.writeFileSync(outputFile, "myVar = " + myVar +"\n");
    console.log("Succesfully updated " + outputFile);

} catch(err) {
    console.log("Error updating " + outputFile);
    console.log(err);
}

initial _version.js file

myVar = {
  "version": 0.00,
}

So you just make a commit, run your app, open browser's console and type myVar.version (of course this is just a simple example)
Notice that _version.js will be marked as changed after the commit, but the version update is actually commited, so just ignore the file being marked. You can complete this method with the post-commit technique from Kuba Wyrobek to get the post-commit git version (in my case knowing the previous one is enough).

tcastelli
  • 35
  • 8
1

You can use Meteor.gitCommitHash on both client and server.

Nathan Schwarz
  • 631
  • 5
  • 19
  • Is this documented somewhere? I only found this PR https://github.com/meteor/meteor/pull/10442 – Jirik Apr 09 '20 at 14:13
  • It's not "documented" per say (because the name is explicit). You can find it on Meteor changelog thought: https://docs.meteor.com/changelog.html#v18120190403 – Nathan Schwarz Apr 09 '20 at 15:59