feat: add uvx (uv tool run) package executor #52
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Action E2E | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - action.yml | |
| - docs/github-action.md | |
| - .github/workflows/action-e2e.yml | |
| push: | |
| branches: [main] | |
| paths: | |
| - action.yml | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.ref) || github.run_id }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| permissions: | |
| contents: read | |
| jobs: | |
| default-config: | |
| name: Default config installs and protects | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 24 | |
| - uses: ./ | |
| - name: PATH wiring | |
| run: | | |
| set -e | |
| which pmg | |
| which npm | |
| test "$(command -v npm)" = "$HOME/.pmg/bin/npm" | |
| - name: Install a benign package | |
| run: | | |
| mkdir t && cd t | |
| npm init -y | |
| npm install express@5.2.1 | |
| test -d node_modules/express | |
| - name: Block a known-malicious package | |
| shell: bash | |
| run: | | |
| set -eo pipefail | |
| mkdir m && cd m | |
| npm init -y | |
| set +e | |
| npm --prefer-online --no-cache i safedep-test-pkg@0.1.3 >out.log 2>&1 | |
| code=$? | |
| set -e | |
| cat out.log | |
| if [ "$code" -eq 0 ]; then | |
| echo "::error::Expected install to fail (malicious package), but it succeeded." >&2 | |
| exit 1 | |
| fi | |
| grep -qi "Malicious package blocked" out.log | |
| custom-config-file: | |
| name: config-file input overrides defaults | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 24 | |
| - name: Write custom PMG config | |
| run: | | |
| cat > pmg.yml <<'YAML' | |
| paranoid: true | |
| dependency_cooldown: | |
| enabled: true | |
| days: 365 | |
| YAML | |
| - uses: ./ | |
| with: | |
| config-file: pmg.yml | |
| - name: Verify config staged into PMG config dir | |
| run: | | |
| set -e | |
| dest="${XDG_CONFIG_HOME:-$HOME/.config}/safedep/pmg/config.yml" | |
| test -f "$dest" | |
| grep -q "^paranoid: true" "$dest" | |
| grep -q "days: 365" "$dest" | |
| - name: Verify env doesn't shadow file-based tuning | |
| shell: bash | |
| run: | | |
| # With no explicit "paranoid" input, the action must not export | |
| # PMG_PARANOID — otherwise it would override the staged config. | |
| if [ -n "${PMG_PARANOID:-}" ]; then | |
| echo "::error::PMG_PARANOID leaked into env ($PMG_PARANOID); would shadow config-file" >&2 | |
| exit 1 | |
| fi | |
| sandbox-setup: | |
| name: Sandbox setup (${{ matrix.driver }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| driver: [landlock, bubblewrap] | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 24 | |
| - uses: ./ | |
| with: | |
| sandbox: "true" | |
| sandbox-driver: ${{ matrix.driver }} | |
| - name: Sandbox env vars propagated | |
| shell: bash | |
| run: | | |
| set -e | |
| test "$PMG_SANDBOX_ENABLED" = "true" | |
| test "$PMG_SANDBOX_DRIVER" = "${{ matrix.driver }}" | |
| pmg version | |
| - name: Bubblewrap binary installed when driver=bubblewrap | |
| if: matrix.driver == 'bubblewrap' | |
| run: bwrap --version | |
| - name: AppArmor user-ns restriction relaxed | |
| shell: bash | |
| run: | | |
| # systemctl-stop is best-effort; just confirm the sysctl is now 0 | |
| # so unprivileged user namespaces work for either driver. | |
| v=$(cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns 2>/dev/null || echo "missing") | |
| echo "apparmor_restrict_unprivileged_userns=$v" | |
| test "$v" = "0" -o "$v" = "missing" | |
| non-linux-fail-fast: | |
| name: Action fails fast on non-Linux runners | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Action must exit non-zero | |
| id: run | |
| continue-on-error: true | |
| uses: ./ | |
| - name: Verify it failed | |
| shell: bash | |
| run: | | |
| test "${{ steps.run.outcome }}" = "failure" |