name: ABE Explore description: Run ABE autonomous bug exploration against a target web application inputs: url: description: Target URL to explore required: true server: description: ABE server URL (if using remote mode) required: false default: '' api-key: description: API key for remote ABE server required: false default: '' max-states: description: Maximum number of states to explore required: false default: '50' seed: description: Deterministic seed for reproducibility required: false default: '42' output: description: Output format (human | json | junit | markdown) required: false default: 'junit' fail-on-severity: description: Fail if findings at or above this severity (low | medium | high | critical) required: false default: 'high' reports-dir: description: Directory for generated reports required: false default: './abe-reports' config: description: Path to ABE JSON config file required: false default: '' outputs: findings-count: description: Number of findings discovered value: ${{ steps.explore.outputs.findings-count }} session-id: description: ABE session ID value: ${{ steps.explore.outputs.session-id }} junit-path: description: Path to JUnit XML results file value: './abe-results.xml' runs: using: composite steps: - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: Install ABE dependencies shell: bash run: npm ci working-directory: ${{ github.action_path }}/../../../ - name: Install Playwright browsers shell: bash run: npx playwright install chromium --with-deps working-directory: ${{ github.action_path }}/../../../ - name: Run ABE exploration id: explore shell: bash working-directory: ${{ github.action_path }}/../../../ env: ABE_API_KEY: ${{ inputs.api-key }} run: | ARGS="--url ${{ inputs.url }}" ARGS="$ARGS --max-states ${{ inputs.max-states }}" ARGS="$ARGS --seed ${{ inputs.seed }}" ARGS="$ARGS --output ${{ inputs.output }}" ARGS="$ARGS --reports-dir ${{ inputs.reports-dir }}" if [ -n "${{ inputs.server }}" ]; then ARGS="$ARGS --server ${{ inputs.server }}" fi if [ -n "${{ inputs.api-key }}" ]; then ARGS="$ARGS --api-key ${{ inputs.api-key }}" fi if [ -n "${{ inputs.fail-on-severity }}" ]; then ARGS="$ARGS --fail-on-severity ${{ inputs.fail-on-severity }}" fi if [ -n "${{ inputs.config }}" ]; then ARGS="$ARGS --config ${{ inputs.config }}" fi npm run abe -- explore $ARGS EXIT_CODE=$? # Parse findings count from JUnit if available if [ -f abe-results.xml ]; then FAILURES=$(grep -oP 'failures="\K[0-9]+' abe-results.xml | head -1 || echo "0") echo "findings-count=$FAILURES" >> $GITHUB_OUTPUT else echo "findings-count=0" >> $GITHUB_OUTPUT fi exit $EXIT_CODE - name: Upload ABE reports if: always() uses: actions/upload-artifact@v4 with: name: abe-reports-${{ github.run_id }} path: | ${{ inputs.reports-dir }}/ abe-results.xml retention-days: 30