mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
ci: add E2E for pmg action server-mode (#354)
* ci: add E2E for pmg action server-mode Exercises the safedep/pmg action with server-mode enabled: the action starts the proxy daemon and injects HTTP_PROXY + CA env vars, then bare npm/pip installs are intercepted. Asserts benign installs pass, malicious npm/pip installs are blocked, and 'pmg proxy stop --fail-on-violation' fails the job on the blocks. Scoped via paths to action.yml and the proxy server sources so it only runs when relevant. Complements persistent-proxy-e2e.yml, which covers the branch's proxy internals via raw pmg proxy commands. * ci: extract shared proxy E2E assertions into composite action Both the action server-mode E2E and the persistent-proxy E2E run the same benign/malicious install assertions. Factor them into a local composite action (.github/actions/proxy-e2e-assertions) so the assertions live in one place and both workflows exercise the composite itself. Proxy teardown (pmg proxy stop --fail-on-violation) stays inline in each workflow since the setup/teardown differs per binary-under-test (released binary via the action vs. branch build via make).
This commit is contained in:
@@ -0,0 +1,50 @@
|
|||||||
|
name: Proxy E2E Assertions
|
||||||
|
description: >
|
||||||
|
Shared assertions for a running PMG persistent proxy. Assumes the proxy is
|
||||||
|
already started and HTTP_PROXY + CA env vars are exported into the job env.
|
||||||
|
Runs benign + malicious installs. The caller owns stopping the proxy (e.g.
|
||||||
|
pmg proxy stop --fail-on-violation) since teardown differs per setup.
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Verify proxy env is set
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "HTTP_PROXY=$HTTP_PROXY"
|
||||||
|
test -n "$HTTP_PROXY"
|
||||||
|
|
||||||
|
- name: Benign npm install succeeds
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir benign-test && cd benign-test
|
||||||
|
npm init -y
|
||||||
|
npm install lodash@4.17.21
|
||||||
|
test -d node_modules/lodash
|
||||||
|
cd .. && rm -rf benign-test
|
||||||
|
|
||||||
|
- name: Malicious npm install is blocked
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir mal-npm && cd mal-npm
|
||||||
|
npm init -y
|
||||||
|
# The install MUST fail (proxy blocks it). Assert that, instead of
|
||||||
|
# continue-on-error which would hide a regression where it succeeds.
|
||||||
|
if npm --no-cache --prefer-online install safedep-test-pkg@0.1.3; then
|
||||||
|
echo "ERROR: malicious npm install succeeded but should have been blocked"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "OK: malicious npm install was blocked"
|
||||||
|
cd .. && rm -rf mal-npm
|
||||||
|
|
||||||
|
- name: Malicious pip install is blocked (python3 -m pip)
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
python3 -m venv venv && source venv/bin/activate
|
||||||
|
if python3 -m pip install safedep-test-pkg; then
|
||||||
|
echo "ERROR: malicious pip install succeeded but should have been blocked"
|
||||||
|
deactivate
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "OK: malicious pip install was blocked"
|
||||||
|
deactivate && rm -rf venv
|
||||||
@@ -24,7 +24,6 @@ jobs:
|
|||||||
SAFEDEP_API_KEY: ${{ secrets.SAFEDEP_CLOUD_API_KEY }}
|
SAFEDEP_API_KEY: ${{ secrets.SAFEDEP_CLOUD_API_KEY }}
|
||||||
SAFEDEP_TENANT_ID: ${{ secrets.SAFEDEP_CLOUD_TENANT_DOMAIN}}
|
SAFEDEP_TENANT_ID: ${{ secrets.SAFEDEP_CLOUD_TENANT_DOMAIN}}
|
||||||
PMG_CLOUD_ENABLED: "true"
|
PMG_CLOUD_ENABLED: "true"
|
||||||
PMG_CLOUD_ENDPOINT_ID: github-actions/${{ github.repository }}
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -60,49 +59,13 @@ jobs:
|
|||||||
- name: Inject proxy env
|
- name: Inject proxy env
|
||||||
run: pmg proxy env >> "$GITHUB_ENV"
|
run: pmg proxy env >> "$GITHUB_ENV"
|
||||||
|
|
||||||
- name: Verify proxy env is set
|
- name: Run proxy E2E assertions
|
||||||
run: |
|
uses: ./.github/actions/proxy-e2e-assertions
|
||||||
echo "HTTP_PROXY=$HTTP_PROXY"
|
|
||||||
test -n "$HTTP_PROXY"
|
|
||||||
|
|
||||||
- name: Benign npm install succeeds
|
|
||||||
run: |
|
|
||||||
mkdir benign-test && cd benign-test
|
|
||||||
npm init -y
|
|
||||||
npm install lodash@4.17.21
|
|
||||||
test -d node_modules/lodash
|
|
||||||
cd .. && rm -rf benign-test
|
|
||||||
|
|
||||||
- name: Malicious npm install is blocked
|
|
||||||
run: |
|
|
||||||
mkdir mal-npm && cd mal-npm
|
|
||||||
npm init -y
|
|
||||||
# The install MUST fail (proxy blocks it). Assert that, instead of
|
|
||||||
# continue-on-error which would hide a regression where it succeeds.
|
|
||||||
if npm --no-cache --prefer-online install safedep-test-pkg@0.1.3; then
|
|
||||||
echo "ERROR: malicious npm install succeeded but should have been blocked"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "OK: malicious npm install was blocked"
|
|
||||||
cd .. && rm -rf mal-npm
|
|
||||||
|
|
||||||
- name: Malicious pip install is blocked (python3 -m pip)
|
|
||||||
run: |
|
|
||||||
python3 -m venv venv && source venv/bin/activate
|
|
||||||
if python3 -m pip install safedep-test-pkg; then
|
|
||||||
echo "ERROR: malicious pip install succeeded but should have been blocked"
|
|
||||||
deactivate
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "OK: malicious pip install was blocked"
|
|
||||||
deactivate && rm -rf venv
|
|
||||||
|
|
||||||
- name: Stop proxy and verify it fails on the blocks
|
- name: Stop proxy and verify it fails on the blocks
|
||||||
if: always()
|
if: always()
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
# We blocked packages above, so --fail-on-violation must exit non-zero.
|
|
||||||
# Assert that (a green test means the gate works), and always run so the
|
|
||||||
# daemon is stopped even if an earlier step failed.
|
|
||||||
if pmg proxy stop --fail-on-violation; then
|
if pmg proxy stop --fail-on-violation; then
|
||||||
echo "ERROR: stop should have exited non-zero (packages were blocked)"
|
echo "ERROR: stop should have exited non-zero (packages were blocked)"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# .github/workflows/pmg-action-e2e.yml
|
||||||
|
name: PMG Server Action E2E
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- "action.yml"
|
||||||
|
- "cmd/proxy/**"
|
||||||
|
- "internal/proxyserver/**"
|
||||||
|
- "internal/flows/cert.go"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pmg-action-server-e2e:
|
||||||
|
name: PMG Server Action E2E
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
steps:
|
||||||
|
- name: Checkout Source
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
|
with:
|
||||||
|
node-version: "24"
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
|
||||||
|
with:
|
||||||
|
python-version: "3.11"
|
||||||
|
|
||||||
|
- name: Run PMG action in server mode
|
||||||
|
uses: ./ # action.yml
|
||||||
|
with:
|
||||||
|
server-mode: true
|
||||||
|
api-key: ${{ secrets.SAFEDEP_CLOUD_API_KEY }}
|
||||||
|
tenant-id: ${{ secrets.SAFEDEP_CLOUD_TENANT_DOMAIN }}
|
||||||
|
|
||||||
|
- name: Run proxy E2E assertions
|
||||||
|
uses: ./.github/actions/proxy-e2e-assertions
|
||||||
|
|
||||||
|
- name: Stop proxy and verify it fails on the blocks
|
||||||
|
if: always()
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if pmg proxy stop --fail-on-violation; then
|
||||||
|
echo "ERROR: stop should have exited non-zero (packages were blocked)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "OK: stop correctly failed on the policy violation"
|
||||||
Reference in New Issue
Block a user