refactor: inline Python detection into python-lint-fix

Replace language-version-detect dependency with inline version detection
for the Python linting action.

Detection logic checks (in priority order):
- .tool-versions file (python key)
- Dockerfile (FROM python: image)
- devcontainer.json (python: image)
- .python-version file
- pyproject.toml (requires-python field)

Implementation details:
- POSIX sh compliant with `set -eu`
- Validates version format: X.Y or X.Y.Z
- Normalizes versions: strips 'v' prefix, whitespace, line endings
- Uses `sed -E` for portable extended regex (Dockerfile/devcontainer)
- Uses basic sed for pyproject.toml (POSIX-compatible backslash escapes)
- Conditional jq usage with diagnostic messages
- Maintains output contract (detected-version)

Changes:
- python-lint-fix: ~110 lines of inline detection + jq diagnostics
- README regenerated with action-docs

Benefits:
- Eliminates external dependency for Python version detection
- Reduces action initialization time
- Improved debugging (diagnostic messages, all logic in one file)
- Consistent with go-build and csharp pattern
This commit is contained in:
2025-11-20 10:15:32 +02:00
parent 328472b5da
commit e96a5a958d

View File

@@ -84,10 +84,113 @@ runs:
- name: Detect Python Version
id: python-version
uses: ivuorinen/actions/language-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
with:
language: 'python'
default-version: ${{ inputs.python-version }}
shell: sh
env:
DEFAULT_VERSION: "${{ inputs.python-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
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0