Skip to content
master
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
bin
 
 
lib
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Reina - 響け!

Gem Version CircleCI

GitHub bot and CLI application to handle deployments and orchestrations of feature stagings on Heroku.

We won't use Heroku's App Setup as it seems to require the direct URL to the tarball of a repository which is hard to provide when it is private. So we do pretty much everything manually in the code base.

Docker Setup

This project is making use of docker compose. To build the projects and run tests, simply do:

docker-compose build
docker-compose run --rm reina rspec

Use case

TL;DR

Deploy different branches of different projects, that rely on each other, to Heroku and get them connected through environment variables.

Background and history

As you can see from the template of the configuration, at Honeypot we have four main applications that make the whole architecture work as intended.

This is nice and fine in production and in the main staging, but it's not that simple with the feature stagings provided by Heroku (basically everytime you open a pull request against a repository a fresh and temporary staging environment gets automatically created).

In the past, the admin and the frontend apps were located in the main back-end repository, while a single searchspot instance was shared among the other feature stagings, with all the obvious indexing problem that you can imagine from such a setup.

As we moved the frontend app to another repository, we basically had the need to manually modify the environment variables to connect it to the back-end everytime we had to do QA for a change that must be present on both the sides.

Sure thing, Kubernetes and similar applications are possibily a good solutions for similar cases but we preferred to continue using a testing architecture similar to the one we were used to since it always well suited our methodologies without adding additional layers we hadn't experience at or moving to other testing solutions.

So we ended up with reina, which basically allows us to replace Heroku's feature stagings by adding a good amount of customizations and nice things. We are sure other solutions do exist, but reina seems working good for us from quite some time. It's not hard to set it up as a bot and hopefully can help anyone else that get into a situation similar to ours. Feel free to open an issue for anything or submit a pull request if you need something from her to do!

Usage

There are two ways to use reina: as a github bot or as a CLI-app.

When used as a bot, just leave a comment in an issue like reina: d projectzero#nice-feature-branch. Reina will handle all the cleaning once you eventually close it. By executing once again the command, the stagings will be replaced with a fresh new deploy. If a branch is not specified, it will automatically deploy the latest master branch for each supported project.

You can also replace the d with r (as in reina: r projectzero#nice-feature-branch) when you want to enable the strict mode which re-deploys only the apps that you have explicitly specified in the command which is useful when you want to deploy only the latest version of an application that you have already deployed rather than the whole suite (to save time).

As a CLI application, execute $ reina 1234 "projectzero#nice-feature-branch".

$ reina -h will show the usage infos in order to enable things like the above mentioned strict mode.

In the example command mentioned before, 1234 would basically be the issue number, while for all the app#branch tuples that are not specified in the command but present in your mapping (config.rb), will be deployed from the master branch (which is the same of what happens with the bot usage btw).

Setup

Install the gem which will provide you both the executable and the library: $ gem install reinarb.

Then, copy somewhere in your machine the config.rb.sample file that you can find here in this repository and rename it as config.rb.

Configure the APPS hash map of the config.rb file based on your setup. We can't provide proper documentation for now but with the template we have left and the source code I hope it will be fine enough for you.

For what concerns the CONFIG hash map, this is how you can get the requested tokens:

  • $HEROKU_PLATFORM_API
$ heroku login
$ heroku keys:add ~/.ssh/id_rsa.pub
$ heroku plugins:install heroku-cli-oauth
$ heroku authorizations:create -d "Platform API token for Reina"
  • $GITHUB_WEBHOOK_SECRET

This is only needed if you want to run reina as a bot.

From your repository's settings, go to "Hooks" and click the "Add webhook" button. You will need to set as URL https://<your_reina_instance_app_name>.herokuapp.com/github and grant issues and issue_comment as permissions. Set a random and secure secret and share it between the form end the environment variable we're here talking about.

  • $APP_NAME_PREFIX

Everything is gonna be fine as app namespace, unless the eventual generated app name has already been used by someone on Heroku.

As a bot

First of all, follow the instructions above, then host the bot as a rack application on Heroku.

Then you need to provide the following environment variables from Heroku:

  • GITHUB_AUTH which is your login data to GitHub in the form of username:password
  • GITHUB_NAME which is your GitHub user's login name (protip: create a user meant to be the actual bot - this is ours)
  • GITHUB_EMAIL which is your GitHub user's email
  • HEROKU_API_KEY which is the output of $ heroku auth:token

Finally you will need to make a JSON out of the two hash maps in config.rb and copy them respectively to the environment variables called APPS and CONFIG (typing require 'json'; puts APPS; puts CONFIG should be enough to get what you need).

If you also want Reina to add replies to your request, create an API key for your account (preferabily the one dedicated to the bot you have created before) with write:discussion and repos permissions. Instructions here. Once the key has been generated, set it as GITHUB_OAUTH_TOKEN (or add it to the config.rb file).

This is what eventually your environment variables should look like on Heroku: https://i.imgur.com/zx4cHWB.png

Reina config setup

app.json

Each application used in reina is required to have app.json in root directory of the project. app.json in each project is used to define addons, dynos, buildpacks and required env vars.

Example app.json

{
  "name": "myapp",
  "scripts": {
    "postdeploy": "bash script/reina_postdeploy_commands"
  },
  "env": {
    "TZ": {
      "value": "Europe/Berlin"
    },
    "APP_NAME": {
      "required": true
    },
    "HEROKU_APP_NAME": {
      "required": true
    },
    "LANG": {
      "required": true
    }
  },
  "formation": {
    "web": {
      "quantity": 1
    },
    "worker": {
      "quantity": 1
    }
  },
  "addons": [
    {
      "plan": "heroku-postgresql",
      "options": {
        "version": "13"
      }
    },
    "heroku-redis",
    {
      "plan": "bonsai:staging",
      "options": {
        "version": "6.5.4"
      }
    }
  ],
  "buildpacks": [
    {
      "url": "https://github.com/heroku/heroku-buildpack-nodejs.git"
    },
    {
      "url": "https://github.com/heroku/heroku-buildpack-ruby.git"
    }
  ]
}

Reina config

Reina is configured using config.rb or APPS and CONFIG env vars. app.json is not used to set any environment variables.

Project Environment variables

Environment variables are setup in reina config env var. To Setup env vars in your reina app you need to provide staging environment to copy env vars from. Example: https://github.com/honeypotio/reina/blob/master/config.rb.sample#L18.

Ignoring environment variables

The configuration supports ignoring certain env vars https://github.com/honeypotio/reina/blob/master/config.rb.sample#L19.

Copying env variables

You can also copy certain vars from other envs https://github.com/honeypotio/reina/blob/master/config.rb.sample#L24.

The config supports copying app urls:

"config_vars": {
  "from": "staging",
  "copy": [
    {
      "from": "api#url",
      "to": "API_URL"
    },
  ]
}

and other env variables from other apps:

"config_vars": {
  "from": "staging",
  "copy": [
    {
      "from": "api#DATABASE_URL",
      "to": "DATABASE_URL"
    },
  ]
}

License

Copyright © 2021 Honeypot GmbH.

About

GitHub bot and CLI to handle deployments and orchestrations of feature stagings on Heroku.

Resources

License