Published on

Dynamically Populating Parameters in Manual GitHub Action

Authors

Overview

When manually running a GitHub Action with configured choice parameters, it's ideal to have the values dynamically generated and displayed in a drop-down menu. This can be accomplished by creating a GitHub Action that updates the parameters in the YAML file of the main action whenever changes are pushed.

GitHub Action to Update YAML File

Here is a GitHub Action designed to populate the option values:

name: 'Populate option values'

on:
  push:
    branches:
      - 'main'

jobs:
  eslint:
    name: Populate Option Values
    runs-on: ubuntu-latest
    steps:
      - name: Check out Code
        uses: actions/checkout@v2
        with:
          token: ${{ secrets.GH_TOKEN }}

      - name: Run Populator
        run: ./scripts/populate-option-value.sh

      - name: Commit Changes
        run: |
          if git diff --quiet; then
            echo "ℹ️ No new Component names to update"
          else
            git config --global user.email "${{ github.actor }}@email.com }}"
            git config --global user.name "${{ github.actor }}"
            git status
            git add .github/workflows/release-it.yml
            git commit -m "✅ Populated option values"
            git push
          fi

Note: You'll need to create a GitHub Personal Access Token (PAT) with push permissions, as the default GitHub PAT does not allow changes to be pushed from the GitHub Action. This should be configured as a secret in your repository.

Populator Script

A script is used to read the current parameter values, compare them to the dynamic values, and update the YAML file if they differ:

Note: here I use

yq
to manipulate YAML. Further you need to allow GH Action to run the script otherwise you will get
Permision Denied
error when run Action.

git update-index --chmod=+x your_script.sh

#!/bin/bash

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
SOURCE_YAML_FILE="$SCRIPT_DIR/../.github/workflows/target-action.yml"

# dynamically generate values.
# ex. could read repository or file to get values
OPTIONS=(major minor patch prerelease)

current_options=$(yq eval '.on.workflow_dispatch.inputs.version.options' $SOURCE_YAML_FILE )

current_options_array=()
while read -r word; do
    current_options_array+=("$word")
done <<< "$current_options"

declare -a output_array=()

for i in $OPTIONS; do
    output_array+=("$i")
done

# Check if the values in the arrays are equal
if [[ "${current_options_array[*]}" == "${output_array[*]}" ]]; then
    echo "Values in YAML file are equal to values in array. No update needed."
else
    echo "Values in YAML file are not equal to values in array. Updating YAML file."
    # Construct YAML-compatible string
    options_string="["

    for option in "${output_array[@]}"; do
        options_string+="\\"$option\\", "
    done

    options_string="${options_string%, }]"

    yq eval ".on.workflow_dispatch.inputs.version.options = $options_string" $SOURCE_YAML_FILE > temp.yml && mv temp.yml $SOURCE_YAML_FILE
fi

The action file with the choice parameter might look like this:

name: 'Release'
on:
  workflow_dispatch:
    inputs:
      version:
        type: choice
        options:
          - 'major'
          - 'minor'
        required: true
        default: 'patch'
jobs:
  release:
    runs-on: [ubuntu-latest]
    name: Release it
    environment: NPM_Feed
    steps:
      - name: Check out Code
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

When the populator action is triggered (any changes pushed to the branch), it will execute the script, populate the target action YAML, and create a commit pushing the changes. The updated YAML might look like this:

name: 'Release'
on:
  workflow_dispatch:
    inputs:
      version:
        type: choice
        options:
          - 'major'
          - 'minor'
					- 'patch'
          - 'prerelease'
        required: true
        default: 'patch'
jobs:
  release:
    runs-on: [ubuntu-latest]
    name: Release it
    steps:
      - name: Check out Code
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      .......

This strategy allows for dynamic population of choice parameters in your GitHub Actions.