Weekly DAST Scan (Probely) #9
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
| # .github/workflows/probely-scan.yml | |
| # | |
| # Copyright © 2025 Network Pro Strategies (Network Pro™) | |
| # SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later | |
| # This file is part of Network Pro | |
| name: Weekly DAST Scan (Probely) | |
| on: | |
| schedule: | |
| - cron: '0 9 * * 2' # Every Tuesday, 9 AM UTC | |
| workflow_dispatch: | |
| jobs: | |
| dast-scan: | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: read | |
| actions: read | |
| id-token: none | |
| env: | |
| PROBELY_API_KEY: ${{ secrets.PROBELY_API_KEY }} | |
| TARGET_ID: ${{ secrets.PROBELY_TARGET_ID }} | |
| API_BASE: https://api.probely.com | |
| MAX_WAIT_MINUTES: 60 # configurable | |
| steps: | |
| - name: Start Probely Scan | |
| id: start-scan | |
| run: | | |
| curl_retry() { | |
| curl --fail-with-body --retry 3 --retry-delay 5 --retry-max-time 30 "$@" | |
| } | |
| echo "🧪 Triggering Probely scan for target $TARGET_ID ..." | |
| response_file=$(mktemp) | |
| http_code=$(curl_retry -s -w "%{http_code}" -o "$response_file" -X POST "$API_BASE/targets/$TARGET_ID/scan_now/" \ | |
| -H "Authorization: JWT $PROBELY_API_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{}') | |
| echo "🌐 HTTP status: $http_code" | |
| echo "📄 Raw API response:" | |
| cat "$response_file" | |
| if [ "$http_code" -ne 201 ] && [ "$http_code" -ne 200 ]; then | |
| echo "::error ::Unexpected HTTP response from Probely API: $http_code" | |
| exit 1 | |
| fi | |
| if ! jq . "$response_file" >/dev/null 2>&1; then | |
| echo "::error ::Invalid JSON response from Probely API." | |
| cat "$response_file" | |
| exit 1 | |
| fi | |
| jq . "$response_file" | |
| scan_id=$(jq -r '.id // empty' "$response_file") | |
| if [ -z "$scan_id" ]; then | |
| echo "::error ::Scan ID not found in response. Response content:" | |
| cat "$response_file" | |
| exit 1 | |
| fi | |
| echo "scan_id=$scan_id" >> "$GITHUB_ENV" | |
| echo "✅ Scan started with ID: $scan_id" | |
| - name: Wait for Scan Completion | |
| run: | | |
| echo "⏳ Waiting for scan $scan_id to complete..." | |
| elapsed=0 | |
| while [ $elapsed -lt $((MAX_WAIT_MINUTES * 60)) ]; do | |
| status=$(curl --fail-with-body -s "$API_BASE/targets/$TARGET_ID/scans/$scan_id/" \ | |
| -H "Authorization: JWT $PROBELY_API_KEY" | jq -r '.status // empty') | |
| echo "⏱️ Status: $status (elapsed $elapsed sec)" | |
| if [ "$status" = "completed" ]; then | |
| echo "✅ Scan completed successfully." | |
| break | |
| elif [ "$status" = "failed" ]; then | |
| echo "::error ::Scan failed." | |
| exit 1 | |
| fi | |
| sleep 60 | |
| elapsed=$((elapsed + 60)) | |
| done | |
| if [ "$status" != "completed" ]; then | |
| echo "::error ::Scan did not complete in time ($MAX_WAIT_MINUTES min timeout)." | |
| exit 1 | |
| fi | |
| - name: Download Probely CSV Report | |
| run: | | |
| echo "📥 Downloading report for scan $scan_id ..." | |
| curl -s "$API_BASE/targets/$TARGET_ID/scans/$scan_id/endpoints/" \ | |
| -H "Authorization: JWT $PROBELY_API_KEY" \ | |
| -o probely-scan-coverage.csv | |
| if [ ! -s probely-scan-coverage.csv ]; then | |
| echo "::error ::Report file is empty or missing." | |
| exit 1 | |
| fi | |
| echo "✅ Report saved as probely-scan-coverage.csv" | |
| - name: Upload report artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: probely-scan-coverage | |
| path: probely-scan-coverage.csv | |
| # cspell:ignore mktemp |