Use Travis to build and deploy your Jekyll site through SSH

An image of bricks with the Jekyll, GitHub and Travis logos on it

After transitioning my blog to Jekyll my next goal was to have the site built and deployed via an external service which is automatically triggered by pushing to a certain GitHub branch (in my case master).

I achieved this a few years ago by using DeployBot but their free plan only supports the deployment of one site and it wasn’t ideal anyway because I had to run the build on my end, so I started researching how can this be done with one of the continuous integration services out there which support unlimited open source builds.

While searching around I found plenty of articles dealing with deploying to GitHub pages (this looks to be the most popular scenario) but only a handful about deploying to your own server. This motivated me to document my solution, so that if I happen to change the hosting I don’t have to figure out everything again and maybe also help others who stumble upon this article.

I choose Travis as the CI service because I’ve used it for jekyll_asset_pipeline and some other open source side projects I’m working on.


Building a piece of software usually consists of the build part itself followed by automated testing. The actual build part in Jekyll’s case is straight forward, the command is even called jekyll build, but I was wondering about the second part: as opposed to an application what can you test on a static site? The answer came as html-proofer which checks your site’s HTML files for the correctness of local and outbound links, image references, the presence of alt tags on the images, etc.

Continuous integration of a Jekyll site with Travis is documented on the official site so I will only describe what I changed.

I decided to run html-proofer through rake instead of a stand alone command so I could add configuration more easily. My Rakefile looks like this:

require 'html-proofer'
task :test do
  options = {
    disable_external: true,
    url_ignore: [
  HTMLProofer.check_directory("./_site/", options).run

I disabled the checking of external links because this blog has some ancient content with links that died a long time ago. The /feed/ directory is redirected from the vhost config so I set that to be ignored.

Try it out by running rake test (after running jekyll build of course). Does it pass? Great! It doesn’t? Get editing!

At this point my .travis.yml read:

language: ruby
- 2.4
  - NOKOGIRI_USE_SYSTEM_LIBRARIES=true # speeds up installation of html-proofer
  - master
  - bundle exec jekyll build
  - bundle exec rake test

I’d say it’s pretty self explanatory. The one line that isn’t comes with a comment.

Don’t forget to add rake and html-proofer to your Gemfile to be able to run the build on Travis. Also don’t forget to add vendor to your exclude: list in Jekyll’s _config.yml or else all hell will break loose. I warned you.

After pushing to the master branch on GitHub the project should successfully build on Travis.


On to the deploy part which is based on this article.

In this step we’ll be deploying the _site directory which we generated during the previous step to our hosting server through a secure SSH connection. To be able to do this we’ll need to generate an RSA key pair, add the public key as trusted to our hosting server and give Travis the private key. Wait, what? But how do we protect it from the public eye? Never fear, Travis provides us with the means to encrypt it, by using the travis utility which has to be installed to the local machine by running gem install travis.

Let’s get to work!

First of all it is recommended to create a separate deploy user on the hosting server and set the directory which the site is served from to be writable by this user. Then generate the RSA keypair by running the following command in the project’s directory on the local machine:

$ ssh-keygen -t rsa -b 4096 -C '' -f ./deploy_rsa

This results in deploy_rsa and, the private and public keys respectively. Whatever you do, don’t check these into your site’s git repository and don’t build your site while they’re sitting there. We’ll delete them soon.

Now encrypt the private key:

$ travis encrypt-file deploy_rsa --add

If this is the first time you’re running the travis utility you will get:

not logged in - try running travis login --org

Which should be done in order to associate the Travis build with this directory and make our life easier in the future.

But what happened? The utility created a deploy_rsa.enc (an encrypted version of the private key), with a decryption key that it stored as an environment variable on Travis and also added some lines to the .travis.yml file which will decrypt the private key file during the build.

Now add the public key to the list of accepted keys on the hosting server:

$ ssh-copy-id -i <ssh-user>@<deploy-host>

The unencrypted private key as well as the public key can now be deleted from the local machine:

$ rm -f deploy_rsa

Once this is done the previous no-check-in / no-build ban is lifted so add deploy_rsa.enc to the git repository.

Now edit .travis.yml and move the decryption line from the script: section to the before_deploy: section and modify as follows:

- openssl aes-256-cbc -K $encrypted_<...>_key -iv $encrypted_<...>_iv
  -in deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy\_rsa
- ssh-add /tmp/deploy\_rsa

This ensures that before the deploy is done the private key is decrypted and loaded into memory.

What’s left to do is the deployment itself. This will be done with rsync and we want to keep the deployment host, user and directory secret because we don’t want script kiddies sniffing around our hosting server now, do we?

Run these on the local machine in the project directory:

$ travis encrypt DEPLOY_DIRECTORY=<deploy directory> --add
$ travis encrypt DEPLOY_HOST=<deploy host> --add
$ travis encrypt DEPLOY_USER=<deploy user> --add

These will add three lines starting with - secure to the section of .travis.yml. Add the following to the before_deploy: section of the same file:

- echo -e "Host $DEPLOY_HOST\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

This ensures that the deploy process doesn’t hang waiting for user input.

And now for the grand finale! Add to the end of .travis.yml:

  provider: script
  skip_cleanup: true
  script: rsync -r --quiet --delete-after _site/* $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_DIRECTORY
    branch: master

skip_cleanup ensures that the result of the build is not deleted before we transfer it. --delete-after’s effect is that it will clean the directory on the hosting server before uploading the freshly built site so that there are no left overs or forgotten files.

The final version of my .travis.yml file looks something like this:

language: ruby
- 2.4
  - secure: <secure $DEPLOY_USER>=
  - secure: <secure $DEPLOY_HOST>=
  - secure: <secure $DEPLOY_DIRECTORY>=
  - master
- bundle exec jekyll build
- bundle exec rake test
- openssl aes-256-cbc -K $encrypted_<stuff>_key -iv $encrypted_<stuff>_iv
  -in ./deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy_rsa
- ssh-add /tmp/deploy_rsa
- echo -e
  "Host $DEPLOY_HOST\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
  provider: script
  skip_cleanup: true
  script: rsync -r --quiet --delete-after _site/*
    branch: master

And with this we’re done! Push to the master branch on GitHub and sit back and relax while your site is automagically deployed by Jenkins. Well, possibly it won’t happen on the first try, but hey, once it does I guarantee an overwhelming feeling of satisfaction for the nerd inside you.

As an additional note, when I’m proof reading my site and making small changes to many files by multiple commits through the GitHub web interface I usually add [ci skip] to the commit messages so that I don’t overwhelm Travis. They’re giving me something for free and I tend to respect that by not abusing their service.

Header image by Alan Levine, found on Flickr.

Capsula timpului muzicală

După atâția ani de MP3 și muzică digitală, anul trecut m-a prins și pe mine fascinația sculelor audio “vintage” și printre altele mi-am luat un casetofon deck Technics la un preț incredibil față de cât costa pe vremea adolescenței mele când un asemenea aparat aparținea de domeniul viselor.

Tot scotocind prin vechea mea cameră din Baia Sprie după casete mi-am găsit și organizatorul de casete murdar și foarte prăfuit că zăcea nefolosit de vreo 15 ani. Așa că l-am adus la Baia Mare să-l spăl în mașina de spălat vase…

Organizatorul meu de casete

Spălătura s-a întâmplat, dar după câte se vede în poza de mai sus nu a avut tocmai efectul scontat și apoi o vreme rack-ul a așteptat pe hol să fie dus înapoi. Într-o dupămasă l-am găsit căzut pe jos cu piesa de legătură ruptă (în poză apare deja lipită).

Organizatorul spart

Când să-l montez la loc am întrezărit ceva ce părea a fi o hârtie împăturită în spațiul gol din interior…

Ce se vede?

Erau de fapt două hârtii împăturite.


După ce le-am despăturit mi-am dat seama că erau coperți pentru două casete cu selecții înregistrate de mine.


Menționez aici că grafica de pe această copertă a fost rezultatul încercării mele de atunci de a desena ceva cu elemente abstracte similar cu ce văzusem pe casetele poloneze semi-pirat de atunci.

Vara lui 1994 a însemnat pentru mine vacanța dintre școala generală și liceu, respectiv pregătirea pentru admitere. Fiind un procrastinator profesionist de la o vârstă fragedă, am așa o vagă presupunere că am înregistrat casetele și am desenat coperțile în perioada când trebuia de fapt să învăț pentru admitere.

Deduc din lista de piese că eram fascinat de euro dance, probabil de la finalul clasei a VIII-a (sau a opta, să nu par academician) când, clasa noastră ca să fie mai cu moț a organizat nu mai puțin de trei(!) serate de adio. Serate la care acesta a fost genul de muzică dominant.

Îmi mai amintesc că nu prea îmi permiteam să-mi cumpăr casetele cu selecții poloneze, dar aveam o colegă care își lua săptămânal ce mai apărea nou la băieții care veneau la taraba de la piață. Eu probabil împrumutasem de la cineva câteva casete și mi-am ales de pe ele ce-mi placea.

Aceasta a fost epoca când informațiile muzicale mi le luam din Ecran Magazin (o variantă autohtonă mai ieftină pentru revistele Bravo și Popcorn) și de la emisiunea de dedicații muzicale prezentată de Delia și DJ Zsolt care rula în fiecare seară la Cinemar Baia Mare.

Dar să vedem ce muzică era pe aceste casete? Pe verso-ul coperții artistice prezentate mai sus (pe care am menționat și că e volumul 1) găsim prima listă de piese:

Prima listă de piese

Side A

  1. Capella - U Got 2 Let The Music // Euro dance cum scrie la carte.
  2. Billy Joel - The River Of Dreams // Îmi amintesc că stăteam pe gânduri dacă s-o înregistrez sau nu că nu prea îmi plăcea. Cu urechile de acum consider că e una dintre cele mai OK muzici listate aici.
  3. Loft - Hold On // Ca și Capella mai sus, o piesă euro dance destul de cunoscută.
  4. 2 Unlimited - Faces // A trebuit s-o reascult să-mi amintesc ceva de ea. Ce versuri descriptive.
  5. Madonna - Rain // Vai, cât de mult mi-a plăcut asta. Am ascultat-o de jde ori și știu că odată am dat volumul atât de tare încât mi s-a încălzit amplificatorul Electronica 3220 de mirosea. Chiar și acum zic că e OK.
  6. DJ Bobo - Take Control // Tot o piesă clasică euro dance, doar că nu prea îmi plăcea DJ Bobo. Și atunci de ce am înregistrat-o?

Side B

  1. Salt N’ Pepa - Watta Man // De fapt “Whatta Man feat. En Vogue”. Ce? Salt ‘N’ Pepa mai au și alte piese în afară de “Push It?” Glumesc, de asta chiar îmi amintesc cu refren cu tot.
  2. Maxx - No More // Euro dance tot după rețeta care s-a dovedit atât de succes în acei ani. Îmi aminteam de refren.
  3. Intermission - Six Day // De fapt “Six Days”. Idem mai sus.
  4. Magic Affair - Omen III // “Do what you want but don’t forget the omen.” Din nou, am reușit să citez în mare refrenul chiar înainte să re-ascult.
  5. Take That - Babe // Wow, boybands. Nu știu de ce am înregistrat-o.
  6. Doop - Doop // Asta mi-a plăcut cu toate că era super copilăroasă și mă amuza idea că dacă întorceai invers “doop” se citea la fel. Chiar mi-a influențat niște alegeri de pseudonime pe web.
  7. Ace Of Base - Don’t Turn Around // Ace Of Base, marea revelație a acelor ani, îi prezentau ca următoarea ABBA…
  8. Freddie Mercury - Living On My Own // Vai, ce i-au făcut lui săracu’ Freddie? Știți voi, e melodia cu “vino lele”, “viorele”…

Mai sunteți aici? OK, trecem la a doua listă:

A doua listă de piese

Side A

  1. Prince Ital Joe featuring Marky Mark - United // Știu că am citit relativ recent pe Wikipedia că Prince Ital Joe a murit în 2001 și mai știu că m-am amuzat copios când am citit un comentariu pe YouTube la această piesă sau alta cu Marky Mark (cunoscut în ziua de azi ca actorul Mark Wahlberg) care zicea ceva de genul: “this was back when Mark Wahlberg was a real ni**a”.
  2. CO.RO. - There’s Something Going On (Mix) // Aveam o fascinație cu CO.RO că înainte cu vreun an tot stând la pândă să înregistrez piese de la radio am prins o parte din “Because The Night” și mi s-a părut extraordinară.
  3. Haddaway - Life (Mix) // Nu prea mai știu nimic despre piesă doar că e o altă piesă de-a lui Haddaway, căntărețul cu “What Is Love” care o știe toată lumea din scena cu Jim Carrey.
  4. Joshua Kadison - Jesse // De fapt “Jessie”. O baladă a cărei refren o mai știam aproximativ. Știu că atunci eram suprasaturat de piesă, dar acum chiar am ascultat-o cu plăcere.
  5. Roxette - Sleeping In My Car // Asta iarăși nu știu de ce am mai înregistrat-o și pe caseta cu selecții, că oricum eram fan înrăit Roxette și sigur o aveam deja pe albumul Crash, Boom, Bang. Poate era o încercare de-a mea de a promova Roxette pentru audiența casetei cu selecții, care eram tot eu.
  6. Ace Of Base - The Sign // Anii ăștia au fost anii Ace Of Base. Din fericire au trecut. Nu am fost un mare fan.
  7. Loft - Summer, Summer, Summer // A trebuit să-i dau play să-mi amintesc de ea. Nu am rezistat s-o ascult mai mult de 20 de secunde…
  8. Culture Beat - Got To Get It // Ani buni pentru Culture Beat, care explodaseră în popularitate cu “Mr. Vain”.

Side B

  1. Erasure - Always // Una dintre acele piese care îmi plăceau și îmi displăceau în același timp.
  2. Magic Affair - Give Me All Your Love // Dacă “The Omen” de mai sus mi-o aminteam, habar nu am ce-i cu asta.
  3. D:Ream - Another Night Another Dream // Nu știu cine a greșit aici, eu sau cei care au tipărit inserturile pentru casetele poloneze de pe care am copiat titlul pieselor, în orice caz e vorba de The Real McCoy nu D:Ream. Tot o piesa euro dance foarte cunoscută.
  4. Reel To Real - I Like To Move It // Scris de fapt Reel 2 Real. Asta o cam cunoaște toată lumea, dacă nu de altundeva atunci din desenul animat Madagascar.
  5. Positive Connection - Abracadabra // Îmi amintesc în mare linia melodică a refrenului…
  6. Take That - Pray // Din nou.
  7. Loft - Love Is Magic // A treia piesa Loft pe două casete. Se pare că-mi plăceau tare mult.
  8. Mo.Do. - Einz, Zwei, Polizei // Am greșit la ortografie, dar cui îi pasă? Oribilă.

Având în vedere de câte ori m-am întrebat mai sus de ce am înregistrat câte o piesă tind să cred că speram să mai dau unora caseta să aprecieze gusturile și abilitățile mele fine de selecție. Sau, judecând după frecvența de balade (numite pe atunci “bluzuri”), speram s-o duc la seratele care credeam că vor urma și la liceu. La mult timp după acest moment am aflat de conceptul de mixtape, care era varianta anglofonă a ceea ce am făcut eu.

Casetele binențeles că nu au supraviețuit, cel puțin nu cu conținutul acesta și dacă aveți impresia că sunt un fan euro dance greșiți, piesele mi se par acum cel mult puerile. Dar au fost potrivite pentru acea vreme și din prisma nostalgiei a fost, ăăă, plăcut să le reascult. Majoritatea.

Probabil că nu voi primi multe puncte de coolness și / sau hipsterism în urma acestei însemnări, eram mult mai câștigat dacă era ceva rock pe casete. În apărarea mea fie spus aveam pe atunci (și mai am) casete cu muzica electronică de o calitate mai bună: Vangelis, Jarre, Electric Light Orchestra, etc. De asemenea era mai fain dacă gaseam ceva capsula de acest gen din liceu când eram deja fan Dream Theater și alte formații de care să nu-mi fie rușine. De fapt făcusem și în liceu ceva asemănător, într-o zi în loc să-mi fac temele am copiat textele și creditele albumului Mandylion de la The Gathering. Poate voi reveni cu o poză că parcă am dat și peste acea hârtie când m-am uitat peste casete.

În încheiere vreau să spun că nu știu când am pus hârtiile alea acolo, probabil cu ocazia unei curațenii sau a unei aranjări a casetelor, dar acum le-am pus înapoi exact cum le-am găsit. Dacă au supraviețuit 24 de ani plus o spălătură nu văd de ce nu ar mai rezista… :)

Imagini aeriene de final de an

Lacul Albastru văzut din dronă

Baia Sprie văzută din dronă

În timp ce schimbam motorul blogului și mai reciteam însemnări aleatorii mă gândeam că s-au cam dus zilele când făceam premiera la ceva aici pe blog. În exemplul de față am pus aceste poze peste tot (Instagram, Facebook, Flickr) mai puțin aici. Dar mi-e cumva dor să fac asta și să pun și povestioarele aferente.

Așadar, pozele fiind puse, iată povestea:

Am fugit în pauza de masă a ultimei zile de lucru din an (29 decembrie 2017) la Baia Sprie, am ieșit în curtea casei părintești și am făcut kilometraj la dronă, adică am zburat până la Lacul Albastru, am făcut prima poză din această însemnare iar apoi am revenit cu ea aproximativ deasupra locului de decolare și am făcut a doua. Binențeles că am făcut mai multe poze din diferite unghiuri și am vrut să pun ceva exclusiv pe blog, dar cele de mai sus sunt cele mai reușite din set, și nici așa nu sunt pe deplin mulțumit de cea cu lacul, putea fi încadrată mult mai bine. Dar e destul de greu să încadrezi poze când drona de mărimea unui telefon mobil e la 700 de metri distanță și 250 de metri diferență de altitudine față de tine și un ochi îți stă obsesiv pe bara de baterie.

Ar mai fi de menționat cât de mult diferă workflow-ul cu poze față de cel de odinioară când făceam pozele, le descărcam de pe card când ajungeam acasă, eventual le mai editam puțin și apoi le publicam. Acuma le-am descărcat din dronă pe mobil prin WiFi, le-am editat în Lightroom-ul de pe Android, mi le-am trimis pe mail, creat versiunile redimensionate în Gimp pe Linux (am mai zis că o să-mi fie dor de media manager-ul din Wordpress) și le-am încărcat manual.

Și dacă tot suntem la povești, au trecut trei ani și puțin de la prima însemnare legată de dronă în care am promis că voi reveni cu mai multe detalii despre acest hobby și cu toate că am pus de atunci două articole în care mă lăudam cu filmări reușite, încă nu am apucat să public articolul cuprinzător plănuit. Sper să mă țină noul val de motivație și inspirație și să vadă lumina zilei în curând.

A new blogging engine

Code screenshot

My last entry about a blogging software switch was called ‘Keeping up with the times’ and I could have called this one the same. Back then, I finally realized that maintaining my Movable Type installation was a pain as I knew next to no Perl but since I was an established PHP developer the migration to Wordpress was a logical step. Now I’m ‘admitting’ that I slowly transitioned to being a Ruby developer so I’m embracing Jekyll.

So what were the other reasons for the switch?

  • I was getting a little paranoid about Wordpress and the plugins I was using. I wasn’t terribly excited about the perspective that if a security flaw appears and I’m not updating in time (if an update is available at all) my server gets f!@#ed.
  • It takes Jekyll about one minute to generate the whole site but the resulting files are vanilla HTMLs so they’re served much faster than their Wordpress equivalents. I haven’t even configured the web server for this site to include the PHP interpreter. As a note here, while discussing this post with Alex he mentioned that there are caching solutions and even a static site generator for Wordpress too.
  • I wanted to use the gem that I’m a maintainer / co-author of, in a “production” environment. I put quite a few hours of work into it and was very curious to actually see it doing its job.

What are the downsides?

  • Not being a dynamically generated database backed site the comments have to be served by a third party system. There might be self hosted alternatives out there, but I haven’t researched them because I had Disqus integrated with Wordpress for a long while anyway. I’m still not entirely comfortable to give all my comments away to a third party service (up until now, comments were also saved locally by Wordpress).
  • I had my concerns about search, and I thought I’ll have to insert a Google search box, but recently I discovered Algolia which is awesome and a lot faster than the Wordpress search was. See it action!
  • I have to admit, Wordpress’ media manager was great and I’m badly missing it.

Actually the migration began in 2014 when I discovered Jekyll and the majority of the post files were created back then by an import from Wordpress, but they were of sub-par quality with lots of junk in them. So in the last few days I hacked together some Ruby scripts which:

  • Removed useless YAML attributes and converted the ugly binary dates generated by the import.
  • Fixed the formatting of tons of posts. This was due since 2009 when I switched to Wordpress but I thought I’ll do it on a need by need basis as I stumble upon posts with broken formatting. Which I did, but it wasn’t nearly enough. It was the Algolia search that prompted me to do this whole clean-up as my unformatted older posts were generated as one long paragraph and the indexer wasn’t accepting them.
  • Fixed internal dead links. Lots of posts were still containing links to other posts using the old permalink style - /blog/archives/year/month/day/post_name. Now they all point to the correct format - /year/month/day/post-name/.
  • Updated links to assets which were moved to

Another point that’s worth mentioning is that the generated pages are ran through jekyll-tidy which turns them into deliciously formatted HTML. This tickles my web developer bone the right way. Go ahead, have a look at the source of a page and wonder at the perfect indentation.

Last but not least, the theme I’m using is a lightly customized Hyde, the about page got some long needed updates and to celebrate the launch the site is now secured with a Let’s Encrypt certificate and is served through HTTP/2.

Here’s to many years of static HTML! :)

My adventures in social coding

At the beginning of 2014 I accepted to work on a project for a friend and since it was a simple presentation site I decided to build it in Jekyll1. (Throughout this post I will add explanations for non technical people as footnotes.) By the time I got started on this project I was kind of spoiled by Rails’ asset pipeline2 functionality which was missing from Jekyll, but I quickly found a plugin which promised to deliver this. Taking a closer look at its GitHub repository I noticed that the original author has not touched it for half a year or so and some of the pull requests3 were pretty straight forward so I decided to fork4 the repository and integrate those changes. Thanks to the magic of git and the Internet, I can “retrace” the timeline of what happened to my fork:

  • January 8, 2014 - I start committing code, one of the main tasks being renaming the plugin from jekyll_asset_pipeline to japr (Jekyll Asset Pipeline Reborn).
  • January 14, 2014 - Thanks to my guerilla marketing campaign, which involved leaving comments with links to my repository on the original repository’s issues and pull requests, the first contributions by other people appear on my fork.
  • March 7, 2014 - More contributions by third parties.
  • May 27, 2014 - A contributor adds Rubocop which is a code quality checker that analyzes your code and reports “offenses” where it’s not written as it should be. He also rewrites the code in some places.
  • September 9, 2014 - Even more contributions.
  • … silence for a long time during which my fork goes abandoned and becomes incompatible with the latest version of Jekyll …
  • May 7, 2017 - A kind soul submits a pull request to fix the compatibility issues but due to lack of time I ignore it.
  • November 24, 2017 - While browsing around I notice a fork of my fork with changes that make it compatible with the current Jekyll version - I leave a comment on the author’s fork that if he wants he can submit a pull request…

Which he did and from this point forward things sprang into motion: I got motivated to fix the outstanding Rubocop offenses, one of them being to write documentation for the classes and modules of the library. While doing this I actually understood the flow of the code - what it does and how it does it, after 3 years of pretending that I’m a maintainer… But better later than never, right? Another ambition got its resolution when I managed to bump the automated test coverage to 100%, which means that each and every line of the library is covered by tests, the risk of inadvertently breaking something without noticing while adding a new feature or fixing something being minimal. After releasing this version, I remember that I had an uplifting feeling while I was walking around town, looking at people and thinking “heh, you might not know, but I just released an opensource library doing some good for the community”. This was a high point of the euphoria roller coaster that followed.

I then researched a little bit and noticed that there at least two more libraries focused on providing the same thing (an asset pipeline for Jekyll) one of them being minimalist and the other, well, the “everything but the kitchen sink” type. This was a low point, but I soon realized that the library I’m maintaining sits somewhere in between them having a medium amount of features.

A few short days later I’m laying in bed one night and after unsuccessfully waiting for sleep to come I decide to open up my phone and I notice an email. Written by the original author of the library I forked, in which he tells me that he noticed that I continued maintaining it and as he doesn’t have the time, he wants to pass on the baton of the original library to a maintainer. I almost screamed a little. The highest point of the roller coaster - and it kind of stayed here from that point forward.

I got into my pre-Christmas mini vacation and after two or three afternoons of work I integrated the changes of my fork back into the original repository. And now I’m happily smiling as an author on the gem’s page. Another bucket list item checked off.


  1. Jekyll is a tool that generates a site based on a template and some post files which contain the actual content of the pages. It sits somewhere between writing your site by hand in HTML and using a full-blown CMS like WordPress.
  2. The simple explanation for an asset pipeline is that it takes a bunch of CSS or JS files, pre-processes them, merges them together, minifies the result, etc. The obvious benefit is that instead of multiple requests there will be one request for CSS and one for JavaScript, easing the load on the server and making the page load faster.
  3. A pull request is a way to propose your changes to a repository of code. Before making their way into the code base these changes have to be accepted by the owner of said repository.
  4. A fork is a copy of a repository of code.