Note_Tech

All technological notes.


Project maintained by simonangel-fong Hosted on GitHub Pages — Theme by mattgraham

GitHub Actions: Custom Actions

Back


Custom Actions


Types


Lab: Create Composiste Actions


name: 17 - Custom Actions - Composite
run-name: 17 - Custom Actions - Composite | env - $

on:
  workflow_dispatch:
    inputs:
      target-env:
        description: "Selete environment for dependencies installation"
        type: choice
        options:
          - dev
          - prod

env:
  working-directory: react-app

jobs:
  build:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: $

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Setup Node and NPM Dependencies
        uses: ./.github/actions/composite-cache-deps
        with:
          node-version: 24.x
          working-dir: $
          target-env: $

      - name: Test
        run: npm run test

      - name: Build
        run: npm run build

Lab: Create a JS action

# init js project
cd .github/actions/js-dependency-update

npm init -y
npm install @actions/core@latest

Custom Actions

Input & Output


Lab: Docker action

name: Ping URL
description: Ping URL untl maximum trials have exceeded. If result is not 200 until then, fails the action.

inputs:
  url:
    description: URL to ping
    required: true
  max_trials:
    description: maximum number of trials
    default: "10"
    required: false
  delay:
    description: Delay in seconds between trials
    default: "5"
    required: false

outputs:
  url-reachable:
    description: Whether the URL is reachable

runs:
  using: docker
  image: Dockerfile
FROM python:alpine3.19
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
CMD ["python", "/app/main.py"]
import os
import requests
from time import sleep

URL = os.getenv("INPUT_URL", "http://google.com")
DELAY = os.getenv("INPUT_DELAY", '5')
MAX_TRIALS = os.getenv("INPUT_MAX_TRIALS", "10")


def set_output(file_path, key, value):
    with open(file_path, "a") as file:
        print(f"{key}={value}", file=file)


def ping_url(url, delay, max_trials):
    trials = 0

    while trials < max_trials:
        try:
            response = requests.get(url)
            if response.status_code == 200:
                print(f"Website {url} is reachable.")
                return True
        except requests.ConnectionError:
            print(
                f"Website {url} is unreachable. Retring in {delay} seconds...")
            sleep(delay)

            trials += 1
        except requests.exceptions.MissingSchema:
            print(f"Invalid URL format: {url}")

    return False


def run():
    website_url = URL
    delay = int(DELAY)
    max_trials = int(MAX_TRIALS)

    # get ping return
    website_reachable = ping_url(website_url, delay, max_trials)

    # set output
    set_output(os.getenv('GITHUB_OUTPUT'),'url-reachable',website_reachable)

    if not website_reachable:
        raise Exception(f'Website {website_url} is malformaed or unreachable.')

    print(f"website {website_url} is reachable.")


if __name__ == "__main__":
    run()

name: 17 - Custom Actions - Docker
run-name: 17 - Custom Actions

on:
  workflow_dispatch:
    inputs:
      url:
        type: string
        default: "https://www.google.com"
      max_trials:
        description: maximum number of trials
        default: "10"
        required: false
      delay:
        description: Delay in seconds between trials
        default: "5"
        required: false

jobs:
  ping-url:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Ping URL
        id: ping-url
        uses: ./.github/actions/docker-ping-url
        with:
          url: $
          max_trials: $
          delay: $

      - name: Print output
        run: |
          echo "URL reachable: $"