How to build a custom GitHub Action

Sara Verdi
Sara Verdi
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


Building custom GitHub Actions can boost productivity by automating complex processes, such as CI/CD tasks, code linting, or even interacting with other services and APIs. This guide will walk you through the process of creating a custom GitHub Action, incorporating Graphite Automations for more complex workflows.

GitHub Actions is a powerful automation tool that helps you to streamline software development workflows directly within your GitHub repository. These actions can be used to handle tasks like continuous integration and continuous deployment (CI/CD), testing, or deploying code changes based on specific triggers within GitHub. The core concept behind GitHub Actions lies in its ability to automate workflows, defined as 'actions,' triggered by GitHub events such as a push, a pull request, or issue creation.

An action itself is a custom piece of software, typically a script or a Docker container, that executes a set of tasks. These tasks can be as simple as sending a notification or as complex as deploying a multi-container application to a cloud provider. Actions are defined in a YAML file within your repository in a directory named .github/workflows. Each workflow can contain one or more jobs, and each job can contain one or more steps. A step can run commands or an action.

To tailor actions to specific needs, you have two main options:

  1. JavaScript actions: These are executed directly on GitHub’s virtual machines or runners. They are fast to start and allow for complex scripting in a familiar language.

  2. Docker container actions: These run inside a Docker container and can be used when you need a specific operating system environment or tools not available on GitHub-hosted runners.

By creating custom GitHub Actions, you can automate nearly any aspect of your development workflow, making it possible to reduce errors, ensure consistency, and save time for more critical tasks.

  1. Create an action metadata file (action.yml): This file defines the inputs, outputs, and main entry point of your action.

    Terminal
    name: 'Custom Notification Action'
    description: 'Posts a custom message to Slack or updates a task in JIRA'
    inputs:
    message:
    description: 'Message to post'
    required: true
    runs:
    using: 'node12'
    main: 'index.js'
  2. Write the action code (index.js):

    Terminal
    const core = require('@actions/core')
    try {
    const message = core.getInput('message')
    console.log(`Hello ${message}`)
    // Add more code to perform the action, like calling APIs
    } catch (error) {
    core.setFailed(error.message)
    }
  3. Add dependencies and commit: Ensure any dependencies are included in your repository and create a commit with all the files.

  1. Create a Dockerfile: This defines the environment and includes instructions for what to run.

    Terminal
    FROM alpine:3.10
    COPY entrypoint.sh /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
  2. Define the action metadata file (action.yml):

    Terminal
    name: 'Hello World'
    description: 'Greet someone and record the time'
    inputs:
    who-to-greet: # id of input
    description: 'who to greet'
    required: true
    default: world
    outputs:
    time: # id of output
    description: 'The time we greeted you'
    runs:
    using: 'docker'
    image: 'Dockerfile'
    args:
    - '${{ inputs.who-to-greet }}'
  3. Write the action code

Create a new entrypoint.sh file in the repository directory. Then add the following code to your entrypoint.sh file:

Terminal
#!/bin/sh -l
echo "Hello $1"
time=$(date)
echo "time=$time" >> $GITHUB_OUTPUT
  1. Trigger the workflow by pushing changes to your repository and observe the Actions tab in GitHub.

After testing and confirming that your action works:

  1. Tag your repository and push the tag to GitHub: This allows users to pin to specific versions of your action.
  2. Document how to use your action in the README.
  3. Publish your action in the GitHub Marketplace for broader visibility.

For more sophisticated automation, consider using Graphite Automations, which can automate tedious tasks like assigning reviewers, adding labels, and more when PR attributes meet specific criteria. This can be particularly useful in a complex workflow where your GitHub Action interacts with pull requests.

For instance, you could create a custom GitHub Action that uses Graphite to automatically add reviewers to a PR based on the content of the files changed, leveraging Graphite's ability to specify glob patterns for filenames and automate actions based on these rules.

By following these steps, you'll be able to build custom GitHub Actions that can automate virtually any aspect of your development workflow, enhancing productivity and consistency across your projects.

Git inspired
Graphite's CLI and VS Code extension make working with Git effortless.
Learn more

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2