From 692d24d6fbbe61ba71a7f6585416015a1df15ef3 Mon Sep 17 00:00:00 2001 From: Ernesto Tagwerker Date: Mon, 10 Feb 2020 16:18:49 -0500 Subject: [PATCH 1/3] Initial commit with article about skunk and github actions --- ...tech-debt-using-skunk-on-github-actions.md | 221 ++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 _posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md diff --git a/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md b/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md new file mode 100644 index 00000000..14f187aa --- /dev/null +++ b/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md @@ -0,0 +1,221 @@ +--- +layout: post +title: "How to Calculate Tech Debt Using Skunk on GitHub Actions" +date: 2020-02-10 16:16:00 +categories: ["tech-debt"] +author: etagwerker +--- + +In preparation for my talk at [RubyConf Australia](https://www.rubyconf.org.au/) this +month, I've been working on a way to make it easy for anyone to run `skunk` on their +Ruby projects. In order to do that I decided to use GitHub Actions. It's a powerful +service by GitHub and it's quite easy to set up. + +This is an article 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](https://github.blog/2018-10-17-action-demos/) +and I had been meaning to play around with them to incorporate some automation to +our workflows at [FastRuby.io](https://fastruby.io). The good news is that [GoRails](https://gorails.com) +already published an article about setting up CI in your Rails app: +[Continuous Integration with GitHub Actions](https://gorails.com/episodes/github-actions-continuous-integration-ruby-on-rails) + +After following those steps, I ended up with a copy/pasted YAML file that looked like this: + +```yaml +# .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: ${{ secrets.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`](https://github.com/fastruby/skunk) 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 tutorial, I thought it was best to simplify it to look like this: + +```yaml +# .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](https://github.com) to run the [`skunk`](https://github.com/fastruby/skunk) +action every time there is any push to GitHub. To see an entire list +of events that you can configure: [Webhook Events](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#webhook-events) + +There are only two steps: + +1. Setup my Ruby environment. I'm going to need this because `skunk` is a Ruby gem. +1. 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 `skunk app/` + +The next thing I wanted to do is run `skunk` on a pull request in order to +compare the _Stink Score_ between the pull request and `master`. This will help +us answer this question: + +> Are we increasing or decreasing the tech debt average in our project? + +In order to do this, I had to tweak the call to `skunk` to use the `--branch` +option: + +```yaml +# .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` _magic_ in there. The GitHub Action will do one thing if +you are within the context of a pull request (compare action), and another thing +if it is running a commit pushed to the `master` branch. + +One last thing I had to add was a step to generate [SimpleCov](https://github.com/colszowka/simplecov)'s +resultset JSON file. Skunk is most useful when it considers code coverage data. +[The StinkScore is a combination of code smells; complexity; and code coverage data](https://github.com/fastruby/skunk#what-is-the-stinkscore). + +I tweaked the steps configuration to look like this: + +```yaml +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 stink score: 13.42 +Feature branch ((HEAD detached at 0315f34)) average stink 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](https://github.com/fastruby/skunk/pull/26). +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](https://github.com/fastruby/skunk/runs/437118684) + +## 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 + +- You can see all the trial and error that went into writing this article: +[https://github.com/fastruby/skunk/actions?query=workflow%3ASkunk](https://github.com/fastruby/skunk/actions?query=workflow%3ASkunk) +- A new update to GitHub Actions adds even more features to it: +[https://github.blog/2020-02-06-manage-secrets-and-more-with-the-github-actions-api/](https://github.blog/2020-02-06-manage-secrets-and-more-with-the-github-actions-api/) From ef635ac68a734e57cd14a56b29c35568f745be9e Mon Sep 17 00:00:00 2001 From: Ernesto Tagwerker Date: Wed, 12 Feb 2020 09:52:59 -0500 Subject: [PATCH 2/3] Addressed comments by @lubc --- ...te-tech-debt-using-skunk-on-github-actions.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md b/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md index 14f187aa..2db96f6c 100644 --- a/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md +++ b/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md @@ -2,13 +2,13 @@ layout: post title: "How to Calculate Tech Debt Using Skunk on GitHub Actions" date: 2020-02-10 16:16:00 -categories: ["tech-debt"] +categories: ["code-quality"] author: etagwerker --- In preparation for my talk at [RubyConf Australia](https://www.rubyconf.org.au/) this -month, I've been working on a way to make it easy for anyone to run `skunk` on their -Ruby projects. In order to do that I decided to use GitHub Actions. It's a powerful +month, I've been working on a way to make it easy for anyone to run [`skunk`](https://www.fastruby.io/blog/code-quality/intruducing-skunk-stink-score-calculator.html) on +their Ruby projects. In order to do that I decided to use GitHub Actions. It's a powerful service by GitHub and it's quite easy to set up. This is an article about the process that I followed and how you can use it in your own @@ -110,8 +110,8 @@ steps synchronously, from top to bottom. If you want to run `skunk` for a Rails application, you can change the last step to `skunk app/` The next thing I wanted to do is run `skunk` on a pull request in order to -compare the _Stink Score_ between the pull request and `master`. This will help -us answer this question: +compare the [_Stink Score_](https://github.com/fastruby/skunk#what-is-the-stinkscore) +between the pull request and `master`. This will help us answer this question: > Are we increasing or decreasing the tech debt average in our project? @@ -147,9 +147,9 @@ jobs: fi ``` -There is some `bash` _magic_ in there. The GitHub Action will do one thing if -you are within the context of a pull request (compare action), and another thing -if it is running a commit pushed to the `master` branch. +There is some `bash` logic in there: The GitHub Action will [compare your branch vs. master](https://github.com/fastruby/skunk#comparing-one-branch-vs-another) if +it is running within the context of a pull request, or [generate a tech debt report](https://github.com/fastruby/skunk#getting-a-sorted-list-of-stinkiest-files) if +it is running a commit pushed to the `master` branch. One last thing I had to add was a step to generate [SimpleCov](https://github.com/colszowka/simplecov)'s resultset JSON file. Skunk is most useful when it considers code coverage data. From aa0f2c4d614e594fe0ff72af5208441bc3d013ca Mon Sep 17 00:00:00 2001 From: Ernesto Tagwerker Date: Wed, 12 Feb 2020 09:53:48 -0500 Subject: [PATCH 3/3] Updated date --- ...-02-12-calculate-tech-debt-using-skunk-on-github-actions.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename _posts/{2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md => 2020-02-12-calculate-tech-debt-using-skunk-on-github-actions.md} (99%) diff --git a/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md b/_posts/2020-02-12-calculate-tech-debt-using-skunk-on-github-actions.md similarity index 99% rename from _posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md rename to _posts/2020-02-12-calculate-tech-debt-using-skunk-on-github-actions.md index 2db96f6c..3eefd147 100644 --- a/_posts/2020-02-10-calculate-tech-debt-using-skunk-on-github-actions.md +++ b/_posts/2020-02-12-calculate-tech-debt-using-skunk-on-github-actions.md @@ -1,7 +1,7 @@ --- layout: post title: "How to Calculate Tech Debt Using Skunk on GitHub Actions" -date: 2020-02-10 16:16:00 +date: 2020-02-12 9:16:00 categories: ["code-quality"] author: etagwerker ---