diff --git a/pr-lint/action.yml b/pr-lint/action.yml index 6c71909..57dcf92 100644 --- a/pr-lint/action.yml +++ b/pr-lint/action.yml @@ -136,9 +136,118 @@ runs: - name: Detect PHP Version if: steps.detect-php.outputs.found == 'true' id: php-version - uses: ivuorinen/actions/language-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42 - with: - language: 'php' + shell: sh + env: + DEFAULT_VERSION: '8.4' + run: | + set -eu + + # Function to validate version format + validate_version() { + version=$1 + case "$version" in + [0-9]*.[0-9]* | [0-9]*.[0-9]*.[0-9]*) + return 0 + ;; + *) + return 1 + ;; + esac + } + + # Function to clean version string + clean_version() { + printf '%s' "$1" | sed 's/^[vV]//' | tr -d ' \n\r' + } + + detected_version="" + + # Parse .tool-versions file + if [ -f .tool-versions ]; then + echo "Checking .tool-versions for php..." >&2 + version=$(awk '/^php[[:space:]]/ {gsub(/#.*/, ""); print $2; exit}' .tool-versions 2>/dev/null || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found PHP version in .tool-versions: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse Dockerfile + if [ -z "$detected_version" ] && [ -f Dockerfile ]; then + echo "Checking Dockerfile for php..." >&2 + version=$(grep -iF "FROM" Dockerfile | grep -F "php:" | head -1 | \ + sed -n -E "s/.*php:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found PHP version in Dockerfile: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse devcontainer.json + if [ -z "$detected_version" ] && [ -f .devcontainer/devcontainer.json ]; then + echo "Checking devcontainer.json for php..." >&2 + if command -v jq >/dev/null 2>&1; then + version=$(jq -r '.image // empty' .devcontainer/devcontainer.json 2>/dev/null | sed -n -E "s/.*php:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found PHP version in devcontainer: $version" >&2 + detected_version="$version" + fi + fi + else + echo "jq not found; skipping devcontainer.json parsing" >&2 + fi + fi + + # Parse .php-version file + if [ -z "$detected_version" ] && [ -f .php-version ]; then + echo "Checking .php-version..." >&2 + version=$(tr -d '\r' < .php-version | head -1) + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found PHP version in .php-version: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse composer.json + if [ -z "$detected_version" ] && [ -f composer.json ]; then + echo "Checking composer.json..." >&2 + if command -v jq >/dev/null 2>&1; then + version=$(jq -r '.require.php // empty' composer.json 2>/dev/null | sed -n 's/[^0-9]*\([0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*/\1/p') + if [ -z "$version" ]; then + version=$(jq -r '.config.platform.php // empty' composer.json 2>/dev/null | sed -n 's/[^0-9]*\([0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*/\1/p') + fi + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found PHP version in composer.json: $version" >&2 + detected_version="$version" + fi + fi + else + echo "jq not found; skipping composer.json parsing" >&2 + fi + fi + + # Use default version if nothing detected + if [ -z "$detected_version" ]; then + detected_version="$DEFAULT_VERSION" + echo "Using default PHP version: $detected_version" >&2 + fi + + # Set output + printf 'detected-version=%s\n' "$detected_version" >> "$GITHUB_OUTPUT" + echo "Final detected PHP version: $detected_version" >&2 - name: Setup PHP if: steps.detect-php.outputs.found == 'true' @@ -182,9 +291,113 @@ runs: - name: Detect Python Version if: steps.detect-python.outputs.found == 'true' id: python-version - uses: ivuorinen/actions/language-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42 - with: - language: 'python' + shell: sh + env: + DEFAULT_VERSION: '3.11' + run: | + set -eu + + # Function to validate version format + validate_version() { + version=$1 + case "$version" in + [0-9]*.[0-9]* | [0-9]*.[0-9]*.[0-9]*) + return 0 + ;; + *) + return 1 + ;; + esac + } + + # Function to clean version string + clean_version() { + printf '%s' "$1" | sed 's/^[vV]//' | tr -d ' \n\r' + } + + detected_version="" + + # Parse .tool-versions file + if [ -f .tool-versions ]; then + echo "Checking .tool-versions for python..." >&2 + version=$(awk '/^python[[:space:]]/ {gsub(/#.*/, ""); print $2; exit}' .tool-versions 2>/dev/null || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Python version in .tool-versions: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse Dockerfile + if [ -z "$detected_version" ] && [ -f Dockerfile ]; then + echo "Checking Dockerfile for python..." >&2 + version=$(grep -iF "FROM" Dockerfile | grep -F "python:" | head -1 | \ + sed -n -E "s/.*python:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Python version in Dockerfile: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse devcontainer.json + if [ -z "$detected_version" ] && [ -f .devcontainer/devcontainer.json ]; then + echo "Checking devcontainer.json for python..." >&2 + if command -v jq >/dev/null 2>&1; then + version=$(jq -r '.image // empty' .devcontainer/devcontainer.json 2>/dev/null | sed -n -E "s/.*python:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Python version in devcontainer: $version" >&2 + detected_version="$version" + fi + fi + else + echo "jq not found; skipping devcontainer.json parsing" >&2 + fi + fi + + # Parse .python-version file + if [ -z "$detected_version" ] && [ -f .python-version ]; then + echo "Checking .python-version..." >&2 + version=$(tr -d '\r' < .python-version | head -1) + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Python version in .python-version: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse pyproject.toml + if [ -z "$detected_version" ] && [ -f pyproject.toml ]; then + echo "Checking pyproject.toml..." >&2 + if grep -q '^\\[project\\]' pyproject.toml; then + version=$(grep -A 20 '^\\[project\\]' pyproject.toml | grep -E '^\\s*requires-python[[:space:]]*=' | sed -n 's/[^0-9]*\([0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*/\1/p' | head -1) + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Python version in pyproject.toml: $version" >&2 + detected_version="$version" + fi + fi + fi + fi + + # Use default version if nothing detected + if [ -z "$detected_version" ]; then + detected_version="$DEFAULT_VERSION" + echo "Using default Python version: $detected_version" >&2 + fi + + # Set output + printf 'detected-version=%s\n' "$detected_version" >> "$GITHUB_OUTPUT" + echo "Final detected Python version: $detected_version" >&2 - name: Setup Python if: steps.detect-python.outputs.found == 'true' @@ -215,9 +428,111 @@ runs: - name: Detect Go Version if: steps.detect-go.outputs.found == 'true' id: go-version - uses: ivuorinen/actions/language-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42 - with: - language: 'go' + shell: sh + env: + DEFAULT_VERSION: '1.24' + run: | + set -eu + + # Function to validate version format + validate_version() { + version=$1 + case "$version" in + [0-9]*.[0-9]* | [0-9]*.[0-9]*.[0-9]*) + return 0 + ;; + *) + return 1 + ;; + esac + } + + # Function to clean version string + clean_version() { + printf '%s' "$1" | sed 's/^[vV]//' | tr -d ' \n\r' + } + + detected_version="" + + # Parse .tool-versions file + if [ -f .tool-versions ]; then + echo "Checking .tool-versions for golang..." >&2 + version=$(awk '/^golang[[:space:]]/ {gsub(/#.*/, ""); print $2; exit}' .tool-versions 2>/dev/null || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Go version in .tool-versions: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse Dockerfile + if [ -z "$detected_version" ] && [ -f Dockerfile ]; then + echo "Checking Dockerfile for golang..." >&2 + version=$(grep -iF "FROM" Dockerfile | grep -F "golang:" | head -1 | \ + sed -n -E "s/.*golang:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Go version in Dockerfile: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse devcontainer.json + if [ -z "$detected_version" ] && [ -f .devcontainer/devcontainer.json ]; then + echo "Checking devcontainer.json for golang..." >&2 + if command -v jq >/dev/null 2>&1; then + version=$(jq -r '.image // empty' .devcontainer/devcontainer.json 2>/dev/null | sed -n -E "s/.*golang:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Go version in devcontainer: $version" >&2 + detected_version="$version" + fi + fi + else + echo "jq not found; skipping devcontainer.json parsing" >&2 + fi + fi + + # Parse .go-version file + if [ -z "$detected_version" ] && [ -f .go-version ]; then + echo "Checking .go-version..." >&2 + version=$(tr -d '\r' < .go-version | head -1) + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Go version in .go-version: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Parse go.mod + if [ -z "$detected_version" ] && [ -f go.mod ]; then + echo "Checking go.mod..." >&2 + version=$(grep -E '^go[[:space:]]+[0-9]' go.mod | awk '{print $2}' | head -1 || echo "") + if [ -n "$version" ]; then + version=$(clean_version "$version") + if validate_version "$version"; then + echo "Found Go version in go.mod: $version" >&2 + detected_version="$version" + fi + fi + fi + + # Use default version if nothing detected + if [ -z "$detected_version" ]; then + detected_version="$DEFAULT_VERSION" + echo "Using default Go version: $detected_version" >&2 + fi + + # Set output + printf 'detected-version=%s\n' "$detected_version" >> "$GITHUB_OUTPUT" + echo "Final detected Go version: $detected_version" >&2 - name: Setup Go if: steps.detect-go.outputs.found == 'true'