mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-22 11:29:22 -05:00
193 lines
7.1 KiB
YAML
193 lines
7.1 KiB
YAML
name: Resolve Docker Version
|
|
description: |
|
|
Resolves and validates Docker-compatible SemVer versions for container builds with comprehensive security.
|
|
|
|
Security Features:
|
|
- Command injection protection
|
|
- Input sanitization and validation
|
|
- Docker tag character restrictions
|
|
- Length limits and boundary checks
|
|
- Safe branch name handling
|
|
|
|
Supports multiple modes: release, manual override, branch auto-detection, and experimental timestamped versions.
|
|
|
|
inputs:
|
|
version:
|
|
description: "Explicit version (SemVer only, e.g., 1.2.3-beta). If provided, this version is used directly. If empty, version is auto-generated from branch name."
|
|
required: false
|
|
current_branch:
|
|
description: "Current branch name for auto-detection"
|
|
required: true
|
|
experimental_mode:
|
|
description: "Enable experimental mode with timestamp-based versions"
|
|
required: false
|
|
default: "false"
|
|
|
|
outputs:
|
|
version:
|
|
description: "Resolved Docker-compatible SemVer version"
|
|
value: ${{ steps.resolve.outputs.version }}
|
|
source:
|
|
description: "Source of version (release|override|branch)"
|
|
value: ${{ steps.resolve.outputs.source }}
|
|
normalized:
|
|
description: "Whether the version was normalized (true/false)"
|
|
value: ${{ steps.resolve.outputs.normalized }}
|
|
|
|
runs:
|
|
using: "composite"
|
|
steps:
|
|
- name: Resolve and validate Docker version
|
|
id: resolve
|
|
shell: bash
|
|
env:
|
|
EXPLICIT_VERSION: ${{ inputs.version }}
|
|
CURRENT_BRANCH: ${{ inputs.current_branch }}
|
|
EXPERIMENTAL_MODE: ${{ inputs.experimental_mode }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
# Function to validate SemVer format (Docker-compatible, no '+' build metadata)
|
|
validate_semver() {
|
|
local version="$1"
|
|
local context="$2"
|
|
|
|
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
|
|
echo "ERROR: Invalid $context format. Must be semver without build metadata (e.g., 1.2.3, 1.2.3-alpha)"
|
|
echo "Provided: $version"
|
|
echo "Note: Docker tags cannot contain '+' characters. Use prerelease identifiers instead."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Function to generate branch-based version
|
|
generate_branch_version() {
|
|
local branch="$1"
|
|
local use_timestamp="${2:-true}"
|
|
local timestamp
|
|
|
|
if [[ "$use_timestamp" == "true" ]]; then
|
|
timestamp=$(date +%s)
|
|
else
|
|
timestamp=""
|
|
fi
|
|
|
|
# Sanitize branch name for Docker compatibility
|
|
local sanitized_branch=$(echo "$branch" | sed 's/[^a-zA-Z0-9.-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
|
|
|
|
# Additional safety: truncate if too long (reserve space for prefix and timestamp)
|
|
if (( ${#sanitized_branch} > 80 )); then
|
|
sanitized_branch="${sanitized_branch:0:80}"
|
|
echo "INFO: Branch name truncated for Docker compatibility" >&2
|
|
fi
|
|
local version
|
|
|
|
# Generate version based on branch name (unified approach)
|
|
# All branches get alpha versions with sanitized branch name
|
|
if [[ -n "$timestamp" ]]; then
|
|
version="0.0.0-alpha-$sanitized_branch-$timestamp"
|
|
echo "INFO: Branch '$branch' detected - alpha version: $version" >&2
|
|
else
|
|
version="0.0.0-alpha-$sanitized_branch"
|
|
echo "INFO: Branch '$branch' detected - alpha version: $version" >&2
|
|
fi
|
|
|
|
echo "$version"
|
|
}
|
|
|
|
|
|
# Input validation and sanitization
|
|
if [[ -z "$CURRENT_BRANCH" ]]; then
|
|
echo "ERROR: current_branch input is required"
|
|
exit 1
|
|
fi
|
|
|
|
# Security: Validate inputs to prevent command injection
|
|
# Use grep to check for dangerous characters (more reliable than bash regex)
|
|
validate_input() {
|
|
local input="$1"
|
|
local name="$2"
|
|
|
|
# Check for dangerous characters using grep
|
|
if echo "$input" | grep -q '[;|&`$(){}\\[:space:]]'; then
|
|
echo "ERROR: $name contains potentially dangerous characters: $input"
|
|
echo "Input should only contain letters, numbers, hyphens, underscores, dots, and forward slashes"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Validate current branch
|
|
if ! validate_input "$CURRENT_BRANCH" "Branch name"; then
|
|
exit 1
|
|
fi
|
|
|
|
# Validate explicit version if provided
|
|
if [[ -n "$EXPLICIT_VERSION" ]] && ! validate_input "$EXPLICIT_VERSION" "Explicit version"; then
|
|
exit 1
|
|
fi
|
|
|
|
# Main resolution logic (ultra-simplified)
|
|
NORMALIZED="false"
|
|
|
|
if [[ -n "$EXPLICIT_VERSION" ]]; then
|
|
# Use provided explicit version (from either workflow_call or manual input)
|
|
validate_semver "$EXPLICIT_VERSION" "explicit version"
|
|
|
|
# Normalize to lowercase for Docker/ECR compatibility
|
|
RESOLVED_VERSION="${EXPLICIT_VERSION,,}"
|
|
if [[ "$EXPLICIT_VERSION" != "$RESOLVED_VERSION" ]]; then
|
|
NORMALIZED="true"
|
|
echo "INFO: Original version contained uppercase characters, normalized: $EXPLICIT_VERSION -> $RESOLVED_VERSION"
|
|
fi
|
|
|
|
SOURCE="explicit"
|
|
echo "INFO: Using explicit version: $RESOLVED_VERSION"
|
|
|
|
else
|
|
# Auto-generate version from branch name
|
|
if [[ "$EXPERIMENTAL_MODE" == "true" ]]; then
|
|
# Use timestamped version generation
|
|
echo "INFO: Experimental mode: generating timestamped version from branch: $CURRENT_BRANCH"
|
|
RESOLVED_VERSION=$(generate_branch_version "$CURRENT_BRANCH" "true")
|
|
SOURCE="experimental"
|
|
else
|
|
# Standard branch version (no timestamp)
|
|
echo "INFO: Auto-detecting version from branch: $CURRENT_BRANCH"
|
|
RESOLVED_VERSION=$(generate_branch_version "$CURRENT_BRANCH" "false")
|
|
SOURCE="branch"
|
|
fi
|
|
echo "Generated version: $RESOLVED_VERSION"
|
|
fi
|
|
|
|
# Final validation - ensure result is valid Docker tag
|
|
if [[ -z "$RESOLVED_VERSION" ]]; then
|
|
echo "ERROR: Failed to resolve version"
|
|
exit 1
|
|
fi
|
|
|
|
if (( ${#RESOLVED_VERSION} > 128 )); then
|
|
echo "ERROR: Version must be at most 128 characters (Docker limitation)"
|
|
echo "Generated version: $RESOLVED_VERSION (${#RESOLVED_VERSION} chars)"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! "$RESOLVED_VERSION" =~ ^[a-z0-9._-]+$ ]]; then
|
|
echo "ERROR: Version contains invalid characters for Docker tags"
|
|
echo "Version: $RESOLVED_VERSION"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$RESOLVED_VERSION" =~ ^[.-] || "$RESOLVED_VERSION" =~ [.-]$ ]]; then
|
|
echo "ERROR: Version must not start or end with '.' or '-'"
|
|
echo "Version: $RESOLVED_VERSION"
|
|
exit 1
|
|
fi
|
|
|
|
# Output results
|
|
echo "SUCCESS: Resolved Docker version: $RESOLVED_VERSION (source: $SOURCE)"
|
|
echo "version=$RESOLVED_VERSION" >> $GITHUB_OUTPUT
|
|
echo "source=$SOURCE" >> $GITHUB_OUTPUT
|
|
echo "normalized=$NORMALIZED" >> $GITHUB_OUTPUT
|