test(picklescan): cover operator setitem protocol dispatch #3780
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: Docker Image CI | |
| on: | |
| pull_request: | |
| paths: | |
| - "Dockerfile*" | |
| - ".dockerignore" | |
| - "modelaudit/**" | |
| - "packages/modelaudit-picklescan/**" | |
| - "pyproject.toml" | |
| - "uv.lock" | |
| - ".github/workflows/docker-image-test.yml" | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| # Detect what changed to optimize Docker builds | |
| changes: | |
| name: Detect Docker Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| docker: ${{ steps.filter.outputs.docker }} | |
| full-image: ${{ steps.filter.outputs.full-image }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dorny/paths-filter@v4 | |
| id: filter | |
| with: | |
| filters: | | |
| docker: | |
| - 'Dockerfile*' | |
| - '.dockerignore' | |
| - 'modelaudit/**' | |
| - 'packages/modelaudit-picklescan/**' | |
| - 'pyproject.toml' | |
| - 'uv.lock' | |
| - '.github/workflows/docker-image-test.yml' | |
| full-image: | |
| - 'Dockerfile.full' | |
| - 'packages/modelaudit-picklescan/**' | |
| - '.github/workflows/docker-image-test.yml' | |
| build-test-lightweight: | |
| name: Build and Test Lightweight Docker Image | |
| needs: changes | |
| # Only run if Docker-related files changed | |
| if: needs.changes.outputs.docker == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 # Increased for reliability | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4 | |
| - name: Build lightweight image | |
| uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7 | |
| with: | |
| context: . | |
| file: Dockerfile | |
| tags: modelaudit:lightweight | |
| load: true | |
| cache-from: type=gha,scope=lightweight | |
| cache-to: type=gha,mode=max,scope=lightweight | |
| build-args: | | |
| BUILDKIT_INLINE_CACHE=1 | |
| - name: Test lightweight container help command | |
| run: | | |
| docker run --rm modelaudit:lightweight --help | |
| - name: Test lightweight container scan help | |
| run: | | |
| docker run --rm modelaudit:lightweight scan --help | |
| - name: Test lightweight container version | |
| run: | | |
| # Test that the package is properly installed | |
| docker run --rm modelaudit:lightweight --version | |
| - name: Test lightweight container with invalid command | |
| run: | | |
| # This should fail gracefully | |
| docker run --rm modelaudit:lightweight invalid-command && exit 1 || echo "Command properly rejected invalid input" | |
| - name: Scan image for vulnerabilities | |
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 | |
| with: | |
| # Pin an explicit released Trivy binary to avoid setup failures when | |
| # auto-resolved tags exist without matching release assets. | |
| version: v0.69.2 | |
| image-ref: modelaudit:lightweight | |
| format: table | |
| exit-code: "1" | |
| severity: CRITICAL,HIGH | |
| ignore-unfixed: true | |
| - name: Test lightweight container with actual scan | |
| run: | | |
| # Create a test model file using Docker to ensure Python is available | |
| docker run --rm -v $(pwd):/data python:3.11-slim@sha256:543d6cace00ffc96bc95d332493bb28a4332c6dd614aab5fcbd649ae8a7953d9 sh -c "python -c \"import pickle; pickle.dump({'test': 'data'}, open('/data/test.pkl', 'wb'))\"" | |
| # Now scan the created file | |
| docker run --rm -v $(pwd):/data modelaudit:lightweight /data/test.pkl | |
| build-test-full: | |
| name: Build and Test Full Docker Image | |
| needs: [changes, build-test-lightweight] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 90 # Increased for large ML dependency builds | |
| # Only run if Dockerfile.full specifically changed | |
| if: needs.changes.outputs.full-image == 'true' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4 | |
| - name: Build full image | |
| uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7 | |
| with: | |
| context: . | |
| file: Dockerfile.full | |
| tags: modelaudit:full | |
| load: true | |
| cache-from: type=gha,scope=full | |
| cache-to: type=gha,mode=max,scope=full | |
| build-args: | | |
| BUILDKIT_INLINE_CACHE=1 | |
| timeout-minutes: 60 # Increased timeout for ML dependency build | |
| - name: Test full container help command | |
| run: | | |
| docker run --rm modelaudit:full --help | |
| - name: Test full container scan help | |
| run: | | |
| docker run --rm modelaudit:full scan --help | |
| - name: Test full container version | |
| run: | | |
| # Test that the package is properly installed | |
| docker run --rm modelaudit:full --version | |
| - name: Test full container runs as non-root | |
| run: | | |
| docker run --rm modelaudit:full python -c "import os; uid = os.getuid(); print(f'Container UID: {uid}'); assert uid == 10001" | |
| - name: Scan image for vulnerabilities | |
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 | |
| with: | |
| # Keep full-image scan on the same pinned released Trivy version. | |
| version: v0.69.2 | |
| image-ref: modelaudit:full | |
| format: table | |
| exit-code: "1" | |
| severity: CRITICAL,HIGH | |
| ignore-unfixed: true | |
| - name: Verify ML dependencies in full image | |
| run: | | |
| # Test that ML dependencies are available | |
| docker run --rm modelaudit:full python -c "import tensorflow, torch, onnx; print('All ML dependencies available')" || echo "Warning: Some ML dependencies missing" | |
| - name: Test full container with ML model scan | |
| run: | | |
| # Create the fixture with a root Python image because the full image intentionally runs as UID 10001. | |
| docker run --rm -v $(pwd):/data python:3.11-slim@sha256:543d6cace00ffc96bc95d332493bb28a4332c6dd614aab5fcbd649ae8a7953d9 sh -c "python -c \"import pickle; pickle.dump({'test': 'data', 'numbers': [1, 2, 3]}, open('/data/test_numpy.pkl', 'wb')); print('Created test model')\"" | |
| # Scan the bind-mounted model as the non-root full image. | |
| docker run --rm -v $(pwd):/data modelaudit:full /data/test_numpy.pkl | |
| docker-ci-success: | |
| name: Docker CI Success | |
| needs: [build-test-lightweight] | |
| # Don't require full image test to pass since it's conditional | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check if required jobs succeeded | |
| run: | | |
| LIGHTWEIGHT_RESULT="${{ needs.build-test-lightweight.result }}" | |
| echo "Lightweight Docker build result: $LIGHTWEIGHT_RESULT" | |
| # Success or skipped are both acceptable | |
| # (skipped means the path filters determined the job wasn't needed) | |
| if [[ "$LIGHTWEIGHT_RESULT" == "success" || "$LIGHTWEIGHT_RESULT" == "skipped" ]]; then | |
| echo "Docker CI checks passed (or were skipped due to path filters)!" | |
| exit 0 | |
| else | |
| echo "Docker CI checks failed!" | |
| exit 1 | |
| fi |