Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtmckee committed Oct 6, 2023
0 parents commit e982fe3
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 0 deletions.
55 changes: 55 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: "Test"

on:
push:
branches:
- "main"

jobs:
test-linux:
name: "Test on ${{ matrix.config.os-name }}"
runs-on: "${{ matrix.config.runner }}"
strategy:
matrix:
config:
- os-name: "Linux"
runner: "ubuntu-latest"
test-label: "ci-test-linux"
- os-name: "macOS"
runner: "macos-latest"
test-label: "ci-test-macos"
fail-fast: false

steps:
- name: "Checkout"
uses: "actions/checkout@v4"

- name: "Linux / macOS"
id: linux
if: "runner.os != 'windows'"
shell: "bash"
run: |
env | sort
bash ./finder.sh false
bash ./finder.sh true
test-windows:
name: "Test on ${{ matrix.config.os-name }}"
runs-on: "${{ matrix.config.runner }}"
strategy:
matrix:
config:
- os-name: "Windows"
runner: "windows-latest"
test-label: "ci-test-windows"

steps:
- name: "Checkout"
uses: "actions/checkout@v4"

- name: "Windows"
shell: "powershell"
run: |
dir env:
& .\finder.ps1 false
& .\finder.ps1 true
54 changes: 54 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: "Identify installed Python interpreters"
description: |
Find installed Python interpreters and output them as "python-paths".
This can be useful for cache busting of tox, virtual environments,
and other items that are sensitive to changes in Python minor versions.
Only Python interpreters installed in $RUNNER_TOOL_CACHE will be found.
inputs:
search-runner-tool-cache:
description: |
By default, only paths in the PATH environment variable will be searched
because the "actions/setup-python" action typically modifies the PATH
after installing various Python versions.
Because it is possible to prevent "actions/setup-python" from modifying the PATH,
and because some GitHub runner images have multiple Python versions pre-installed,
it may be desirable to find every Python installed in $RUNNER_TOOL_CACHE,
even if their paths don't appear in the PATH environment variable.
If this input is specified, its value must be the string value "true".
Use quotation marks to ensure the correct value is passed.
required: false
default: "false"

outputs:
python-paths:
description: |
A string of sorted Python executable paths.
The string will be separated by OS-specific PATH separators;
":" is used on Linux and macOS, and ";" is used on Windows.
value: ${{ steps.final-step.outputs.python-path }}

runs:
using: "composite"
steps:
- name: "Find Pythons on Linux / macOS"
id: "linux"
if: "runner.os != 'windows'"
shell: "bash"
run: 'bash ./finder.sh "${{ inputs.search-runner-tool-cache }}" > "$GITHUB_OUTPUT"'

- name: "Find Pythons on Windows"
id: "windows"
if: "runner.os == 'windows'"
shell: "powershell"
run: '& .\finder.ps1 "${{ inputs.search-runner-tool-cache }}" > "$env:GITHUB_OUTPUT"'

- name: "Output"
id: "final-step"
shell: "bash"
run: |
echo "${{ steps.linux.outputs.python-paths }}${{ steps.windows.outputs.python-paths }}" > $GITHUB_OUTPUT
38 changes: 38 additions & 0 deletions finder.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
$search_runner_tool_cache = $args[0]

if ($search_runner_tool_cache -eq "true") {
# Search paths in $RUNNER_TOOL_CACHE for Python interpreters.
$all_paths = `
Get-ChildItem `
-Path `
"$env:RUNNER_TOOL_CACHE\Python\*\*", `
"$env:RUNNER_TOOL_CACHE\PyPy\*\*" `
-Filter "x??" `
-Directory `
| Select-Object -ExpandProperty "FullName"
} else {
# Search paths in $PATH for Python interpreters.
$all_paths = $env:PATH -split ";"
}

# Find Python interpreters.
$paths = @()
foreach ($path in $all_paths) {
# Only consider interpreters in $RUNNER_TOOL_CACHE.
if ($path.StartsWith($env:RUNNER_TOOL_CACHE)) {
if (Test-Path "$path\python.exe") {
$paths += $path
}
}
}

# Sort the paths, ensure each path is unique,
# and create the output result.
$result = (
$paths `
| Sort-Object `
| Get-Unique
) -join ";"

# Output path information.
Write-Output "python-paths=$result"
61 changes: 61 additions & 0 deletions finder.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
search_runner_tool_cache="$1"

if [ "$search_runner_tool_cache" = "true" ]; then
# Search paths in $RUNNER_TOOL_CACHE for Python interpreters.
IFS=: read -r -a all_paths <<< "$(
find \
"$RUNNER_TOOL_CACHE/Python" \
"$RUNNER_TOOL_CACHE/PyPy" \
-mindepth 2 \
-maxdepth 2 \
-name 'x86' \
-o \
-name 'x64' \
| tr '\n' ':'
)"
else
# Search paths in $PATH for Python interpreters.
IFS=: read -r -a all_paths <<< "$PATH"
fi

# Find Python interpreters.
paths=()
for path in "${all_paths[@]}"; do
# Only consider interpreters in $RUNNER_TOOL_CACHE.
if [[ "${path/#${RUNNER_TOOL_CACHE}/}" != "${path}" ]]; then
# Check for bin/python first;
# this results in duplicate paths which are later removed.
if [[ -x "${path}/bin/python" ]]; then
paths+=("${path}/bin")
elif [[ -x "${path}/python" ]]; then
paths+=("${path}")
fi
fi
done

# If no paths were found, look for a "python" symlink.
if [[ "${#paths[@]}" -eq 0 ]]; then
if command -v python &> /dev/null; then
path="$(realpath "$(command -v python)")"
echo "${path}" 1>&2
if [[ "${path/#${RUNNER_TOOL_CACHE}}" != "${path}" ]]; then
paths+=("${path%/python}")
fi
fi
fi

# Sort the paths, ensure each path is unique
# and create the output result.
result="$(
echo "${paths[*]}" \
| tr ' ' '\n' \
| sort \
| uniq \
| tr '\n' ':'
)"

# Trim trailing colons.
result="${result%:}"

# Output path information.
echo "python-paths=${result}"

0 comments on commit e982fe3

Please sign in to comment.