How to Calculate Tech Debt Using Skunk on GitHub Actions

How to Calculate Tech Debt Using Skunk on GitHub Actions

Right before my talk at RubyConf Australia opens a new window , I worked on a way to make it easy for anyone to run skunk opens a new window in their Ruby projects. In order to do that I decided to use GitHub Actions opens a new window . It’s a powerful service by GitHub and it’s quite easy to set up.

This article is about the process that I followed and how you can use it in your own application.

GitHub Actions have been around for more than a year opens a new window and I had been meaning to play around with them to incorporate some automation to our workflows at FastRuby.io opens a new window . The good news is that GoRails opens a new window already published an article about setting up continuous integration in your Rails app: Continuous Integration with GitHub Actions opens a new window

After following those steps, I ended up with a copy/pasted YAML file that looked like this:

# .github/workflows/ci.yml

name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      db:
        image: postgres:11
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      redis:
        image: redis
        ports: ['6379:6379']
        options: --entrypoint redis-server

    steps:
      - uses: actions/checkout@v1
      - name: Setup Ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6.x
      - uses: borales/actions-yarn@v2.0.0
        with:
          cmd: install
      - name: Build and run tests
        env:
          DATABASE_URL: postgres://postgres:@localhost:5432/test
          REDIS_URL: redis://localhost:6379/0
          RAILS_ENV: test
          RAILS_MASTER_KEY: $
        run: |
          sudo apt-get -yqq install libpq-dev
          gem install bundler
          bundle install --jobs 4 --retry 3
          bundle exec rails db:prepare
          bundle exec rails test

Considering that skunk opens a new window is a Ruby gem (it doesn’t need Rails, Redis, nor Postgres) and I didn’t need all the steps I copied from the GoRails opens a new window tutorial, I thought it was best to simplify it to look like this:

# .github/workflows/skunk.yml

name: Skunk
on: [push]

jobs:
  skunk:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v1
      - name: Setup Ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6.x
      - name: Run Skunk on Project
        run: |
          gem install skunk
          skunk lib/

This tells GitHub opens a new window to run the skunk opens a new window action every time there is a new push to the GitHub remote. To see an entire list of events that you can configure: Webhook Events opens a new window

There are only two steps:

  1. Setup my Ruby environment. I’m going to need this because skunk is a Ruby gem.
  2. Install the skunk gem and run it on the lib/ directory.

I really like that the configuration file is easy to read and understand. The order of the steps defined in the steps section is important. It will run steps synchronously, from top to bottom. If you want to run skunk for a Rails application, you can change the last step to do this: skunk app/

The next thing I wanted to do is run skunk on a pull request in order to compare the SkunkScore opens a new window between the pull request and master. This will help us answer this question:

Are we increasing or decreasing the technical debt average in our project?

In order to do this, I had to tweak the call to skunk to use the --branch option:

# .github/workflows/skunk.yml

name: Skunk
on: [push]

jobs:
  skunk:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v1
      - name: Setup Ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6.x
      - name: Run Skunk on Project
        run: |
          gem install skunk
          CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
          if [[ "$CURRENT_BRANCH" != "master" ]]; then
            echo "Executing within branch: $CURRENT_BRANCH"
            skunk lib/ -b master
          else
            echo "Executing within master branch"
            skunk lib/
          fi

There is some bash logic in there: The GitHub Action will compare your branch vs. master opens a new window if it is running within the context of a pull request, or generate a tech debt report opens a new window if it is running a commit pushed to the master branch.

One last thing I had to add was a step to generate SimpleCov opens a new window ’s resultset JSON file. Skunk is most useful when it considers code coverage data. The SkunkScore is a combination of code smells; complexity; and code coverage data opens a new window .

I tweaked the steps configuration to look like this:

steps:
  - uses: actions/checkout@v1
  - name: Setup Ruby
    uses: actions/setup-ruby@v1
    with:
      ruby-version: 2.6.x
  - name: Run test suite with COVERAGE=true
    run: |
      gem install bundler
      bundle install --jobs 4 --retry 3
      COVERAGE=true bundle exec rake test
  - name: Run Skunk on Project
    run: |
      gem install skunk
      CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
      if [[ "$CURRENT_BRANCH" != "master" ]]; then
        echo "Executing within branch: $CURRENT_BRANCH"
        skunk lib/ -b master
      else
        echo "Executing within master branch"
        skunk lib/
      fi

Now you can see the difference in tech debt between master and your pull request:

Base branch (master) average skunk score: 13.42
Feature branch ((HEAD detached at 0315f34)) average skunk score: 13.42
Score: 13.42

This particular example shows that there is no difference in my application’s technical debt: https://github.com/fastruby/skunk/pull/26 opens a new window . That’s because I didn’t change any Ruby code (just a YAML file).

You can see the GitHub Action run over here: https://github.com/fastruby/skunk/runs/437118684 opens a new window

Final Thoughts

GitHub Actions can be very useful when you want to run something really quickly without setting up your own development environment. It can take a lot of trial and error to get the final configuration right.

If you wanted to give skunk a try, now there are no more excuses. You don’t need to install anything in your environment. You can add this GitHub workflow and that’s it:

I hope you can use this free and open source tool to find out your tech debt hot spots!

References

Get the book