# Creating Custom Actions in GitHub Actions Using Docker

### **Introduction**

GitHub Actions provides a powerful way to automate workflows in your repositories. By creating custom actions, you can encapsulate reusable workflows, scripts, and automation steps into a single unit.

In this article, we will walk through the steps of creating a custom GitHub Action (based on Docker), using a practical example of an action that checks the number of public repositories in the Microsoft Azure organization.

### Step-by-Step Guide to Creating a Custom Action

#### **Step 1: Create a New Repository**

To get started, either create a new GitHub repository or navigate to an existing one where you want to create your custom action. The repository will contain all the necessary files for your action.

#### **Step 2: Set Up the Directory Structure**

Clone the repository for local development and begin to add files. Your repository should contain the following structure for the custom action:

```plaintext
my-github-action/
│
├── action.yml       # Metadata file
├── Dockerfile       # Docker configuration file
└── entrypoint.sh    # Script to execute inside the container
```

#### **Step 3: Define Action Metadata in** `action.yml`

The `action.yml` file defines the inputs, outputs, and execution environment of your custom action. Here’s an example:

```plaintext
name: 'Azure Repo Counter Action'
description: 'Fetches the public repository count for the Microsoft Azure GitHub organization'
inputs:
  my-input:
    description: 'A placeholder input value'
    required: true
    default: 'default value'
outputs:
  my-output:
    description: 'The number of public repositories'
runs:
  using: 'docker'
  image: 'Dockerfile'
  args:
    - ${{ inputs.my-input }}
```

This file defines the name of the action, input parameters, and outputs. The `runs` section specifies that the action will be executed in a Docker container.

#### **Step 4: Create the** `Dockerfile`

The Dockerfile describes how to build the Docker image that will run the action. Here’s a simple example:

```plaintext
FROM ubuntu:20.04

RUN apt-get update && apt-get install -y \
  curl \
  jq

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
```

In this file:

* We’re using an Ubuntu base image.
    
* Installing `curl` to make HTTP requests and `jq` to process JSON data.
    
* Copying and setting permissions for the [`entrypoint.sh`](http://entrypoint.sh) script.
    

#### **Step 5: Write the Action Logic in** [`entrypoint.sh`](http://entrypoint.sh)

The [`entrypoint.sh`](http://entrypoint.sh) script will be executed when the action runs. In this case, it fetches the number of public repositories for the Microsoft Azure GitHub organization and sets the value as an output.

```plaintext
#!/bin/bash

# Get the input value
MY_INPUT=$1

# Fetch public repositories from the Microsoft Azure organization using GitHub API
DATA=$(curl -s https://api.github.com/orgs/Azure)

# Use jq to parse the data and get the public repository count
REPO_COUNT=$(echo "$DATA" | jq '.public_repos')

# Output the number of public repositories
echo "Microsoft Azure organization has $REPO_COUNT public repositories"

# Set an output variable using the environment file method (Optional)
echo "my-output=$REPO_COUNT" >> "$GITHUB_ENV"
```

This script fetches data from the GitHub API, processes it using `jq`, and then uses the `GITHUB_ENV` file to pass the result to the workflow.

#### **Step 6: Push Your Action to GitHub**

Once everything is set up, push your changes to the repository:

```plaintext
git add .
git commit -m "Add custom Docker GitHub Action"
git push origin main
```

#### **Step 7: Use the Action in a Workflow**

To use your custom action, create a new workflow file in the `.github/workflows/` directory. Here’s an example workflow:

```plaintext
name: Example Workflow

on: [push]

jobs:
  my-job:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Run Azure Repo Counter Action
        uses: ./  # Uses the custom action in the same repository
        with:
          my-input: "Fetching Azure repositories"

      - name: Print output
        run: echo "Public repositories in Microsoft Azure: ${{ env.my-output }}"
```

This workflow will:

1. Checkout the repository code.
    
2. Execute your custom action.
    
3. Output the number of public repositories in the Microsoft Azure organization.
    

#### **Step 8: Trigger the Workflow**

Push changes to your repository, and GitHub Actions will automatically trigger the workflow. You can view the workflow’s execution in the "Actions" tab and see how your custom action performs.

### Conclusion

By following this guide, you’ve created a reusable GitHub Action that runs in a Docker container, fetches data from the GitHub API, and returns a result to your workflow. You can expand this approach to create more sophisticated actions, integrate with other APIs, or automate any part of your DevOps pipelines. Container actions provide great flexibility, as they allow you to run any tool or script in a controlled environment.
