Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adapt update-cycle test scripts to work on both Windows and macOS #26

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 38 additions & 22 deletions .github/workflows/test-update-cycle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ on: [push]
jobs:
build:

runs-on: windows-latest
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest]
# for supported versions see https://devguide.python.org/versions/
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

runs-on: ${{ matrix.os }}

defaults:
run:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
shell: pwsh # use PowerShell Core, also on macOS

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -32,51 +39,60 @@ jobs:
run: ruff --output-format=github .
- name: identify powershell version
run: $PSVersionTable # or $PSVersionTable.PSEdition
- name: add src to python path
run: Add-Content -Path $Env:GITHUB_ENV -Value "PYTHONPATH=$Env:PYTHONPATH;.\src"
- run: $Env:PYTHONPATH
# https://docs.github.com/en/actions/learn-github-actions/contexts#runner-context
- name: specify app directories for Windows
if: runner.os == 'Windows'
run: |
# make directories accessible as environment variables in subsequent steps
Add-Content -Path $Env:GITHUB_ENV -Value "MYAPP_INSTALL_DIR=$env:LOCALAPPDATA/Programs/my_app"
Add-Content -Path $Env:GITHUB_ENV -Value "MYAPP_TARGETS_DIR=$env:LOCALAPPDATA/my_app/update_cache/targets"
# add src directory to python path
Add-Content -Path $Env:GITHUB_ENV -Value "PYTHONPATH=$Env:PYTHONPATH;./src"
- name: specify app directories for macOS
if: runner.os == 'macOS'
run: |
# make directories accessible as environment variables in subsequent steps
Add-Content -Path $Env:GITHUB_ENV -Value "MYAPP_INSTALL_DIR=$HOME/Applications/my_app"
Add-Content -Path $Env:GITHUB_ENV -Value "MYAPP_TARGETS_DIR=$HOME/Library/my_app/update_cache/targets"
# add src directory to python path
Add-Content -Path $Env:GITHUB_ENV -Value "PYTHONPATH=$Env:PYTHONPATH:./src"
- name: initialize tufup repository
run: python repo_init.py
- name: create my_app v1.0 bundle using pyinstaller
run: cmd.exe /c .\create_pyinstaller_bundle_win.bat
run: pyinstaller "main.spec" --clean -y --distpath "temp_my_app/dist" --workpath "temp_my_app/build"
- name: add my_app v1.0 to tufup repository
run: python repo_add_bundle.py
- name: mock install my_app v1.0
run: |
$myapp_v1_archive = ".\temp_my_app\repository\targets\my_app-1.0.tar.gz"
$myapp_install_dir = "$env:LOCALAPPDATA\Programs\my_app"
$myapp_targets_dir = "$env:LOCALAPPDATA\my_app\update_cache\targets"
# make install dir accessible as environment variable in subsequent steps
Add-Content -Path $Env:GITHUB_ENV -Value "MYAPP_INSTALL_DIR=$myapp_install_dir"
$myapp_v1_archive = "./temp_my_app/repository/targets/my_app-1.0.tar.gz"
# create install dir and extract archive into it
New-Item -Path $myapp_install_dir -ItemType "directory"
tar -xf $myapp_v1_archive --directory=$myapp_install_dir
dir $myapp_install_dir
New-Item -Path $Env:MYAPP_INSTALL_DIR -ItemType "directory"
tar -xf $myapp_v1_archive --directory=$Env:MYAPP_INSTALL_DIR
dir $Env:MYAPP_INSTALL_DIR
# create targets dir and copy the archive into it (this enables patch updates)
New-Item -Path $myapp_targets_dir -ItemType "directory" -Force
Copy-Item $myapp_v1_archive -Destination $myapp_targets_dir
New-Item -Path $Env:MYAPP_TARGETS_DIR -ItemType "directory" -Force
Copy-Item $myapp_v1_archive -Destination $Env:MYAPP_TARGETS_DIR
- name: mock develop my_app v2.0
shell: python
run: |
import pathlib
settings_path = pathlib.Path('.\src\myapp\settings.py')
settings_path = pathlib.Path('./src/myapp/settings.py')
settings_text = settings_path.read_text().replace('1.0', '2.0')
settings_path.write_text(settings_text)
# - run: cat .\src\myapp\settings.py
- name: create my_app v2.0 bundle using pyinstaller
run: cmd.exe /c .\create_pyinstaller_bundle_win.bat
run: pyinstaller "main.spec" --clean -y --distpath "temp_my_app/dist" --workpath "temp_my_app/build"
- name: add my_app v2.0 to tufup repository
run: python repo_add_bundle.py
- name: run update server and update my_app from v1 to v2
run: |
python -m http.server -d .\temp_my_app\repository &
python -m http.server -d ./temp_my_app/repository &
sleep 5
Invoke-Expression "$Env:MYAPP_INSTALL_DIR\main.exe skip"
Invoke-Expression "$Env:MYAPP_INSTALL_DIR/main skip"
- name: proof of the pudding (i.e. verify that install dir contains my_app v2.0)
run: |
python -m http.server -d .\temp_my_app\repository &
python -m http.server -d ./temp_my_app/repository &
sleep 5
$output = Invoke-Expression "$Env:MYAPP_INSTALL_DIR\main.exe skip"
$output = Invoke-Expression "$Env:MYAPP_INSTALL_DIR/main skip"
$pattern = "my_app 2.0"
if ( $output -match $pattern ) {
Write-Output "success: $pattern found"
Expand Down
46 changes: 30 additions & 16 deletions test_update_cycle.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
# but workflow failures are easier to debug when broken down into
# separate steps

# requires Powershell 6 or higher

# exit on cmdlet errors
$ErrorActionPreference = "stop"

Expand All @@ -41,11 +43,21 @@ $enable_patch_update = $true

# directories where this script creates files and deletes files (note these must end
# with $app_name and must be consistent with myapp.settings and repo_settings)
$repo_dir = $PSScriptRoot
$temp_dir = "$repo_dir\temp_$app_name"
$app_install_dir = "$env:LOCALAPPDATA\Programs\$app_name"
$app_data_dir = "$env:LOCALAPPDATA\$app_name"
$targets_dir = "$app_data_dir\update_cache\targets"
$repo_dir = "$PSScriptRoot"
$temp_dir = Join-Path "$repo_dir" "temp_$app_name"
if ( $IsWindows ) {
$app_install_dir = Join-Path "$env:LOCALAPPDATA" "Programs" "$app_name"
$app_data_dir = Join-Path "$env:LOCALAPPDATA" "$app_name"
$path_separator = ";"
} elseif ( $IsMacOS ) {
$app_install_dir = Join-Path "$HOME" "Applications" "$app_name"
$app_data_dir = Join-Path "$HOME" "Library" "$app_name"
$path_separator = ":"
} else {
Write-Host "unsupported OS" -ForegroundColor red
exit 1
}
$targets_dir = Join-Path "$app_data_dir" "update_cache" "targets"
$all_app_dirs = @($temp_dir, $app_install_dir, $app_data_dir)

function Remove-MyAppDirectory {
Expand All @@ -68,7 +80,7 @@ function Remove-MyApp {
}

function Invoke-PyInstaller {
pyinstaller.exe "$repo_dir\main.spec" --clean -y --distpath "$temp_dir\dist" --workpath "$temp_dir\build"
pyinstaller "$repo_dir/main.spec" --clean -y --distpath "$temp_dir/dist" --workpath "$temp_dir/build"
Assert-ExeSuccess
}

Expand All @@ -86,7 +98,7 @@ New-Item -Path $targets_dir -ItemType "directory" -Force | Out-Null

# this script requires an active python environment, with tufup installed
# (we'll assume there's a venv in the repo_dir)
$venv_path = "$repo_dir\venv\Scripts\activate.ps1"
$venv_path = Join-Path "$repo_dir" "venv" "Scripts" "activate.ps1"
if (Test-Path $venv_path) {
& $venv_path
Write-Host "venv activated" -ForegroundColor green
Expand All @@ -95,11 +107,11 @@ if (Test-Path $venv_path) {
}

# make sure python can find myapp
$Env:PYTHONPATH += ";$repo_dir\src"
$Env:PYTHONPATH += "$path_separator$repo_dir/src"

# - initialize new repository
Write-Host "initializing tuf repository for $app_name" -ForegroundColor green
python "$repo_dir\repo_init.py"
python "$repo_dir/repo_init.py"
Assert-ExeSuccess

# - create my_app v1.0 bundle using pyinstaller
Expand All @@ -108,12 +120,12 @@ Invoke-PyInstaller

# - add my_app v1.0 to tufup repository
Write-Host "adding $app_name v1.0 bundle to repo" -ForegroundColor green
python "$repo_dir\repo_add_bundle.py"
python "$repo_dir/repo_add_bundle.py"
Assert-ExeSuccess

# - mock install my_app v1.0
Write-Host "installing $app_name v1.0 in $app_install_dir" -ForegroundColor green
$myapp_v1_archive = "$temp_dir\repository\targets\$app_name-1.0.tar.gz"
$myapp_v1_archive = Join-Path "$temp_dir" "repository" "targets" "$app_name-1.0.tar.gz"
tar -xf $myapp_v1_archive --directory=$app_install_dir
# put a copy of the archive in the targets dir, to enable patch updates
if ($enable_patch_update) {
Expand All @@ -125,7 +137,7 @@ if ($enable_patch_update) {
# (quick and dirty, this modifies the actual source,
# but the change is rolled back later...)
Write-Host "bumping $app_name version to v2.0 (temporary)" -ForegroundColor green
$settings_path = "$repo_dir\src\myapp\settings.py"
$settings_path = Join-Path "$repo_dir" "src" "myapp" "settings.py"
(Get-Content $settings_path).Replace("1.0", "2.0") | Set-Content $settings_path

# - create my_app v2.0 bundle using pyinstaller
Expand All @@ -134,7 +146,7 @@ Invoke-PyInstaller

# - add my_app v2.0 to tufup repository
Write-Host "adding $app_name v2.0 bundle to repo" -ForegroundColor green
python "$repo_dir\repo_add_bundle.py"
python "$repo_dir/repo_add_bundle.py"
Assert-ExeSuccess

# - roll-back modified source
Expand All @@ -143,7 +155,7 @@ Write-Host "rolling back temporary source modification" -ForegroundColor green

# - start update server
Write-Host "starting update server" -ForegroundColor green
$job = Start-Job -ArgumentList @("$temp_dir\repository") -ScriptBlock {
$job = Start-Job -ArgumentList @("$temp_dir/repository") -ScriptBlock {
param($repository_path)
python -m http.server -d $repository_path
Assert-ExeSuccess
Expand All @@ -152,14 +164,16 @@ sleep 1 # not sure if this is required, but cannot hurt

# - run my_app to update from v1 to v2
Write-Host "running $app_name for update..." -ForegroundColor green
Invoke-Expression "$app_install_dir\main.exe"
& "$app_install_dir\main"
Assert-ExeSuccess

# - run my_app again to verify we now have v2.0
Write-Host "hit enter to proceed, after console has closed:" -ForegroundColor yellow -NoNewLine
Read-Host # no text: we use write host to add color
Write-Host "running $app_name again to verify version" -ForegroundColor green
$output = Invoke-Expression "$app_install_dir\main.exe"
# https://devblogs.microsoft.com/powershell/invoke-expression-considered-harmful/
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.4#call-operator-
$output = & "$app_install_dir/main"
Assert-ExeSuccess

# - stop update server
Expand Down