Skip to content

Update marketing examples from WebGoat to known-malicious-repo #190

Update marketing examples from WebGoat to known-malicious-repo

Update marketing examples from WebGoat to known-malicious-repo #190

Workflow file for this run

name: Test
on:
push:
branches: [main, claude/*]
pull_request:
branches: [main]
# Pin opengrep version for consistent SARIF output
# IMPORTANT: When updating this version, also update:
# - internal/version/version.go
# - docker/Dockerfile
env:
OPENGREP_VERSION: "1.15.1"
jobs:
test:
runs-on: ubuntu-latest
# Skip redundant runs: run on push, or on pull_request only if from a fork
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install opengrep (pinned version)
run: |
wget -O /usr/local/bin/opengrep "https://github.com/opengrep/opengrep/releases/download/v${OPENGREP_VERSION}/opengrep_manylinux_x86"
chmod +x /usr/local/bin/opengrep
opengrep --version
- name: Build
run: go build -v ./...
- name: Run unit tests with coverage
run: |
go test -v -race -coverprofile=coverage.out -short ./...
go tool cover -func=coverage.out
- name: Run integration tests (with scanner)
run: |
go test -v -timeout 5m ./test/...
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.out
scanner-test:
runs-on: ubuntu-latest
# Skip redundant runs: run on push, or on pull_request only if from a fork
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install opengrep (pinned version)
run: |
wget -O /usr/local/bin/opengrep "https://github.com/opengrep/opengrep/releases/download/v${OPENGREP_VERSION}/opengrep_manylinux_x86"
chmod +x /usr/local/bin/opengrep
opengrep --version
- name: Clone test repo and scan for fake secrets
run: |
# Clone this repo (contains test/fixtures/fake_secrets.go)
git clone --depth 1 https://github.com/baocin/gitscan.git /tmp/test-repo
# Run scanner with SARIF output to file (--sarif-output writes directly to file)
# Use --quiet to suppress progress bar which can interfere with output
echo "Running opengrep scanner..."
opengrep scan --quiet --config auto --sarif-output=/tmp/scan-results.json /tmp/test-repo || true
# Show scanner progress (from stderr)
echo "=== Scanner Progress ==="
cat /tmp/scan-stderr.log | head -50
# Show JSON results
echo "=== Scan Results (JSON) ==="
cat /tmp/scan-results.json | head -200
# Verify we got JSON output
if [ ! -s /tmp/scan-results.json ]; then
echo "ERROR: No scan output generated"
echo "=== Stderr log ==="
cat /tmp/scan-stderr.log
exit 1
fi
# Check for valid JSON structure
if ! python3 -c "import json; json.load(open('/tmp/scan-results.json'))"; then
echo "ERROR: Invalid JSON output"
echo "=== Full output ==="
cat /tmp/scan-results.json
echo "=== Stderr log ==="
cat /tmp/scan-stderr.log
exit 1
fi
echo "Scanner produced valid JSON output"
- name: Verify SARIF parsing compatibility
run: |
# Test that our Go code can parse the scanner output
go test -v -run TestParseSARIF ./internal/scanner/...
benchmark-test:
runs-on: ubuntu-latest
# Skip redundant runs: run on push, or on pull_request only if from a fork
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install opengrep (pinned version)
run: |
wget -O /usr/local/bin/opengrep "https://github.com/opengrep/opengrep/releases/download/v${OPENGREP_VERSION}/opengrep_manylinux_x86"
chmod +x /usr/local/bin/opengrep
opengrep --version
- name: Run OWASP NodeGoat clone test
run: |
go test -v -run TestCloneOWASPNodeGoatPinned ./test/... -timeout 5m
- name: Run clone speed tests
run: |
go test -v -run TestCloneSpeed ./test/... -timeout 5m
- name: Run OWASP NodeGoat scan test
run: |
go test -v -run TestScanOWASPNodeGoat ./test/... -timeout 10m
- name: Run benchmarks (1 iteration for CI)
run: |
go test -bench=. -benchtime=1x -run=^$ ./test/... -timeout 10m || true
integration-test:
runs-on: ubuntu-latest
needs: test
# Skip redundant runs: run on push, or on pull_request only if from a fork
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install opengrep (pinned version)
run: |
wget -O /usr/local/bin/opengrep "https://github.com/opengrep/opengrep/releases/download/v${OPENGREP_VERSION}/opengrep_manylinux_x86"
chmod +x /usr/local/bin/opengrep
opengrep --version
- name: Build server
run: go build -o gitscan-server ./cmd/gitscan-server
- name: Start server
run: |
./gitscan-server -listen :6633 -cache-dir /tmp/gitscan-cache &
sleep 3
curl -sf http://localhost:6633/health || exit 1
- name: Test health endpoint
run: |
curl -sf http://localhost:6633/health
- name: Test version endpoint
run: |
curl -sf http://localhost:6633/version | jq .
- name: Test homepage
run: |
curl -sf http://localhost:6633/ | grep -q "git.vet"
- name: Test git clone (info/refs)
run: |
# Test that info/refs endpoint responds with git protocol
curl -sf "http://localhost:6633/github.com/OWASP/NodeGoat/info/refs?service=git-upload-pack" | head -c 100
docker-test:
runs-on: ubuntu-latest
needs: test # Run after unit tests pass
# Skip redundant runs: run on push, or on pull_request only if from a fork
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: |
echo "Building Docker image..."
docker build -f docker/Dockerfile -t gitscan:test .
echo "Image built successfully"
- name: Verify binary in image
run: |
echo "=== Checking binary exists and is executable ==="
docker run --rm gitscan:test ls -la /usr/local/bin/gitscan
docker run --rm gitscan:test file /usr/local/bin/gitscan
echo "=== Checking shared library dependencies ==="
docker run --rm gitscan:test ldd /usr/local/bin/gitscan 2>&1 || echo "Static binary or musl-linked"
- name: Start container
run: |
docker run -d --name gitscan-test -p 6633:6633 gitscan:test
echo "Container started, waiting for server..."
# Wait for server to be ready (up to 30 seconds)
for i in $(seq 1 15); do
if curl -sf http://localhost:6633/health > /dev/null 2>&1; then
echo "Server ready after $((i*2)) seconds"
break
fi
echo "Waiting... ($i/15)"
sleep 2
done
- name: Test health endpoint
run: |
response=$(curl -sf http://localhost:6633/health)
echo "Health: $response"
[ "$response" = "ok" ] || [ "$response" = "OK" ] || exit 1
- name: Test version endpoint
run: |
curl -sf http://localhost:6633/version | jq .
- name: Test homepage
run: |
curl -sf http://localhost:6633/ | grep -q "git.vet"
echo "Homepage OK - contains git.vet"
- name: Test pricing page
run: |
curl -sf http://localhost:6633/pricing | grep -q "Pricing"
echo "Pricing page OK"
# Test redirect from /pricing/ to /pricing
status=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:6633/pricing/)
echo "Redirect status: $status"
[ "$status" = "301" ] || [ "$status" = "200" ] || exit 1
- name: Test static assets
run: |
# Test favicon
curl -sf http://localhost:6633/static/favicon.svg > /dev/null
echo "Favicon OK"
- name: Test git protocol - info/refs
run: |
response=$(curl -sf "http://localhost:6633/github.com/OWASP/NodeGoat/info/refs?service=git-upload-pack")
echo "$response" | head -c 200
echo ""
# Verify git protocol response
echo "$response" | grep -q "git-upload-pack" || { echo "Missing git-upload-pack in response"; exit 1; }
echo "Git info/refs OK"
- name: Test report page (404 for non-existent)
run: |
# Should return HTML even for non-existent reports
curl -sf http://localhost:6633/r/nonexistent123 | grep -q "Report Not Found"
echo "Report 404 page OK"
- name: Show container logs
if: always()
run: |
echo "=== Container logs ==="
docker logs gitscan-test 2>&1 | tail -100
- name: Cleanup
if: always()
run: |
docker stop gitscan-test 2>/dev/null || true
docker rm gitscan-test 2>/dev/null || true