DEV Community

Koushik KM
Koushik KM

Posted on

Writing your first Github action

Two days back I came to know about hackathon by Github and I thought of making some useful action. But before that, I decided to do something fun and learn about the basics of Github action. So I created action-pr-gifs Inspired from action-cats. action-pr-gifs will post gif as a comment in PR based on the type of the PR. Check out my action and have fun!

Let's make a simple GitHub action to post a comment in a PR!

Setting the repo

You can create an action in 2 ways

  • Docker container action
  • Javascript action

Docker container

This type of action is ideal if you want to run your actions with a particular Operating system, environments, etc. Note that they are slow when compared with javascript action as it has to retrieve the container.

Javascript action

JavaScript actions can run directly on a runner machine. This is much simpler and faster and I will be using javascript action in this tutorial.

Instead of creating a node repo from scratch I will recommend using template provided by the GitHub team. It has almost everything to start your first GitHub action. But if you want to start everything from scratch like me, you can always do that.

Before writing any actual code, please make sure to configure eslint with your project. It will make sure that you use the same coding style across the project.

action.yml

Add a file action.yml in your root folder and add the following line.

name: 'Action name'
description: 'A sample description'
inputs:
  github-token:
    description: 'Pass in secrets.GITHUB_TOKEN'
    required: true
runs:
  using: 'node12'
  main: 'dist/index.js'
Enter fullscreen mode Exit fullscreen mode

Did you note that I added dist/index.js as main? I will come to that later.

Actual code

Add a new function run in index.js or src/index.js whatever you prefer. This is a simple function to post a comment You are awesome on every pull request. Note that this should be triggered for PR event only. So if it triggered for any other event, the function should throw an error.

const core = require('@actions/core');
const github = require('@actions/github');

async function run() {
  try {
    const githubToken = core.getInput('GITHUB_TOKEN');

    const { context } = github;
    if (context.payload.pull_request == null) {
      core.setFailed('No pull request found.');
    }

    const pullRequestNumber = context.payload.pull_request.number;
    const octokit = new github.GitHub(githubToken);
    const message = 'Wow! you are awesome';

    octokit.issues.createComment({
      ...context.repo,
      issue_number: pullRequestNumber,
      body: message,
    });
  } catch (error) {
    core.setFailed(error.message);
  }
}

run();
Enter fullscreen mode Exit fullscreen mode

Build

GitHub downloads each action run in a workflow during runtime and executes it as a complete package of code. So you need node_modules to run your code. If you added it to .gitignore, please remove it. Alternatively, you can use zeit/ncc to build your source code so that you don't need node modules.

Install ncc using the following command

yarn add @zeit/ncc --dev
Enter fullscreen mode Exit fullscreen mode

Build your source using

ncc build index.js (or) ncc build src/index.js 
Enter fullscreen mode Exit fullscreen mode

This will build your source files to the dist folder. This will be your main file and remember to build and commit this file every time you make a change in the source file.

Testing

There is nothing much in this action to test. But it is always recommended to write tests for your GitHub action. You can check my repository for some examples.

That is it, You have written your first Github action. It is time to test it

Adding action to repositories

Before listing the action in the marketplace you can test it once in the same repository. Create a file .github/workflows/main.yml with the same structure and add the following line.

name: PR

# Controls when the action will run. Triggers the workflow on push or pull request 
# events but only for the master branch
on:
  pull_request:
    branches: [ master ]
jobs:
  pr_check:
    runs-on: ubuntu-latest
    name: A job to Post comment on PR
    steps:
    - uses: actions/checkout@v2
    - name: PR Action
      uses: koushikmohan1996/action-pr-gifs@master
      with:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Enter fullscreen mode Exit fullscreen mode

Based on your action you should change koushikmohan1996/action-pr-gifs@master with your username/reponame@master. Here I used branches: [master] so the action will trigger only if the PR is created to master branch. You can remove this if you want this in all branches.

After you tested everything, you can add this action to Marketplace by creating a release. Note that you need a readme file and license file to make a release in the Marketplace.

Check this sample pr of action-pr-gifs. Drop a comment if you have created any cool Github action or if you come across one.

Signing off!

Top comments (0)