diff --git a/.github/workflows/ci.action.yml b/.github/workflows/ci.action.yml index 6d2ef20..a659054 100644 --- a/.github/workflows/ci.action.yml +++ b/.github/workflows/ci.action.yml @@ -94,3 +94,32 @@ jobs: - run: git clean -xfd - uses: ./ - run: pkgx --version + - uses: actions/upload-artifact@v4 + with: + path: | + ./action.js + ./action.yml + name: action + + linuxen: + needs: dist + continue-on-error: true + runs-on: ubuntu-latest + strategy: + matrix: + container: + - debian:buster-slim + - debian:bullseye-slim + - debian:bookworm-slim + - archlinux:latest + - ubuntu:focal + - ubuntu:jammy + - ubuntu:noble + - fedora:latest + container: ${{ matrix.container }} + steps: + - uses: actions/download-artifact@v4 + with: + name: action + - uses: ./ + - run: pkgx node -e 'console.log(1)' diff --git a/.github/workflows/ci.installer.yml b/.github/workflows/ci.installer.yml index 73af341..25f097b 100644 --- a/.github/workflows/ci.installer.yml +++ b/.github/workflows/ci.installer.yml @@ -180,7 +180,7 @@ jobs: env: PATH: ${{ github.workspace }}/bin:/usr/bin:/bin - - run: pkgx deno eval 'console.log(1)' + - run: pkgx node -e 'console.log(1)' windows: runs-on: windows-latest @@ -188,7 +188,7 @@ jobs: - uses: actions/checkout@v4 - run: .\\installer.ps1 - run: | - $env:Path += ";C:\Program Files\pkgx" + $env:Path += ";$env:LOCALAPPDATA\pkgx" pkgx +zlib.net upgrades: diff --git a/README.md b/README.md index 8659a3a..bd6b105 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,16 @@ just slow things down. ## Version History +* `v4` defaults to `pkgx`^2, uses node^20 and doesn’t install any pre-reqs on Linux† * `v3` defaults to `pkgx`^2 and uses node^20 * `v2` defaults to `pkgx`^1 and uses node^20 * `v1` defaults to `pkgx`@latest and uses node^16 * `v0` should not be used +> † `pkgx` requires glibc>=2.28, libgcc, libstdc++ and libatomic. Generally +> images come installed with these. If you are building binaries you may need +> the `-dev` versions of these packages also. +   diff --git a/action.js b/action.js index b4a09b8..8900246 100644 --- a/action.js +++ b/action.js @@ -1,4 +1,5 @@ const { execSync } = require('child_process'); +const unzipper = require('unzipper'); const semver = require('semver'); const https = require('https'); const path = require('path'); @@ -27,6 +28,7 @@ function platform_key() { } function downloadAndExtract(url, destination, strip) { + return new Promise((resolve, reject) => { https.get(url, (response) => { if (response.statusCode !== 200) { @@ -34,16 +36,23 @@ function downloadAndExtract(url, destination, strip) { return; } - console.log(`extracting tarball…`); - - const tar_stream = tar.x({ cwd: destination, strip }); + console.log(`extracting pkgx archive…`); - response - .pipe(tar_stream) // Extract directly to destination - .on('finish', resolve) - .on('error', reject); - - tar_stream.on('error', reject); + if (platform_key().startsWith('windows')) { + const unzip_stream = unzipper.Extract({ path: destination }); + response + .pipe(unzip_stream) + .promise() + .then(resolve, reject); + unzip_stream.on('error', reject); + } else { + const tar_stream = tar.x({ cwd: destination, strip }); + response + .pipe(tar_stream) + .on('finish', resolve) + .on('error', reject); + tar_stream.on('error', reject); + } }).on('error', reject); }); @@ -93,7 +102,7 @@ async function install_pkgx() { if (platform_key().startsWith('windows')) { // not yet versioned strip = 0; - return 'https://pkgx.sh/Windows/x86_64.tgz'; + return 'https://pkgx.sh/Windows/x86_64.zip'; } let url = `https://dist.pkgx.dev/pkgx.sh/${platform_key()}/versions.txt`; @@ -139,13 +148,6 @@ async function install_pkgx() { fs.appendFileSync(process.env["GITHUB_ENV"], `PKGX_DIR=${process.env.INPUT_PKGX_DIR}\n`); } - if (os.platform() == 'linux') { - console.log(`::group::installing pre-requisites`); - const installer_script_path = path.join(path.dirname(__filename), "installer.sh"); - execSync(installer_script_path, {env: {PKGX_INSTALL_PREREQS: '1', ...process.env}}); - console.log(`::endgroup::`); - } - if (process.env['INPUT_+']) { console.log(`::group::installing pkgx input packages`); let args = process.env['INPUT_+'].split(' '); diff --git a/installer.ps1 b/installer.ps1 index 15466b8..c25b3f4 100644 --- a/installer.ps1 +++ b/installer.ps1 @@ -2,8 +2,8 @@ $ErrorActionPreference = "Stop" -# Determine install location -$installDir = "$env:ProgramFiles\pkgx" +# Determine install location for the current user +$installDir = "$env:LOCALAPPDATA\pkgx" # Create directory if it doesn't exist if (!(Test-Path $installDir)) { @@ -17,10 +17,10 @@ Invoke-WebRequest -Uri $zipUrl -OutFile $zipFile Expand-Archive -Path $zipFile -DestinationPath $installDir -Force Remove-Item $zipFile -# Ensure PATH is updated -$envPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine) +# Ensure user's PATH is updated +$envPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) if ($envPath -notlike "*$installDir*") { - [System.Environment]::SetEnvironmentVariable("Path", "$envPath;$installDir", [System.EnvironmentVariableTarget]::Machine) + [System.Environment]::SetEnvironmentVariable("Path", "$envPath;$installDir", [System.EnvironmentVariableTarget]::User) } Write-Host "pkgx installed successfully! Restart your terminal to use it." diff --git a/installer.sh b/installer.sh index a6fe005..01940dc 100755 --- a/installer.sh +++ b/installer.sh @@ -5,7 +5,6 @@ set -e _main() { if _should_install_pkgx; then _install_pkgx "$@" - _install_pre_reqs elif [ $# -eq 0 ]; then echo /usr/local/bin/"$(pkgx --version) already installed" >&2 echo /usr/local/bin/"$(pkgm --version) already installed" >&2 @@ -47,70 +46,6 @@ _is_ci() { [ -n "$CI" ] && [ $CI != 0 ] } -_install_pre_reqs() { - if _is_ci; then - apt() { - # we should use apt-get not apt in CI - # weird shit ref: https://askubuntu.com/a/668859 - export DEBIAN_FRONTEND=noninteractive - cmd=$1 - shift - $SUDO apt-get $cmd --yes -qq -o=Dpkg::Use-Pty=0 $@ - } - else - apt() { - case "$1" in - update) - echo "ensure you have the \`pkgx\` pre-requisites installed:" >&2 - ;; - install) - echo " apt-get" "$@" >&2 - ;; - esac - } - yum() { - echo "ensure you have the \`pkgx\` pre-requisites installed:" >&2 - echo " yum" "$@" >&2 - } - pacman() { - echo "ensure you have the \`pkgx\` pre-requisites installed:" >&2 - echo " pacman" "$@" >&2 - } - fi - - if test -f /etc/debian_version; then - apt update - - # minimal but required or networking doesn’t work - # https://packages.debian.org/buster/all/netbase/filelist - A="netbase" - - # difficult to pkg in our opinion - B=libudev-dev - - # ca-certs needed until we bundle our own root cert - C=ca-certificates - - case $(cat /etc/debian_version) in - jessie/sid|8.*|stretch/sid|9.*) - apt install libc-dev libstdc++-4.8-dev libgcc-4.7-dev $A $B $C;; - buster/sid|10.*) - apt install libc-dev libstdc++-8-dev libgcc-8-dev $A $B $C;; - bullseye/sid|11.*) - apt install libc-dev libstdc++-10-dev libgcc-9-dev $A $B $C;; - bookworm/sid|12.*|*) - apt install libc-dev libstdc++-11-dev libgcc-11-dev $A $B $C;; - esac - elif test -f /etc/fedora-release; then - $SUDO yum --assumeyes install libatomic - elif test -f /etc/arch-release; then - # installing gcc isn't my favorite thing, but even clang depends on it - # on archlinux. it provides libgcc. since we use it for testing, the risk - # to our builds is very low. - $SUDO pacman --noconfirm -Sy gcc libatomic_ops libxcrypt-compat - fi -} - _install_pkgx() { if _is_ci; then progress="--no-progress-meter" @@ -122,23 +57,27 @@ _install_pkgx() { if [ $# -eq 0 ]; then if [ -f /usr/local/bin/pkgx ]; then - echo "upgrading: /usr/local/bin/pkg[xm]" >&2 + echo "upgrading: /usr/local/bin/pkgx" >&2 else - echo "installing: /usr/local/bin/pkg[xm]" >&2 + echo "installing: /usr/local/bin/pkgx" >&2 fi # using a named pipe to prevent curl progress output trumping the sudo password prompt pipe="$tmpdir/pipe" mkfifo "$pipe" - curl --silent --fail --proto '=https' -o "$tmpdir/pkgm" \ - https://pkgxdev.github.io/pkgm/pkgm.ts - curl $progress --fail --proto '=https' "https://pkgx.sh/$(uname)/$(uname -m)".tgz > "$pipe" & $SUDO sh -c " mkdir -p /usr/local/bin tar xz --directory /usr/local/bin < '$pipe' - install -m 755 "$tmpdir/pkgm" /usr/local/bin + if [ ! -f /usr/local/bin/pkgm ]; then + echo '#!/usr/bin/env -S pkgx -q! pkgm' > /usr/local/bin/pkgm + chmod +x /usr/local/bin/pkgm + fi + if [ ! -f /usr/local/bin/mash ]; then + echo '#!/usr/bin/env -S pkgx -q! mash' > /usr/local/bin/mash + chmod +x /usr/local/bin/mash + fi " & wait @@ -151,7 +90,8 @@ _install_pkgx() { # tell the user what version we just installed pkgx --version - pkgm --version + pkgx pkgm@latest --version + pkgx mash@latest --version else curl $progress --fail --proto '=https' \ @@ -201,8 +141,4 @@ _should_install_pkgx() { } _prep -if [ "$PKGX_INSTALL_PREREQS" != 1 ]; then - _main "$@" -else - _install_pre_reqs -fi +_main "$@" diff --git a/package-lock.json b/package-lock.json index e78b673..5db4f51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,8 @@ "": { "dependencies": { "semver": "^7.7.1", - "tar": "^7.4.3" + "tar": "^7.4.3", + "unzipper": "^0.12.3" } }, "node_modules/@isaacs/cliui": { @@ -78,6 +79,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -114,6 +121,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -128,6 +141,15 @@ "node": ">= 8" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -168,6 +190,20 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -188,6 +224,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -197,6 +245,12 @@ "node": ">=8" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -217,6 +271,18 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -275,6 +341,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "license": "MIT" + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -306,6 +378,27 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, "node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", @@ -321,6 +414,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/semver": { "version": "7.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", @@ -354,6 +453,15 @@ "node": ">=8" } }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -467,6 +575,34 @@ "node": ">=18" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unzipper": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.3.tgz", + "integrity": "sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA==", + "license": "MIT", + "dependencies": { + "bluebird": "~3.7.2", + "duplexer2": "~0.1.4", + "fs-extra": "^11.2.0", + "graceful-fs": "^4.2.2", + "node-int64": "^0.4.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 1c4761c..6deb251 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "dependencies": { "semver": "^7.7.1", - "tar": "^7.4.3" + "tar": "^7.4.3", + "unzipper": "^0.12.3" }, "scripts": { - "dist": "npx esbuild ./action.js --bundle --platform=node --target=node20 --outfile=./action.js --allow-overwrite --minify" + "dist": "npx esbuild ./action.js --bundle --platform=node --target=node20 --outfile=./action.js --allow-overwrite --minify --external:@aws-sdk/client-s3" } }