Skip to content

feat(windows): scaffolding pass for Windows support #326

feat(windows): scaffolding pass for Windows support

feat(windows): scaffolding pass for Windows support #326

Workflow file for this run

name: ci
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: denolib/setup-deno@v2
with:
deno-version: v2.x
- run: deno fmt --check .
- run: deno lint .
- run: deno check ./pkgm.ts
#TODO test on linux! we are currently broken due to rpath issues
# https://github.com/pkgxdev/pkgm/pull/30#issuecomment-2678957666
test:
continue-on-error: true
strategy:
matrix:
os:
- macos-latest
- ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: pkgxdev/setup@v4
- run: ./pkgm.ts i git
- run: ~/.local/bin/git --version
- run: "! test -f /usr/local/bin/git"
- run: ./pkgm.ts ls | grep .local/pkgs/git-scm.org
- run: ./pkgm.ts rm git
- run: test ! -f ~/.local/bin/git
- run: ./pkgm.ts i pkgx.sh/brewkit
- run: ~/.local/bin/bk --help
# check repeats work
- run: rm ~/.local/bin/bk
- run: test ! -f /usr/local/bin/bk
- run: ./pkgm.ts i pkgx.sh/brewkit
- run: ~/.local/bin/bk --help
- run: ./pkgm.ts i gum
- run: ~/.local/bin/gum --version
# test a thing with deps
# https://github.com/pkgxdev/pkgm/issues/24
- run: ./pkgm.ts i curl
- run: ~/.local/bin/curl -L pkgx.sh
- run: ./pkgm.ts shim semverator
- run: ~/.local/bin/semverator validate 1.0.0
# tests shims do not shim deps
- run: ./pkgm.ts shim node@20
- run: test ! -d ~/.local/bin/openssl
- run: if [[ $(~/.local/bin/node --version) != v20* ]]; then false; fi
- run: ./pkgm.ts i hyperfine@1.18
- run: ./pkgm.ts outdated | grep hyperfine
- run: if pkgx semverator satisfies '>=1.19' "$(hyperfine --version | cut -f 2 -d ' ')"; then false; fi
- run: ./pkgm.ts update
- run: pkgx semverator satisfies '>=1.19' "$(hyperfine --version | cut -f 2 -d ' ')"
# TODO pending: https://github.com/pkgxdev/pantry/issues/8487
# - run: ./pkgm.ts i xpra.org # https://github.com/pkgxdev/pkgm/issues/13
# - run: ls -la /usr/local/pkgs/xpra.org/v6.2.3/venv/bin
# - run: xpra --version
# verifies that libpkgx is creating the pantry at the right place
# Refs: https://github.com/pkgxdev/pkgm/issues/59
- run: |
./pkgm.ts i semverator
if test -d /tmp/foo/pkgx; then
test $(uname) = Linux
else
test $(uname) = Darwin
fi
env:
XDG_DATA_HOME: /tmp/foo
- run: |
set -x
sudo ./pkgm.ts i node@22 dev
[[ $(node --version) = v22* ]] || exit 2
mkdir foo
cd foo
echo "dependencies: node@20" > pkgx.yaml
mkdir -p /tmp/bar/pkgx/dev$PWD/
touch /tmp/bar/pkgx/dev$PWD/dev.pkgx.activated # `dev .` doesn’t work in CI (fix in dev^2)
[[ $(node --version) = v20* ]] || exit 3
env:
XDG_DATA_HOME: /tmp/bar
# https://github.com/pkgxdev/pkgm/issues/62
- run: |
./pkgm.ts i spotify_player
spotify_player --version
# Scaffolding-pass smoke for the Windows port. Uses an explicit
# `pkgx deno^2.1 run` invocation because the kernel doesn't interpret
# `#!/usr/bin/env -S pkgx …` shebangs on Windows; a `pkgm.cmd` wrapper
# that papers over this belongs in pkgxdev/setup's installer.ps1, not
# here.
#
# End-to-end install can't be exercised yet: a probe of all 842
# top-level prefixes in dist.pkgx.dev (the bucket pkgx pulls from)
# finds zero packages with a `windows/` subdir. pkgm install is
# blocked on upstream shipping Windows artifacts; we test what we
# can — that pkgm runs at all on Windows.
test-windows:
runs-on: windows-latest
defaults:
run:
shell: pwsh
steps:
- uses: actions/checkout@v4
- uses: pkgxdev/setup@v4
- name: smoke - pkgm --version
# Verifies the floor: pkgx.exe is on PATH, deno can run the
# script, libpkgx imports resolve on Windows, parseArgs + the
# version arm exit 0. No filesystem touching yet.
run: |
$denoArgs = @(
'deno^2.1', 'run', '--ext=ts',
'--allow-sys=uid', '--allow-run', '--allow-env',
'--allow-read', '--allow-write', '--allow-ffi',
'--allow-net=dist.pkgx.dev',
'./pkgm.ts', '--version'
)
pkgx @denoArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
- name: smoke - pkgm ls on a fresh runner
# Exercises install_prefix() (now %LOCALAPPDATA%\pkgm on
# Windows) and the ls() candidate-paths branch. Fresh runner
# → no installed pkgs → empty output, exit 0. Catches regressions
# in the path-resolution layer without depending on
# dist.pkgx.dev having Windows builds.
run: |
$denoArgs = @(
'deno^2.1', 'run', '--ext=ts',
'--allow-sys=uid', '--allow-run', '--allow-env',
'--allow-read', '--allow-write', '--allow-ffi',
'--allow-net=dist.pkgx.dev',
'./pkgm.ts', 'ls'
)
pkgx @denoArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
# Validates `sudo pkgm install` behaviour fixed in 2b33f20:
# - privilege drop so pkgx cache stays owned by $SUDO_USER, not root
# - HOME override so the cache lands under the invoking user's tree
# - fallback to running pkgx as root when it lives under /root/.pkgx
# and is therefore unreachable to $SUDO_USER (pkgxdev/pkgm#68)
# Linux-only: the /root/.pkgx scenario doesn't arise on macOS in practice.
sudo-install:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pkgxdev/setup@v4
- name: sudo install drops privileges and overrides HOME
run: |
set -eux
# marker to scope ownership checks to files created by this install
touch /tmp/pkgm-sudo-marker
sudo ./pkgm.ts i hyperfine
test -x /usr/local/bin/hyperfine
# HOME override: pkgx must not have created anything under /root/.pkgx
# during this install. We scope the check to paths newer than the
# marker so a pre-existing /root/.pkgx from the runner image or
# setup action does not cause a false failure.
created_under_root=$(sudo find /root/.pkgx -newer /tmp/pkgm-sudo-marker -print 2>/dev/null || true)
if [ -n "$created_under_root" ]; then
echo "::error::pkgx cached under /root/.pkgx — HOME override failed"
echo "$created_under_root"
exit 1
fi
# Privilege drop: nothing newly created under ~/.pkgx should be
# owned by root. Any root-owned file here means pkgx ran as root
# despite SUDO_USER being set.
owned_by_root=$(sudo find "$HOME/.pkgx" -newer /tmp/pkgm-sudo-marker -user root -print 2>/dev/null || true)
if [ -n "$owned_by_root" ]; then
echo "::error::pkgx cache files created as root under \$HOME/.pkgx:"
echo "$owned_by_root"
exit 1
fi
- name: sudo install falls back when pkgx is unreachable as $SUDO_USER
# Must be last — this step strips pkgx from every location the
# runner user can reach, leaving only /root/.pkgx, which the
# subsequent shebang resolution still needs to walk through sudo.
run: |
set -eux
# Stage pkgx exclusively under /root so that reachable_as() returns
# false for the runner user and no alternative is found.
pkgx_src=$(command -v pkgx)
sudo mkdir -p /root/.pkgx/bin
sudo cp "$pkgx_src" /root/.pkgx/bin/pkgx
# Wipe every alternative the resolver looks for:
# ~/.pkgx/pkgx.sh/v*/bin/pkgx, ~/.local/bin/pkgx, /usr/local/bin/pkgx
rm -rf "$HOME/.pkgx"
sudo rm -f /usr/local/bin/pkgx "$HOME/.local/bin/pkgx"
# Invoke pkgm.ts with the /root pkgx on PATH. `sudo env PATH=...`
# is the canonical way around the default secure_path policy in
# Ubuntu's sudoers.
set +e
out=$(sudo env PATH="/root/.pkgx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ./pkgm.ts i gum 2>&1)
rc=$?
set -e
echo "$out"
# Regression check for pkgxdev/pkgm#68: the install succeeds without
# crashing when only the sudo-only pkgx remains reachable.
test $rc -eq 0
test -x /usr/local/bin/gum