GitHub Shareable Action

GitHub Shareable Action

Background

I need to set up 3 GitHub workflows for 10 repo. For each workflow, it will run a similar bash script.

First trial - Create Separate Bash Script and Workflow

On my first trial, I did the following:

  1. work on a single repo
  2. create three separate bash scripts
  3. create three separate workflows

Here are the three bash scripts:

run-dependabot-alert.sh

#!/bin/sh

TOKEN=$1
REPO=$2

get_response(){
  curl -sL \
    -H "Accept: application/vnd.github+json" \
    -H "Authorization: Bearer $TOKEN"\
    -H "X-GitHub-Api-Version: 2022-11-28" \
    https://api.github.com/repos/januschung/"$REPO"/dependabot/alerts
}

do_something(){
    echo "Running Dependabot!"
}

get_response
do_something        

run-secret-scanning.sh

#!/bin/sh

TOKEN=$1
REPO=$2

get_response(){
? curl -sL \
? ? -H "Accept: application/vnd.github+json" \
? ? -H "Authorization: Bearer $TOKEN"\
? ? -H "X-GitHub-Api-Version: 2022-11-28" \
? ? https://api.github.com/repos/januschung/"$REPO"/secret-scanning/alerts
}

do_something(){
? ? echo "Running Secret Scanning!"
}

get_response
do_something        

run-codeql-alert.sh

#!/bin/sh

TOKEN=$1
REPO=$2

get_response(){
? curl -sL \
? ? -H "Accept: application/vnd.github+json" \
? ? -H "Authorization: Bearer $TOKEN"\
? ? -H "X-GitHub-Api-Version: 2022-11-28" \
? ? https://api.github.com/repos/januschung/"$REPO"/code-scanning/alerts
}

do_something(){
? ? echo "Running CodeQL Scanning!"
}

get_response
do_something        

Here is one of the three workflows, as they are more like the same:

dependabot-workflow.yml

name: 'Dependabot Alert Check'
on:
? push:
? ? branches:
? ? ? - 'main'

jobs:
? dependabot-scanning-alert-check:
? ? runs-on: ubuntu-latest
? ? steps:
? ? ? - uses: actions/checkout@v3
? ? ? ? with:
? ? ? ? ? token: ${{ secrets.GH_TOKEN }}
? ? ? - name: Run Dependabot Alert Check
? ? ? ? shell: bash
? ? ? ? run: |
? ? ? ? ? ./scripts/run-dependabot-alert.sh ${{ secret.GH_TOKEN }} ${{ github.event.repository.name }}        

As you can see, there are a lot of similar logic from both of the bash scripts and the workflows. It will be tedious to repeat the work across the other repos.

Can I do better? Sure!

Second Trial - Create Shareable Composite Action

Since all of the 10 repo will share the same logic, I converted the workflow into a shareable composite action in a dedicated repo. In so doing, the other repo can reference the same action. Here are the benefits:

  • a single source of truth
  • easier to maintain one set of bash scripts and action
  • easier to get the rest of the repo onboard

Here is the shareable composite action:

name: 'Alert Check'
description: 'Run alert check'
inputs:
  alert-type:
    description: 'Alert type to run - code-scanning, dependabot or secret-scanning'
    required: true
    default: 'dependabot'
? gh-token:
? ? required: true

runs:
? using: "composite"
? steps:
? ? - uses: actions/checkout@v3
? ? ? with:
? ? ? ? token: ${{ inputs.gh-token }}
? ? - shell: bash
? ? ? run: echo "${{ github.action_path }}" >> $GITHUB_PATH
? ? - shell: bash
? ? ? run: |
? ? ? ? ${{ alert-type }}.sh ${{ inputs.gh-token }} ${{ github.event.repository.name }}        

Note that the bash scripts are now migrated from scripts folder into .github/actions/alerts.

The corresponding workflow that reference the shareable composite action:

on: [push]

jobs:
? run_alert:
? ? runs-on: ubuntu-latest
? ? name: Run Dependabot Alert
? ? steps:
? ? ? - uses: actions/checkout@v3
? ? ? - uses: januschung/shared-action-repo/.github/actions/alerts@main
? ? ? ? with:
? ? ? ? ? gh-token: ${{ secrets.GH_TOKEN }}
          alert-type: ${{ matrix.type }}        

Looking way much better now. But, can I do even better?

Third Trial - Consolidate Into a Single Bash Script and a Single Action

Since all three bash scripts share 80% of the same logic, I consolidated them into a single one:

alert.sh

#!/bin/sh

TOKEN=$1
REPO=$2
TYPE=$3

get_response(){
? curl -sL \
? ? -H "Accept: application/vnd.github+json" \
? ? -H "Authorization: Bearer $TOKEN"\
? ? -H "X-GitHub-Api-Version: 2022-11-28" \
? ? https://api.github.com/repos/januschung/"$REPO"/"$TYPE"/alerts
}

do_something(){
? ? if [ "TYPE" == 'code-scanning' ]; then
? ? ? ? do_something_code_scanning
? ? elif [ "TYPE" == 'dependabot' ]; then
? ? ? ? do_something_dependabot
? ? elif [ "TYPE" == 'secret-scanning' ]; then
? ? ? ? do_something_secret_scanning
? ? else
? ? ? ? exit 1
? ? fi
}

do_something_code_scanning(){
? ? echo "Running Secret Scanning!"
}

do_something_dependabot(){
? ? echo "Running Dependabot!"
}

do_something_secret_scanning(){
? ? echo "Running Secret Scanning!"
}

get_response
do_something        

The consolidated action.yml

name: 'Alert Check'
description: 'Run alert check'
inputs:
? alert-type:
? ? description: 'Alert type to run - code-scanning, dependabot or secret-scanning'
? ? required: true
? ? default: 'dependabot'
? gh-token:
? ? required: true

runs:
? using: "composite"
? steps:
? ? - uses: actions/checkout@v3
? ? ? with:
? ? ? ? token: ${{ inputs.gh-token }}
? ? - shell: bash
? ? ? run: echo "${{ github.action_path }}" >> $GITHUB_PATH
? ? - shell: bash
? ? ? run: |
? ? ? ? alert.sh ${{ inputs.gh-token }} ${{ github.event.repository.name }} {{ inputs.alert-type }}        

I do not want to create three seperate workflows from the external repo either, so I use GitHub Matrix in a single workflow:

on: [push]

jobs:
? run_alert:
? ? runs-on: ubuntu-latest
? ? name: Run Alert
? ? strategy:
? ? ? matrix:
? ? ? ? type: ['code-scanning', 'dependabot', 'secret-scanning']
? ? steps:
? ? ? - uses: actions/checkout@v3
? ? ? - uses: januschung/shared-action-repo/.github/actions/alerts@main
? ? ? ? with:
? ? ? ? ? gh-token: ${{ secrets.GH_TOKEN }}
          alert-type: ${{ matrix.type }}         

That is it! I hope this helps if you are into similar situation in the coming future.

Useful Links

Composite Action

Matrix

要查看或添加评论,请登录

Janus Chung的更多文章

  • GitHub Multi Repos Update

    GitHub Multi Repos Update

    Background This is related to the other blog post about GitHub Shared Action. I want to make the same change to…

社区洞察

其他会员也浏览了