Use Git commit sha to keep track of running version in production

Git is the de facto standard version control system in software development. For organizing Git Logoour issues and keeping track of the status we use the Kanban view of Jira.

Our last two columns on our Kanban board are:

  • Awaiting deploy
  • Done

All issues in the column “Awaiting deploy” are fully implemented and tested. The code has been reviewed by a 2nd developer and as result of the review process merged from the feature branch into our master branch. They are ready to be released to production.

Releasing to production is merging master branch into production branch and push it to our git repository. After this step all issues are moved from the column “Awaiting deploy” to “Done“. Now this column holds all issues that are new in production.

Our deployment script on server side will now pull this branch and restart the servers with the new code. A common way how to deploy Ruby On Rails applications. That means that the full repository is available on our production servers. This comes in handy if we want to determine the actual HEAD commit of our production branch.

We do this by calling “git rev-parse HEAD“.

To have this information available in our application we use the following code in a Rails initializer:

if Rails.env.production?
   commit_hash = `git rev-parse HEAD 2>/dev/null`.to_s.strip
   APP_VERSION = Time.now.utc.strftime("%Y%m%d-%H%M-") + commit_hash[-8..-1]
else
   APP_VERSION = Time.now.utc.strftime("%Y%m%d-%H%M-development")
end

To have this information easily accessible we render this information as html meta tag into all our sites:

<meta name="lingohub-version" content="<%= APP_VERSION %>"/>

results in:

<meta name="lingohub-version" content="20130412-1646-0ab4b155"/%>

This version will be now assigned to all issues in the “Done” column. We now know the date and the last git commit sha that runs in production.

For other SCMs these CLI commands would do the trick:

  • SVN: svn log -r HEAD
  • Mercurial: hg id -i

links:

i18n Resource File Formats: YAML files

We are continuing our series on localization resource file formats, this time with a closer look at one of the most popular formats, especially since the rise of Ruby/Rails in web development. For those not so familiar with YAML I suggest the very good basic introduction that the Wikipedia article provides.

YAML is a human-readable data serialization format. Its syntax was designed to be easily mapped to data types common to most high-level languages (lists, associative arrays and scalars). YAML is what we use for localizing Lingohub in our Ruby on Rails application. It has proven to be a very efficient production environment, especially used in conjunction with Github integration that Lingohub supports natively.

Unlike some other formats, YAML has a well defined standard. Let me outline some key features below followed by an example. As always, feel free to send us questions on these file types or others that you want to use to localize your apps.

Key features of YAML resource file format:

  • key-value pairs are delimited with colon ( : )
  • values can be surrounded by quotes
  • correct and consistent line indentation is important
  • comments start with a hash sign ( # ), and are ignored by the parser
  • in the Lingohub context, all comment lines directly preceding a key-value pair (with no blank lines in between) are treated as translation descriptions or LingoCheck rules belonging to that line.
  • place-holder syntax is: %{name}, where “name” can consist of multiple non-white-space characters
  • we use UTF-8 encoding for YAML resource files exports by default, but we also support other encodings our users might prefer.

An example of a YAML localization resource file format:

References:

We are continuing our series on localization resource file formats with with some other popular file types soon, stay tuned and feel free to post questions below.

BaRuCo – Barcelona Ruby Conference


Last weekend I had the great chance to be part of BaRuco. A Ruby conference in sunny Barcelona. Believe it or not, it was my first time visiting this great city.

BaRuCo, organized by :codegram, was a fine Ruby conference with a bunch of great talks. The agenda was quite dense. 8 talks per day. Maybe a bit too dense but I will talk about that later.

Cosmo Caixa

First of all I really want to thank the organizers for choosing the venue: Cosmo Caixa, a technology museum, is a great place to stay for two days. Actually it is a kind of museum I have never seen before. Cosmo Caixa exhibition is quite unstructured with no real topic and it is a good thing. If you visit Barcelona you have to visit this place!

Talks

There are some talks I like to mention:

PROGRAMMING WORKOUT, BY MICHAŁ TASZYCKI

Michal talked about the passion to continuous learning. How you keep your fire burning to improve yourself and stay focused. Plus some tricks to set your goals wisely.

TRACING YOUR WAY THROUGH RUBY, BY ELISE HUARD

A great talk about using dtrace and how to probe your Ruby application if anything else does not give you that granular level of insight. Aaron Patterson already added dtrace probes to MRI, but we have to wait for Ruby 2.0.

RUBYMOTION FOR FASTER CLIENT/SERVER DEVELOPMENT, BY RANDALL THOMAS & TAMMER SALEH

The two guys of Thunderbolt Labs gave a good insight to using RubyMotion in client projects. RubyMotion promises to develop iOS application in Ruby. The presentation included information how RubyMotion development differs from your known Ruby development (eg. you cannot use require and gems).

IT’S NOT HOW GOOD YOUR APP IS, IT’S HOW GOOD YOU WANT IT TO BE, BY JOSH KALDERIMIS

If you have never seen Josh on stage – go for it!
This talk explained how the guys of Travis CI use several techniques to monitor what’s going on in their application. Ranging from using ActiveSupport Notifications to add custom log entries. Papertrail to aggregate and browse their logs. Josh told me that his talk will be online soon.

Seen crititical

As I mentioned the schedule was quite dense, hence most of the time was spent sitting in the Auditorium. But besides listening to great talks, most of us who attend at a conference want to use some time to meet other developers. Chat about what you do and how you enjoy it. There was no real chance to skip a talk in advance to prolong a nice chat you just started during the short coffee break. The space outside of the auditorium was shut off for the “real” guests of the museum, so everyone automatically moved in again.

See you there next year!

 

 

Ruby: ensure_encoding to ensure your encoding

Consider following situation: you receive a file, either from your drive or from HTTP, and you have no clue what encoding was used for the content of this file. Nothing is stored with the content that indicates the encoding. Even scanning the file’s content doesn’t help to derive the encoding. It is just a series of bits and bytes. Every byte maps to a different character based on the used charset. A ISO-8859-1 file may have the same byte sequence as a UTF-8 file. But just by applying the correct encoding as mapping will lead to a meaningful sequence of characters.

You can consider yourself lucky if:

  • you know the file type and which can indicate the encoding
  • the actual encoding is stored inside the file’s content. For example the encoding directive in XML files (which of course can be wrong as well)

At lingohub we use file types to parse language resource files:

Unfortunately, this is the theory, in practice the file’s encoding can be anything . Even developers touching this resource files might not know which encoding is set in their editor. They never had to think about that. The code they edit just works fine since it hardly includes localized characters or is just executed in a similar environment as it was written.
But now imagine that you send your language resource files to your translator. The resource file then gets edited on a Windows systems and is would be automatically saved CP-1257 encoded. You don’t expect that a translator with no technical background will be aware of the fact that your resource file parser actually expects UTF-16, do you?

At lingohub had to find a solution for such a situation. Our import must handle *all* resource files regardless of the used encoding. Like above mentioned there is not actual evidence that indicates the encoding 100%, however, we found a way which works quite well:

  1. Importing the file in binary format.
  2. Start to apply an encoding to this byte sequence,
  3. if it fails, try the next encoding.
  4. Until the conversion works out fine.

Because this is a common approach there are several implementations out there. We have chosen ensure_encoding. It does a great job (even it is called experimental).

After requiring this gem through

  • gem ‘ensure-encoding’, ’0.1′

it will add the ensure_encoding() method to String. This will give you the power to convert the given String to your preferred encoding without actually knowing the input encoding.

This usage will try to convert a String to UTF-8 while ‘sniffing’ the actual input encoding. 

Since it is not always possible to convert every character to the chosen target encoding there are several options how to handle that situation by setting the :invalid_characters option:

  • :transcode – will always try to convert characters
  • :raise – will raise an exception
  • :drop – will drop all non convert-able characters
The readme covers some scenarios, so one may choose which option would be the best fit.

While the ‘:external_encoding => :sniff’ option works great for UTF-16 and UTF-8, it is not able to handle all encodings we have to support for importing/exporting i18n resource files, we haven chosen to give ensure_encoding a hint which encodings we expect:

The Importance of an API

I have worked on many software projects over the last couple of years. One aspect that became more and more important is an API (Application Programming Interface). A decade ago an API was just classes/interfaces that a developer could use to interact with a library/framework, mostly in the same language. As systems became more and more complex and diverse, SOAP quickly rose as a defacto standard in the Java/.NET community to communicate between systems. However, once again Ruby on Rails showed that things don’t need to be complicated to be useful, and it integrated parts of Roy Fielding’s dissertation of a Restful approach (REST). Since then, REST has become the standard for nearly every Web application. Many standard apps build REST APIs that allow users and developers to integrate with their services. Twitter is a prime example that creates and builds value with such an approach.

We here at linguist strongly believe that creating a vibrant community is a key factor for our success. That is why we offer an API right from the beginning. The API supports many different actions like uploading/downloading resources, creating projects, inviting new collaborators, listing collaborators…You can find a full listing in our API overview. The documentation covers all necessary information about the entry points and shows how to use the API. We planned the API with your needs and requirements in mind, and it’s now up to you to let us know what’s missing and what can be improved. If you have trouble using the API or have ideas or questions, simply create a ticket on our support page.

I’m totally excited about linguist and can’t wait to implement all those awesome features you come up with! Happy translating.

Further readings on good REST APIs: