# yaml-language-server: $schema=https://json.schemastore.org/github-action.json # permissions: # - (none required) # Read-only validation action --- name: Version Validator description: 'Validates and normalizes version strings using customizable regex patterns' author: 'Ismo Vuorinen' branding: icon: check-circle color: green inputs: version: description: 'Version string to validate' required: true validation-regex: description: 'Regex pattern for validation' required: false default: '^[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$' language: description: 'Language name for error messages' required: false default: 'version' outputs: is-valid: description: 'Boolean indicating if version is valid (true/false)' value: ${{ steps.validate.outputs.is-valid }} validated-version: description: 'Cleaned/normalized version string' value: ${{ steps.validate.outputs.validated-version }} error-message: description: 'Error message if validation fails' value: ${{ steps.validate.outputs.error-message }} runs: using: composite steps: - name: Validate Inputs id: validate-inputs shell: bash env: VERSION: ${{ inputs.version }} VALIDATION_REGEX: ${{ inputs.validation-regex }} LANGUAGE: ${{ inputs.language }} run: | set -euo pipefail # Validate version input is not empty if [[ -z "$VERSION" ]]; then echo "::error::Version input cannot be empty" exit 1 fi # Validate version string doesn't contain dangerous characters if [[ "$VERSION" == *";"* ]] || [[ "$VERSION" == *"&&"* ]] || \ [[ "$VERSION" == *"|"* ]] || [[ "$VERSION" == *"`"* ]] || [[ "$VERSION" == *"$"* ]]; then echo "::error::Invalid version string: '$VERSION'. Potentially dangerous characters detected" exit 1 fi # Validate validation-regex is not empty and doesn't contain dangerous patterns if [[ -z "$VALIDATION_REGEX" ]]; then echo "::error::Validation regex cannot be empty" exit 1 fi # Basic check for regex safety (prevent ReDoS) if [[ "$VALIDATION_REGEX" == *".*.*"* ]] || [[ "$VALIDATION_REGEX" == *".+.+"* ]]; then echo "::warning::Validation regex may be vulnerable to ReDoS attacks" fi # Validate language parameter if [[ "$LANGUAGE" == *";"* ]] || [[ "$LANGUAGE" == *"&&"* ]] || [[ "$LANGUAGE" == *"|"* ]]; then echo "::error::Invalid language parameter: '$LANGUAGE'. Command injection patterns not allowed" exit 1 fi echo "Input validation completed successfully" - name: Validate Version id: validate shell: bash env: VERSION: ${{ inputs.version }} VALIDATION_REGEX: ${{ inputs.validation-regex }} LANGUAGE: ${{ inputs.language }} run: |- set -euo pipefail input_version="$VERSION" regex="$VALIDATION_REGEX" language="$LANGUAGE" # Clean the version string cleaned_version=$(echo "$input_version" | sed -e 's/^[vV]//' | tr -d ' ' | tr -d '\n' | tr -d '\r') # Validate the version if [[ $cleaned_version =~ $regex ]]; then { echo "is-valid=true" printf 'validated-version=%s\n' "$cleaned_version" echo "error-message=" } >> "$GITHUB_OUTPUT" echo "✅ Valid $language version: $cleaned_version" >&2 else error_msg="Invalid $language version format: '$input_version' (cleaned: '$cleaned_version'). Expected pattern: $regex" # Sanitize error message by removing newlines to prevent GITHUB_OUTPUT injection error_msg_sanitized="$(echo "$error_msg" | tr -d '\n\r')" { echo "is-valid=false" echo "validated-version=" printf 'error-message=%s\n' "$error_msg_sanitized" } >> "$GITHUB_OUTPUT" echo "❌ $error_msg" >&2 fi