Mauro Morales

software developer

Year: 2015

  • Yes, Ship It!

    Last week I had the chance to participate in my first Hackweek. I never had such an experience in any other company I’ve ever worked for and between my colleagues’ reports about previous experiences and my own expectations I was very excited to see what was all the fuzz about.

    These type of events are not unique to SUSE, as a matter of fact Twitter and a bunch of other companies were also having their Hackweeks at the same time and I’m glad this is the case because after having the chance to participate in one I realize it’s a great way to promote creativity.

    A hackweek is basically a week were you get to work on anything you want to work on. You are not expected to deliver anything but instead encouraged to experiment and explore with anything you think is worth spending time on.

    In order to make the most out of Hackweek I decided to join a project and not start one of my own so I could do some pairing. This kind of interactions always make it a lot of fun for me plus I get to learn a ton. That’s how I joined Cornelius Schumacher to work on Yes Ship It! This is a project he had already started on his own so we were not doing everything from scratch.

    The approach of yes_ship_it is different from the typical release script. It doesn’t define a series of steps which are executed to make a release. It defines a sequence of assertions about the release, which then are checked and enforced.

    The first thing we decided to do together was a Rails App which allows you to track successful software releases. Since it was going to be 100% related to Yes Ship It! we decided to call it Yes It Shipped!. Let me show you how trivial it is to add it to a project like the formstack-api gem.

    1. Install the yes_ship_it gem
    $ gem install yes_ship_it
    
    1. Add a yes_ship_it.conf file
    $ yes_ship_it init
    
    1. Release!
    $ yes_ship_it
    

    By default yes_ship_it will check if:

    • you are in the right release branch (by default master) and the code was pushed.
    • the working directory is not missing to commit anything.
    • the version was update
    • the changelog was updated
    • a tag was added and published
    • a new version of the gem was built and published

    The aim is to make it as generic as possible so you can adapt it to anyproject you have. For starters you can remmove any check in the process and soon enough you will be able to add checks of your own.

    What I like the most about it is that I can run yes_ship_it at any time. I don’t need to remember or make sure what was the last step I did because that’s exactly what it will do for me.

    What do you think? Leave your comments below and remember to release early and release often!

  • Running openSUSE 13.2 on Linode

    Linode is one of my favorite VPS providers out there. One of the reasons why I like them is because they make it extremely easy to run openSUSE. This post is a quick tutorial on how to get you started.

    The first time you log in you will be presented with the different Linode plans. And the Location where your server will reside.

    I’ll choose the smallest plan

    Once you see your Linode listed, click on it’s name

    Now click on “Deploy an image”

    In there we will select openSUSE 13.2, the amount of space in disk. You can leave the defaults which will choose for the full disk size with a 256MB swap partition. Choose your password and click Deploy.

    This will take a bit but as soon as it’s done you will be able to Boot your machine.

    Finally click on the “Remote Access” tab so you can see different options to log into your machine.

    I personally like to ssh in from my favorite terminal app

    ssh root@10.0.0.10

    You will be welcomed by openSUSE with the following message:

    Have a lot of fun...
    linux:~ #

    Now you can play with your new openSUSE 13.2 box. Enjoy!

  • Getting Started With Continuous Delivery

    More and more companies are requiring developers to understand Continuous Integration and Continuous Delivery but starting to implement it in your projects can be a bit overwhelming. Start with a simple website and soon enough you will feel more confident to do with more complex projects.

    THE RIGHT MINDSET

    TDD/BDD, CI/CD, XP, Agile, Scrum …. Ahhhhh, leave me alone I just want to code!

    Yes, all this methodologies can be a bit complicated at first, but simply because you are not used to them. Like a muscle you need to train them and the more you do so, the sooner you won’t feel like doing them is a total waste of time.

    Once you have made up your mind that CD is for you, your team or your project then you will need to define a process and follow it. Don’t make it easy to break the process and before you know it you and your team will feel like fish in the water.

    AUTOMATE A SIMPLE WEBSITE DEPLOYMENT

    There are many ways you can solve this problem. I will use a certain stack. If you don’t have experience with any of the tools, try to implement it with one you do have experience with.

    StackTool/ServiceAlternatives
    VPSDigitalOceanLinode or Vagrant
    Configuration ManagementAnsibleChef or Puppet
    Static site generatorMiddlemanJekyll or pure HTML
    CI/CD ServerSemaphoreCodeship or Jenkins

    The first thing is to create a new droplet in DO (you could also do this with Ansible but we won’t at this tutorial). Make sure there is a deployuser and to set up ssh keys for it (again something we could do with Ansible but we’ll leave that for another post) Setup your your domain to point to the new server’s IP address, I will use ‘example.com’.

    ANSIBLE

    Create a folder for your playbook and inside of it start with a file calledansible.cfg. There we will override the default configuration by pointing to a new inventory inside your playbook’s folder and specify the deploy user.

    [defaults]
    hostfile=inventory
    remote_user=deploy
    

    Now in our inventory file we specify a group called web and include our domain.

    [web]
    example.com
    

    Our tasks will be defined in simple-webserver.yml

    ---
    - name: Simple Web Server
      hosts: example.com
      sudo: True
      tasks:
        - name: Install nginx
          apt: pkg=nginx state=installed update_cache=true
          notify: start nginx
        - name: remove default nginx site
          file: path=/etc/nginx/sites-enabled/default state=absent
        - name: Assures project root dir exists
          file: >
            path=/srv/www/example.com
            state=directory
            owner=deploy
            group=www-data
        - name: copy nginx config file
          template: >
            src=templates/nginx.conf.j2
            dest=/etc/nginx/sites-available/example.com
          notify: restart nginx
        - name: enable configuration
          file: >
            dest=/etc/nginx/sites-enabled/example.com
            src=/etc/nginx/sites-available/example.com
            state=link
          notify: restart nginx
      handlers:
        - name: start nginx
          service: name=nginx state=started
        - name: restart nginx
          service: name=nginx state=restarted
    

    In it we make reference to a template called templates/nginx.conf.j2 where we will specify a simple virtual host.

    server {
            listen *:80;
    
            root /srv/www/example.com;
            index index.html index.htm;
    
            server_name example.com;
    
            location / {
                    try_files $uri $uri/ =404;
            }
    }
    

    I’ll show you in another post how to do this same setup but with multiple virtual hosts in case you run multiple sites.

    Run it by calling:

    ansible-playbook simple-webserver.yml
    

    MIDDLEMAN

    Middleman has a very simple way to deploy over rsync. Just make sure you have the following gem in your Gemfile

    gem 'middleman-deploy'
    

    And then add something like this to your config.rb

    activate :deploy do |deploy|
      deploy.method = :rsync
      deploy.host   = 'example.com'
      deploy.path   = '/srv/www/example.com'
      deploy.user  = 'deploy'
    end
    

    Before you can deploy you need to remember to build your site. This is prone to errors so instead we will add a rake task in our Rakefile to do this for us.

    desc 'Build site'
    task :build do
      `middleman build`
    end
    
    desc 'Deploy site'
    task :deploy do
      `middleman deploy`
    end
    
    desc 'Build and deploy site'
    task :build_deploy => [:build, :deploy] do
    end
    

    GIT FLOW

    Technically you don’t really need git flow for this process but I do believe having a proper branching model is key to a successful CD environment. Depending on your team’s process you might want to use something else but if you don’t have anything defined please take a look at git flow, it might be just what you need.

    For this tutorial I will oversimplify the process and just use the develop, master and release branches by following these three steps:

    1. Commit all the desired changes into the develop branch
    2. Create a release and add the release’s information
    3. Merge the release into master

    Let’s go through the steps in the command line. We start by adding the new features and committing them.

    git add Rakefile
    git commit -m 'Add rake task for easier deployment'
    

    Now we create a release.

    git flow release start '1.0.0'
    

    This would be a good time to test everything out. Bump the version number of your software (in my case 1.0.0), update the change log and do any last minute fixes.

    Commit the changes and let’s wrap up this step by finishing our release.

    git flow release finish '1.0.0'
    

    Try to write something significant for your message tag so you can easily refer to a version later on by it’s description.

    git tag -n
    

    Hold your horses and don’t push your changes just yet.

    SEMAPHORE

    Add a new project from Github or Bitbucket.

    For the build you might want to have something along the lines of:

    bundle install --path vendor/bundle
    bundle exec rake spec
    

    Now go into the projects settings inside the Deployment tab and add a server.

    Because we are using a generic option Sempahore will need access to our server. Generate an SSH key and paste the private in Semaphore and the public in your server.

    For the deploy commands you need to have something like this:

    ssh-keyscan -H -p 22 example.com >> ~/.ssh/known_hosts
    bundle exec rake build_deploy
    

    PUSH YOUR CHANGES

    Push your changes in the master branch and voilà, Semaphore will build and deploy your site.

    Once you get into the habit of doing this with your website you will feel more confident of doing it with something like a Rails application.

    If you have any questions please leave them below, I’ll respond to every single one of them.