Adding git commit hash to build/compilation

Hey,

I would like to add the current git hash to my compiled binary, so that I can identify the binary, when running in production (enjoying a webapp running on k8s with a number of replicas, which means all replicas must be updated/deleted and I’d like to be sure that this has happened). Is there any fancy hook into crystal build that I could use or does anyone have better ideas than that?

Thanks for any help!

–Alex

Try this:

commit_hash = {{ `git rev-parse HEAD`.stringify }}
puts commit_hash

Basically, {{ ... }} is macro code at compile-time, and you can use backtick to execute something at compile time. That returns the output, and we make that a string literal.

Just beware that if the command fails, the compilation fails, so you won’t be able to compile your program (which might be something desirable, depending on what you want).

2 Likes

works like a charm, thank you!

I think I asked something similar recently, and was cautioned about doing this because the compile cache would not be updated unless the file to compile had changed?

So, if you do that in a file that does not change in a commit, the result might be wrong.

Right?

I think I asked something similar recently, and was cautioned about doing this because the compile cache would not be updated unless the file to compile had changed?

No, that shouldn’t happen. You should probably tell whoever told you that that it’s not true, so the belief doesn’t spread.

  # NOTE: the compiler is allowed to cache the executable generated for
  # *filename* and only recompile it if any of the files it depends on changes
  # (their modified time). This is why it's **strongly discouraged** to use a program
  # for `run` that changes in subsequent compilations (for example, if it executes
  # shell commands at compile time, or other macro run programs). It's also strongly
  # discouraged to have a macro run program take a lot of time, because this will
  # slow down compilation times. Reading files is OK, opening an HTTP connection
  # at compile-time will most likely result in very slow compilations.
  def run(filename, *args) : MacroId
  end

I think this might have been where I got the Idea that it would be cached from.
It’s about the “run” method, and not a general thing.

But out of curiosity, if I compile a project, then commit the last changes, then compile again without changing any files, would the new executable pick up the changed commit hash even though no source file was changed?

Yes.