add conditional-variables
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
name: Conditional Variables
|
||||
|
||||
description: |
|
||||
Evaluates a list of conditions and exposes variables as outputs.
|
||||
Conditions are evaluated in order. All matching conditions are applied.
|
||||
If multiple conditions set the same variable, the last matching value wins.
|
||||
|
||||
inputs:
|
||||
context:
|
||||
description: |
|
||||
Context variables available during condition evaluation.
|
||||
|
||||
conditions:
|
||||
description: |
|
||||
List of conditions to evaluate.
|
||||
|
||||
Example:
|
||||
|
||||
- when:
|
||||
branch:
|
||||
- 9.0-alpine-24
|
||||
- 9.0-alpine-23
|
||||
set:
|
||||
DOTNET_VERSION: 9.0
|
||||
|
||||
required: true
|
||||
|
||||
fail-on-no-match:
|
||||
description: |
|
||||
Fail the action when no condition matches.
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Evaluate conditions
|
||||
shell: bash
|
||||
env:
|
||||
CONTEXT: ${{ inputs.context }}
|
||||
CONDITIONS: ${{ inputs.conditions }}
|
||||
FAIL_ON_NO_MATCH: ${{ inputs.fail-on-no-match }}
|
||||
run: |
|
||||
"${{ github.action_path }}/evaluate.sh"
|
||||
@@ -0,0 +1,141 @@
|
||||
trim() {
|
||||
local var="$*"
|
||||
var="${var#"${var%%[![:space:]]*}"}"
|
||||
var="${var%"${var##*[![:space:]]}"}"
|
||||
printf '%s' "$var"
|
||||
}
|
||||
|
||||
declare -A context
|
||||
|
||||
#
|
||||
# Load context
|
||||
#
|
||||
while IFS='=' read -r key value; do
|
||||
|
||||
key="$(trim "${key:-}")"
|
||||
value="$(trim "${value:-}")"
|
||||
|
||||
[[ -z "$key" ]] && continue
|
||||
[[ "$key" =~ ^# ]] && continue
|
||||
|
||||
context["$key"]="$value"
|
||||
|
||||
done <<< "$CONTEXT"
|
||||
|
||||
matched=false
|
||||
|
||||
#
|
||||
# Evaluate conditions (OR)
|
||||
#
|
||||
while IFS= read -r condition; do
|
||||
|
||||
condition="$(trim "${condition:-}")"
|
||||
|
||||
[[ -z "$condition" ]] && continue
|
||||
[[ "$condition" =~ ^# ]] && continue
|
||||
|
||||
read -r variable operator expected <<< "$condition"
|
||||
|
||||
#
|
||||
# Validate condition format
|
||||
#
|
||||
if [[ -z "${variable:-}" || -z "${operator:-}" || -z "${expected:-}" ]]; then
|
||||
echo "Invalid condition: $condition"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -v context["$variable"] ]]; then
|
||||
echo "Unknown context variable '$variable'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
actual="${context[$variable]}"
|
||||
|
||||
case "$operator" in
|
||||
|
||||
"==")
|
||||
[[ "$actual" == "$expected" ]] && matched=true
|
||||
;;
|
||||
|
||||
"!=")
|
||||
[[ "$actual" != "$expected" ]] && matched=true
|
||||
;;
|
||||
|
||||
">"|">="|"<"|"<=")
|
||||
|
||||
#
|
||||
# Numeric comparisons only
|
||||
#
|
||||
if [[ ! "$actual" =~ ^-?[0-9]+$ ]]; then
|
||||
echo "Numeric operator '$operator' requires integer value. Actual: '$actual'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$expected" =~ ^-?[0-9]+$ ]]; then
|
||||
echo "Numeric operator '$operator' requires integer comparison value. Expected: '$expected'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$operator" in
|
||||
">")
|
||||
(( actual > expected )) && matched=true
|
||||
;;
|
||||
">=")
|
||||
(( actual >= expected )) && matched=true
|
||||
;;
|
||||
"<")
|
||||
(( actual < expected )) && matched=true
|
||||
;;
|
||||
"<=")
|
||||
(( actual <= expected )) && matched=true
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unsupported operator: $operator"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
#
|
||||
# OR logic:
|
||||
# stop at first match
|
||||
#
|
||||
[[ "$matched" == true ]] && break
|
||||
|
||||
done <<< "$CONDITIONS"
|
||||
|
||||
#
|
||||
# Set outputs
|
||||
#
|
||||
if [[ "$matched" == true ]]; then
|
||||
|
||||
while IFS= read -r output; do
|
||||
|
||||
output="$(trim "${output:-}")"
|
||||
|
||||
[[ -z "$output" ]] && continue
|
||||
[[ "$output" =~ ^# ]] && continue
|
||||
|
||||
#
|
||||
# Validate output syntax
|
||||
#
|
||||
if [[ ! "$output" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then
|
||||
echo "Invalid variable definition: $output"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$output" >> "$GITHUB_OUTPUT"
|
||||
|
||||
done <<< "$VARIABLES"
|
||||
|
||||
fi
|
||||
|
||||
if [[ "$matched" == false && "$FAIL_ON_NO_MATCH" == "true" ]]; then
|
||||
echo "No conditions matched"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "matched=$matched" >> "$GITHUB_OUTPUT"
|
||||
Reference in New Issue
Block a user