Writing a GitHub Actions Workflow for Chef Cookbook
Tags: github, actions, devops, chefcookbook
Published: 2020-12-22 19:54:12

# Table of Content
  - [Introduction](#introduction)
  - [Objective](#objective)
  - [Berkshelf](#berkshelf)
  - [Steps to Create GitHub Actions](#steps-to-create-github-actions)
  - [Github Action Workflow Explained](#github-action-workflow-explained)
  - [Bibliography](#bibliography)

## Introduction
I’m assuming the target audience for this article expected to have basic understanding of GitHub as source control tool. 
Also this article meant for Chef cookbook DevOps developers, looking to get an idea about implementing Continuous Integration flow for Chef cookbooks using GitHub actions.

## Objective
1. The [cookbooks](https://github.com/chefgs/cookbooks) code repo has Chef wrapper cookbooks for apache and windows
2. Chef deployment can be done in two ways, using 1. Berkshelf, 2. Policyfile
3. Berkshelf is bit older deployment style, where as, Policyfile deployment is newer way of doing Chef deployment
4. I’ve picked up Berkshelf way for this repo

## Berkshelf
1. Used Berksfile for creating the repo content, cookbooks repo contains the cookbooks and all it’s inter dependent cookbooks, which is ready to be packaged to store in artifact or can be uploaded to Chef server.
2. Read this article in Chef documentation to know more about, [how Berkshelf works?](https://docs.chef.io/berkshelf.html)

## Steps to Create GitHub Actions
1. Under the Github code repository, I've chosen `Actions` tab
2. Chose `New WorkFlow`
3. Then chose `Setup a workflow yourself`
4. YAML code below will be the GitHub Action CI Workflow for the cookbooks repository
```
name: Build-Package Chef Cookbooks

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Set up Ruby 2.6
      uses: actions/setup-ruby@v1
      with:
        ruby-version: 2.6.x
    - name: Setup Gem Files
      run: |
        bundle install --jobs 4 --retry 3 # Install berks gem
    - name: Run Code Analysis using cookstyle
      run: |
        echo `pwd`
        echo "\n"
        chmod +x sca.sh
        ./sca.sh
    - name: Build and Bundle Cookbooks and dependencies
      run: |
        echo `pwd`
        echo "\n"
        chmod +x berks-vendor.sh
        echo `ls -l`
        ./berks-vendor.sh # Berks vendor cookbooks
    - name: Package cookbooks to upload to artifact repo or Upload cookbook Chef server using berks upload
      run: |
        echo "package cookbooks dumped in the `cookbook_cache` directory and store it to artifact repo, or upload cookbooks to Chef server using ‘berks upload’ command"
```
 
## Github Action Workflow Explained
- The Workflow I have created for this repo is a Custom Workflow, fits better for this cookbook repository
- Workflow kicks off on every code push to the repo, runs the rest of the steps on the CI server (ubuntu in most cases)
- Checking out the repo
- Installs Ruby
- Uses Gemfile and installs required Gem packages and it’s dependent gems
- Invoke static code analysis on the cookbooks using cookstyle gem, sca.sh script performing code analysis step. Script uses `cookstyle` ruby gem to perform the Cookbook syntax check and code analysis
```
# sca.sh script
ls -ltr | grep drw | grep -v cookbook | awk '{print $9}' | while read dir_name 
do
# berks vendor ../cookbook_cache
echo $dir_name
cookstyle $dir_name
done
```
- Build and store cookbooks using ‘berks vendor’ command into a directory, berks-vendor.sh script used for this step.

```
# berks-vendor.sh script
ls -ltr | grep drw | grep -v cookbook | awk '{print $9}' | while read dir_name 
do
echo $dir_name
cd $dir_name
berks vendor ../cookbook_cache
cd ..
done
```
- Last CI step in the workflow is to, package cookbooks dumped in the `cookbook_cache` directory and store it to artifact repo, or upload cookbooks to Chef server using ‘berks upload’ command.
- All the GitHub action workflows stored inside the same repository location under `.github/workflows`. In case of any changes we can access the YAML file and edit it.

## Bibliography
[Github Action Documentation](https://docs.github.com/en/free-pro-team@latest/actions)
[Chef Berkshelf](https://docs.chef.io/berkshelf.html)