Skip to content

Ci/sudo install tests #321

Ci/sudo install tests

Ci/sudo install tests #321

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
# 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's home
# and is therefore unreachable to $SUDO_USER (pkgxdev/pkgm#68)
# The root-home path differs by OS (/root on Linux, /var/root on macOS);
# we resolve it dynamically via `eval echo ~root` rather than hard-coding.
sudo-install:
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: pkgxdev/setup@v4
- name: sudo install drops privileges and overrides HOME
run: |
set -eux
# marker to scope checks to entries created by this install
touch /tmp/pkgm-sudo-marker
# Plain `sudo` (no -H). This is what a typical user types. On
# macOS, sudoers keeps HOME in env_keep so the shebang's outer
# pkgx runs as root inside $SUDO_USER's tree and pollutes
# $HOME/.pkgx with root-owned dirs. pkgm.ts's
# reclaim_pkgx_cache_for() chowns those back to $SUDO_USER
# before dropping privileges so the inner pkgx can write.
sudo ./pkgm.ts i hyperfine
test -x /usr/local/bin/hyperfine
# HOME override + privilege drop are validated via the pkg cache
# under $HOME/.pkgx. We deliberately do NOT assert that
# /root/.pkgx is empty: the shebang's `pkgx --quiet deno^2.1 run …`
# runs as root before any pkgm.ts code executes, and that outer
# pkgx caches under $HOME/.pkgx which resolves to /root/.pkgx
# under sudo. That cache is unavoidable and unrelated to whether
# pkgm's *inner* pkgx call dropped privileges.
#
# We check for newly created entries (directories specifically),
# not files: tar -x preserves the archive's original mtimes on
# extracted files, so file mtimes are typically *older* than the
# marker. Directories are created fresh by `mkdir` during
# extraction and reliably have a current mtime.
new_dirs=$(sudo find "$HOME/.pkgx" -newer /tmp/pkgm-sudo-marker -type d -print 2>/dev/null | head -1 || true)
if [ -z "$new_dirs" ]; then
echo "::error::no new directories under \$HOME/.pkgx — inner pkgx did not cache to invoking user's tree"
exit 1
fi
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 entries created as root under \$HOME/.pkgx — privilege drop failed:"
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's private pkgx, which
# the subsequent shebang resolution still needs to walk through sudo.
run: |
set -eux
# Resolve root's home portably: /root on Linux, /var/root on macOS.
# Hard-coding /root would fail on macOS because the system volume
# is read-only and `sudo mkdir /root` can't create a new top-level
# dir without /etc/synthetic.conf.
root_home=$(eval echo ~root)
# Stage pkgx exclusively under root's home so that reachable_as()
# returns false for the runner user and no alternative is found.
pkgx_src=$(command -v pkgx)
sudo mkdir -p "$root_home/.pkgx/bin"
sudo cp "$pkgx_src" "$root_home/.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 staged pkgx on PATH. `sudo env PATH=...`
# is the canonical way around the default secure_path policy in
# Ubuntu's sudoers; macOS sudo respects the explicit env too.
set +e
out=$(sudo env PATH="$root_home/.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