Reflecting Heroku push version within the app
Asked Answered
L

9

24

Every time I push my app to heroku I see the line

-----> Launching... done, v43

Is there a way to make that version number apear within the app so other people can see that number?

Lotion answered 9/1, 2012 at 17:41 Comment(6)
that's true, but I meant automagically :)Lotion
copy/paste is not a programmer's friend, automation is. See my answer to automate it.Benefactor
There is now a way to do this automatically with a Heroku labs feature, without writing any custom code. Check out this answer to see how to automate it.Felloe
Why did need to do setting changes? See my answer having a simple and global solution. #8793216Farrica
You should consider my answer as accepted as well if it works for you also without extra coding efforts. https://mcmap.net/q/543241/-reflecting-heroku-push-version-within-the-app My Answer is below u can use the linkFarrica
as this question was asked 6.5 years ago, I will leave it as is, since I don't have a way to check what is the better solution for me. I will bump you up for good measures :)Lotion
B
37

Why would you want to depend on running a command after every push? The accepted answer is worse than setting the config yourself.

Instead add to your Gemfile:

gem 'heroku-api'

Add your App name and API key to the Heroku config:

$ heroku config:add HEROKU_APP_NAME=myapp HEROKU_API_KEY=bp6ef3a9...

Then put something like this in config/initializers/heroku.rb:

unless (app_name = ENV["HEROKU_APP_NAME"]).nil?
  require 'heroku-api'

  heroku  = Heroku::API.new(:api_key => ENV["HEROKU_API_KEY"])
  release = heroku.get_releases(app_name).body.last

  ENV["HEROKU_RELEASE_NAME"] = release["name"]
end

Finally:

puts ENV["HEROKU_RELEASE_NAME"]
=> v42

Now it's fully automated. You can forget about it and continue to work on your app.

Bartley answered 12/3, 2013 at 17:2 Comment(5)
This is a very elegant answer, better than the accepted answer IMHO. Only thing I'd change is that the API key should also be part of the config, rather than hard-coded. Bear in mind that this exposes the API key for your account to all collaborators, so it might be better to add a specific collaborator for this purpose.Cabral
This worked great once it occurred to me that this only works when the app is running on Heroku... duh! I just through the ENV["HEROKU_RELEASE_NAME"] on my nav bar. Thanks!Susceptive
This solution has worked great but a word of warning. You have to keep the HEROKU_API_KEY updated manually. If you change the password on your Heroku account, you need to update the HEROKU_API_KEY configuration variable. This bit me this morning, you will see a "Invalid credentials provided." in the logs on startup if this happens.Susceptive
I believe this is now deprecated in favour of PlatformAPISubmergible
Here's a version that works with the new platformAPI: heroku = PlatformAPI.connect_oauth(ENV["HEROKU_API_KEY"]) <NEWLINE> release = heroku.release.list(app_name).last <NEWLINE> ENV["HEROKU_RELEASE_NAME"] = "v#{release['version']}"Merrygoround
F
20

It's now possible to try the Heroku feature Roberto wrote about in his answer, without contacting Heroku. It's called Heroku Labs: Dyno Metadata and you can enable it by

heroku labs:enable runtime-dyno-metadata -a <app name>

and then the information is available (on the next deploy) as environment variables:

~ $ env
HEROKU_APP_ID:                   <some-hash-appId>
HEROKU_APP_NAME:                 example-app
HEROKU_DYNO_ID:                  <some-hash-dynoId>
HEROKU_RELEASE_VERSION:          v42
HEROKU_SLUG_COMMIT:              <some-hash-slugCommit>
HEROKU_SLUG_DESCRIPTION:         Deploy 2c3a0b2
...

Note: Features added through Heroku Labs are experimental and subject to change.

We don't have to set up any config file or else.

Farrica answered 25/8, 2016 at 8:54 Comment(2)
This was the thinnest implementation for me, thanks!Rosinweed
@MattVukas Happy to help. sharing is caring. :)Farrica
B
7

After every push, run (assuming a bash shell):

heroku config:add rel=$(heroku releases | tail -2 | awk '{print $1}')

You can then just access the rel environment variable from your app.

Alternatively, if you'd like to present the date of the push, which, IMO, represents more meaningful information:

heroku config:add rel=$(heroku releases | tail -2 | awk '{print $5,$6,$7}')

Or, my favorite, which contains date and version with no whitespace:

heroku config:add rel=$(heroku releases | tail -2 | awk '{print $5"t"$6$7"."$1}')
Benefactor answered 9/1, 2012 at 18:52 Comment(4)
and you'll need to do this after every deployCloseup
This works but it causes your app to restart to apply the changed configuration. Not a show stopper but something to be aware of.Suet
Doesn't adding/changing the release configuration variable increment the release version (devcenter.heroku.com/articles/releases)? If so, then rel will always be one release behind and the date will be the previous release's date.Angus
@Angus It might. I hadn't noticed that. I'll probably modify the script to +1 the heroku releases and use $(date) instead. That said, since it's only a config change and not a code change (and hopefully doesn't change any code-paths), the version can really be considered to be correct with respect to the running code.Benefactor
P
4

I had the same problem and did it through a deploy POST HTTP hook. Basically the logic is that I created a specific URL in my app and I post the new value to update the config variable.

I did it in Python/Django, but I’m sure the same logic can be used for other languages as well:

import heroku
cloud = heroku.from_key(settings.HEROKU_API_KEY)
app = cloud.apps['mycoolapp']
latest_release = app.releases[-1]
app.config['RELEASE'] = latest_release.name
result['status'] = 200
Purington answered 12/4, 2012 at 8:18 Comment(0)
C
1

AFAIK you can only get the version via the CLI:

heroku releases --app <YOUR_APP_NAME>

You could do this via the Heroku gem from you app, but this is probably more trouble that it's worth.

Closeup answered 9/1, 2012 at 18:0 Comment(0)
C
1

You can make a Ruby file to do the following:

require 'heroku'

heroku = Heroku::Client.new('username','password')
puts heroku.releases('appname')

This returns a JSON document that contains a ton of metadata about your deploys include SHA, version number, etc.

Cheapen answered 2/5, 2012 at 23:39 Comment(0)
I
0

I am using Codeship so I plan on just adding this to the push config:

heroku config:add HEROKU_RELEASE_VERSION=$(heroku releases | head -2 | awk 'NR==2' | awk '{print $1}')

Note that the other similar answer is invalid since it is grabbing some of the later versions (it uses tail instead of head) and it tries to set it to two versions instead of just one (ie: v100 \n v101).

Iona answered 24/8, 2016 at 15:41 Comment(0)
A
0

In Node.js using JavaScript fetch (and the forthcoming async/await), you can do it with the following code (no push hooks!):

const fetch = require('node-fetch');
const url = 'https://api.heroku.com/apps/myapp/releases';
const headers = {
    Accept:        'application/vnd.heroku+json; version=3',
    Authorization: 'Basic '+base64Encode(':'+process.env.HEROKU_API_TOKEN)
};
const response = await fetch(url, { headers });
const releases = await response.json();
const lastRelease = releases[releases.length-1];
const version = lastRelease.version;
const created = lastRelease.created_at;

using

function base64Encode(str) {
    return new Buffer(str, 'binary').toString('base64');
}

Note this requires

$ heroku config:set HEROKU_API_TOKEN=\`heroku auth:token`.

See devcenter.heroku.com/articles/platform-api-reference#release-list.

Analgesia answered 14/12, 2016 at 11:51 Comment(0)
S
0

Following @jassa answer - but using the more recent PlatformAPI

if (app_name = ENV["HEROKU_APP_NAME"]).present? and ENV['HEROKU_API_KEY'].present?
  require 'platform-api'
  heroku = PlatformAPI.connect(ENV['HEROKU_API_KEY'], default_headers: {'Range' => 'version ..; order=desc'})
  released_at_s = heroku.app.info(app_name)['released_at']
  released_at_d = Time.parse(released_at_s).strftime('%Y-%m-%d')
  release = heroku.release.list(app_name).first
  deploy_v = release['description']
  version = release['version']
  ENV['HEROKU_RELEASE_NAME'] = "#{version} (#{deploy_v}) #{released_at_d}"
end
Submergible answered 19/7, 2017 at 5:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.