Skip to content

FIX HTTP targets store decoded response text and JSON keys may contain digits or hyphens #8095

FIX HTTP targets store decoded response text and JSON keys may contain digits or hyphens

FIX HTTP targets store decoded response text and JSON keys may contain digits or hyphens #8095

Workflow file for this run

# Tests Docker image builds for devcontainer and production
name: docker_build
on:
push:
branches:
- "main"
- "releases/v*"
pull_request:
branches:
- "main"
- "releases/**"
merge_group:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
# Stage 1: Build devcontainer base image
build-devcontainer:
name: Build Devcontainer
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Build devcontainer image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .devcontainer
file: .devcontainer/Dockerfile
push: false
tags: pyrit-devcontainer:latest
load: true
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Save devcontainer image
run: docker save pyrit-devcontainer:latest | gzip > devcontainer.tar.gz
- name: Upload devcontainer artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: devcontainer-image
path: devcontainer.tar.gz
retention-days: 1
# Stage 2: Build production images (parallel)
build-production-local:
name: Build Production (local)
runs-on: ubuntu-latest
needs: build-devcontainer
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Download devcontainer image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: devcontainer-image
- name: Load devcontainer image
run: gunzip -c devcontainer.tar.gz | docker load
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
with:
driver: docker
- name: Build production image (local)
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: docker/Dockerfile
push: false
tags: pyrit:local-test
load: true
build-args: |
BASE_IMAGE=pyrit-devcontainer:latest
PYRIT_SOURCE=local
- name: Save production image
run: docker save pyrit:local-test | gzip > local.tar.gz
- name: Upload production artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: production-local-image
path: local.tar.gz
retention-days: 1
build-production-pypi:
name: Build Production (PyPI)
runs-on: ubuntu-latest
needs: build-devcontainer
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Get latest PyRIT version from PyPI
id: pypi-version
run: |
VERSION=$(pip index versions pyrit 2>/dev/null | head -1 | grep -oP '\(\K[^)]+' || echo "0.10.0")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Latest PyRIT version on PyPI: $VERSION"
- name: Download devcontainer image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: devcontainer-image
- name: Load devcontainer image
run: gunzip -c devcontainer.tar.gz | docker load
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
with:
driver: docker
- name: Build production image (PyPI)
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: docker/Dockerfile
push: false
tags: pyrit:pypi-test
load: true
build-args: |
BASE_IMAGE=pyrit-devcontainer:latest
PYRIT_SOURCE=pypi
PYRIT_VERSION=${{ steps.pypi-version.outputs.version }}
- name: Save production image
run: docker save pyrit:pypi-test | gzip > pypi.tar.gz
- name: Upload production artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: production-pypi-image
path: pypi.tar.gz
retention-days: 1
# Stage 3: Test production images (parallel)
test-local-import:
name: Test Import (local)
runs-on: ubuntu-latest
needs: build-production-local
permissions:
contents: read
steps:
- name: Download production image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: production-local-image
- name: Load production image
run: gunzip -c local.tar.gz | docker load
- name: Test PyRIT import
run: |
docker run --rm --entrypoint /opt/venv/bin/python pyrit:local-test -c "import pyrit; print(f'PyRIT version: {pyrit.__version__}')"
test-local-gui:
name: Test GUI (local)
runs-on: ubuntu-latest
needs: build-production-local
permissions:
contents: read
steps:
- name: Download production image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: production-local-image
- name: Load production image
run: gunzip -c local.tar.gz | docker load
- name: Test GUI mode
run: |
docker run -d --name pyrit-gui-test -e PYRIT_MODE=gui -p 8000:8000 pyrit:local-test
echo "Waiting for GUI to start..."
sleep 15
if ! docker ps | grep -q pyrit-gui-test; then
echo "Container not running! Logs:"
docker logs pyrit-gui-test
exit 1
fi
echo "Testing API health endpoint..."
curl -sf http://localhost:8000/api/health || (echo "Health endpoint failed" && docker logs pyrit-gui-test && exit 1)
echo "Testing frontend is served..."
RESPONSE=$(curl -s http://localhost:8000/)
echo "$RESPONSE" | head -5
echo "$RESPONSE" | grep -iq '<!doctype html>' || (echo "Frontend not served" && docker logs pyrit-gui-test && exit 1)
echo "✅ GUI mode tests passed"
docker stop pyrit-gui-test && docker rm pyrit-gui-test
test-local-jupyter:
name: Test Jupyter (local)
runs-on: ubuntu-latest
needs: build-production-local
permissions:
contents: read
steps:
- name: Download production image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: production-local-image
- name: Load production image
run: gunzip -c local.tar.gz | docker load
- name: Test Jupyter mode
run: |
docker run -d --name pyrit-jupyter-test -e PYRIT_MODE=jupyter -p 8888:8888 pyrit:local-test
echo "Waiting for Jupyter to start..."
sleep 20
if ! docker ps | grep -q pyrit-jupyter-test; then
echo "Container not running! Logs:"
docker logs pyrit-jupyter-test
exit 1
fi
echo "Testing Jupyter responds..."
curl -sf http://localhost:8888/api || (echo "Jupyter API failed" && docker logs pyrit-jupyter-test && exit 1)
echo "✅ Jupyter mode tests passed"
docker stop pyrit-jupyter-test && docker rm pyrit-jupyter-test
test-pypi-import:
name: Test Import (PyPI)
runs-on: ubuntu-latest
needs: build-production-pypi
permissions:
contents: read
steps:
- name: Download production image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: production-pypi-image
- name: Load production image
run: gunzip -c pypi.tar.gz | docker load
- name: Test PyRIT import
run: |
docker run --rm --entrypoint /opt/venv/bin/python pyrit:pypi-test -c "import pyrit; print(f'PyRIT version: {pyrit.__version__}')"
test-pypi-gui:
name: Test GUI (PyPI)
runs-on: ubuntu-latest
needs: build-production-pypi
permissions:
contents: read
steps:
- name: Download production image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: production-pypi-image
- name: Load production image
run: gunzip -c pypi.tar.gz | docker load
- name: Test GUI mode
run: |
docker run -d --name pyrit-gui-pypi -e PYRIT_MODE=gui -p 8000:8000 pyrit:pypi-test
echo "Waiting for GUI to start..."
sleep 15
if ! docker ps | grep -q pyrit-gui-pypi; then
echo "Container not running! Logs:"
docker logs pyrit-gui-pypi
exit 1
fi
curl -sf http://localhost:8000/api/health || (echo "Health endpoint failed" && docker logs pyrit-gui-pypi && exit 1)
RESPONSE=$(curl -s http://localhost:8000/)
echo "$RESPONSE" | head -5
echo "$RESPONSE" | grep -iq '<!doctype html>' || (echo "Frontend not served" && docker logs pyrit-gui-pypi && exit 1)
echo "✅ GUI mode tests passed (PyPI)"
docker stop pyrit-gui-pypi && docker rm pyrit-gui-pypi
test-pypi-jupyter:
name: Test Jupyter (PyPI)
runs-on: ubuntu-latest
needs: build-production-pypi
permissions:
contents: read
steps:
- name: Download production image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: production-pypi-image
- name: Load production image
run: gunzip -c pypi.tar.gz | docker load
- name: Test Jupyter mode
run: |
docker run -d --name pyrit-jupyter-pypi -e PYRIT_MODE=jupyter -p 8888:8888 pyrit:pypi-test
echo "Waiting for Jupyter to start..."
sleep 20
if ! docker ps | grep -q pyrit-jupyter-pypi; then
echo "Container not running! Logs:"
docker logs pyrit-jupyter-pypi
exit 1
fi
curl -sf http://localhost:8888/api || (echo "Jupyter API failed" && docker logs pyrit-jupyter-pypi && exit 1)
echo "✅ Jupyter mode tests passed (PyPI)"
docker stop pyrit-jupyter-pypi && docker rm pyrit-jupyter-pypi