diff --git a/.github/actions/install-win-store-python/action.yml b/.github/actions/install-win-store-python/action.yml index 428ab080..26ddd296 100644 --- a/.github/actions/install-win-store-python/action.yml +++ b/.github/actions/install-win-store-python/action.yml @@ -11,40 +11,69 @@ runs: using: composite steps: - - name: Python Constants + - name: Python Definitions id: python shell: powershell run: | - # Constants for all Python versions - echo "exe-dir=$(Join-Path -Path $env:LOCALAPPDATA -ChildPath \Microsoft\WindowsApps\)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - - # Constants for each Python version - if ( "${{ inputs.python-version }}" -eq "3.11" ) { - echo "version=3.11" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - echo "store-url=https://apps.microsoft.com/store/detail/python-311/9NRWMJP3717K" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - echo "scripts-dir=$(Join-Path -Path $env:LOCALAPPDATA -ChildPath '\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts')" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + switch ( "${{ inputs.python-version }}" ) { + "3.11" { + $StoreURL = "https://apps.microsoft.com/store/detail/python-311/9NRWMJP3717K" + $ExeDir = Join-Path "$env:LOCALAPPDATA" "\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0" + $ScriptsDir = Join-Path "$env:LOCALAPPDATA" "\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts" + } + "3.10" { + $StoreURL = "https://apps.microsoft.com/store/detail/python-310/9PJPW5LDXLZ5" + $ExeDir = Join-Path "$env:LOCALAPPDATA" "\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0" + $ScriptsDir = Join-Path "$env:LOCALAPPDATA" "Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\Scripts" + } + "3.9" { + $StoreURL = "https://apps.microsoft.com/store/detail/python-39/9P7QFQMJRFP7" + $ExeDir = Join-Path "$env:LOCALAPPDATA" "\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0" + $ScriptsDir = Join-Path "$env:LOCALAPPDATA" "Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\Scripts" + } + "3.8" { + $StoreURL = "https://apps.microsoft.com/store/detail/python-38/9MSSZTT1N39L" + $ExeDir = Join-Path "$env:LOCALAPPDATA" "\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0" + $ScriptsDir = Join-Path "$env:LOCALAPPDATA" "\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\Scripts" + } + default { + echo " >>> Python ${{ inputs.python-version }} is not supported <<<" + exit 1 + } } + echo "version=${{ inputs.python-version }}" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + echo "store-url=$StoreURL" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + echo "exe-dir=$ExeDir" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + echo "scripts-dir=$ScriptsDir" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + echo "appx-path=$(Join-Path "$env:TEMP" python-${{ inputs.python-version }}.appx)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + - name: Cache Python AppxBundle uses: actions/cache@v3.2.3 with: - path: python-${{ steps.python.outputs.version }}.appx + path: ${{ steps.python.outputs.appx-path }} key: python-${{ steps.python.outputs.version }}-appx-bundle - name: Install Windows Store Python ${{ steps.python.outputs.version }} shell: powershell run: | - if (-not (Test-Path -Path python-${{ steps.python.outputs.version }}.appx -PathType Leaf)) { + if (-not (Test-Path -Path "${{ steps.python.outputs.appx-path }}" -PathType Leaf)) { + # The Appx download URL must be resolved each time since the URL expires after a few hours echo "Downloading Python ${{ steps.python.outputs.version }}..." $WebResponse = Invoke-WebRequest -UseBasicParsing -Method 'POST' -Uri 'https://store.rg-adguard.net/api/GetFiles' -Body "type=url&url=${{ steps.python.outputs.store-url }}&ring=Retail" -ContentType 'application/x-www-form-urlencoded' $DownloadURL = ($WebResponse.Links | where {$_ -like '*.msix*'} | where {$_ -like '*_neutral_*' -or $_ -like "*_"+$env:PROCESSOR_ARCHITECTURE.Replace("AMD","X").Replace("IA","X")+"_*"} | Select-String -Pattern '(?<=a href=").+(?=" r)').matches.value - echo "Downloading from $DownloadURL" - Invoke-WebRequest -Uri $DownloadURL -UseBasicParsing -OutFile python-${{ steps.python.outputs.version }}.appx + echo "Appx download URL: $DownloadURL" + if (($DownloadURL -eq $null) -or ((([uri]$DownloadURL).Host.split('.')[-2..-1] -join '.') -ne "microsoft.com")) { + echo $WebResponse + echo " >>> Download URL must resolve to microsoft.com. Aborting. <<< " + exit 1 + } + Invoke-WebRequest -Uri $DownloadURL -UseBasicParsing -OutFile ${{ steps.python.outputs.appx-path }} } echo "Installing Python ${{ steps.python.outputs.version }}..." - Add-AppxPackage -Path .\python-${{ steps.python.outputs.version }}.appx + Add-AppxPackage -Path ${{ steps.python.outputs.appx-path }} echo "Updating `$PATH..." echo "${{ steps.python.outputs.exe-dir }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append diff --git a/.github/workflows/test-install-win-store-python.yml b/.github/workflows/test-install-win-store-python.yml new file mode 100644 index 00000000..e39b1591 --- /dev/null +++ b/.github/workflows/test-install-win-store-python.yml @@ -0,0 +1,36 @@ +name: Test Action install-win-store-python + +on: + pull_request: + push: + branches: + - main + +jobs: + test-install-win-store-python: + name: Test Win Store Python + runs-on: windows-latest + timeout-minutes: 30 + strategy: + matrix: + python-version: [ "3.8", "3.9", "3.10", "3.11" ] + steps: + - uses: actions/checkout@v3 + - name: Install Windows Store Python + uses: ./.github/actions/install-win-store-python + with: + python-version: ${{ matrix.python-version }} + - name: Test Windows Store Python Install + run: | + $PythonExeSubDir = "\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.${{ matrix.python-version }}_qbz5n2kfra8p0\python.exe" + $ExpectedPythonPath = Join-Path "$env:LOCALAPPDATA" "$PythonExeSubDir" + if ( "$((Get-Command python).Path)" -ne "$ExpectedPythonPath" ) { + echo "Python is at $((Get-Command python).Path)" + echo "Python was expected at $ExpectedPythonPath" + exit 1 + } + if ( "$(python -V)" -cnotlike "Python ${{ matrix.python-version }}*" ) { + echo "Found $(python -V)" + echo "Expected Python ${{ matrix.python-version }}" + exit 1 + } diff --git a/.gitignore b/.gitignore index 3f07fd0d..4c405c72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ venv .envrc - +.idea