Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ jobs:
api-token: ${{ secrets.API_DISCOVERY_TOKEN || 'test-token' }}
dry-run: 'true'

- name: Display outputs
- name: Check outputs
run: |
echo "Spec path: ${{ steps.discovery.outputs.spec-path }}"
echo "Success: ${{ steps.discovery.outputs.success }}"
echo "Endpoints: ${{ steps.discovery.outputs.endpoints-count }}"
echo "Frameworks: ${{ steps.discovery.outputs.frameworks-detected }}"
test "${{ steps.discovery.outputs.success }}" = "true"

202 changes: 46 additions & 156 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
# Code Discovery GitHub Action
# APIsec Surface GitHub Action

Automatically discover API endpoints in your repository and upload them to the APIsec platform. This action uses the Code Discovery CLI to scan your codebase, generate OpenAPI specifications, and create pull requests with the results.
Scans your repository with the Surface CLI ([`apisec-surface`](https://pypi.org/project/apisec-surface/)) and uploads the result to APIsec. Surface replaces Code Discovery / Code Bolt; applications created by Code Discovery are updated in place.

## Features
## Quick start

- 🔍 **Automatic Framework Detection** - Detects Spring Boot, Micronaut, Argos, FastAPI, Flask, Django, Express, ASP.NET Core, Gin and more
- 📝 **OpenAPI Generation** - Generates OpenAPI 3.0 specifications from your code
- 🔄 **State Management** - Tracks application and instance IDs across runs
- 🔀 **Pull Request Creation** - Automatically creates PRs with discovered endpoints
- ⚠️ **Non-Blocking** - Warnings don't fail your workflow

## Usage

### Basic Example
1. Add two repository secrets (Settings → Secrets and variables → Actions):
- `API_DISCOVERY_ENDPOINT`: your APIsec API URL, for example `https://api.apisecapps.com`
- `API_DISCOVERY_TOKEN`: an APIsec personal access token with the `app:create` permission
2. Add `.github/workflows/api-discovery.yml`:

```yaml
name: API Discovery
Expand All @@ -24,183 +19,78 @@ on:
jobs:
discover:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: apisec-inc/apisec-bolt-code-discovery-github-action@v0.1.7
with:
api-endpoint: ${{ secrets.API_DISCOVERY_ENDPOINT }}
api-token: ${{ secrets.API_DISCOVERY_TOKEN }}
```

### Scheduled Runs

```yaml
name: API Discovery

on:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM

jobs:
discover:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: apisec-inc/apisec-bolt-code-discovery-github-action@v0.1.7
- uses: apisec-inc/apisec-bolt-code-discovery-github-action@v1
with:
api-endpoint: ${{ secrets.API_DISCOVERY_ENDPOINT }}
api-token: ${{ secrets.API_DISCOVERY_TOKEN }}
pr-title: 'chore: update OpenAPI specification [skip ci]'
pr-body: 'Automatically generated OpenAPI specification from code discovery'
```

### Custom Configuration

```yaml
- uses: apisec-inc/apisec-bolt-code-discovery-github-action@v0.1.7
with:
api-endpoint: ${{ secrets.API_DISCOVERY_ENDPOINT }}
api-token: ${{ secrets.API_DISCOVERY_TOKEN }}
repo-path: './backend'
config-path: './backend/.codediscovery.yml'
```
Existing Code Discovery workflows only need the tag changed to `@v1`. The `contents: write` and `pull-requests: write` permissions are no longer needed.

### Dry Run (Testing)
### Dry run

```yaml
- uses: apisec-inc/apisec-bolt-code-discovery-github-action@v0.1.7
- uses: apisec-inc/apisec-bolt-code-discovery-github-action@v1
with:
api-endpoint: ${{ secrets.API_DISCOVERY_ENDPOINT }}
api-token: ${{ secrets.API_DISCOVERY_TOKEN }}
dry-run: true # Skip API upload, still generates spec
dry-run: true
```

## Inputs

| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `api-endpoint` | ✅ Yes | - | External API endpoint URL |
| `api-token` | ✅ Yes | - | Bearer token for API authentication |
| `repo-path` | ❌ No | `.` | Path to repository root to analyze |
| `config-path` | ❌ No | `.codediscovery.yml` | Path to .codediscovery.yml config file |
| `pr-title` | ❌ No | `chore: update OpenAPI specification` | Pull request title |
| `pr-body` | ❌ No | `Automatically generated OpenAPI specification` | Pull request body |
| `dry-run` | ❌ No | `false` | Skip API upload (for testing) |
| `host-url` | ⚠️ Recommended | `''` | OpenAPI server URL (e.g. `https://api.example.com`). Required when no parser can extract a host from your sources; without it, state isn't saved across runs. |
| `api-endpoint` | Yes | | APIsec API URL |
| `api-token` | Yes | | APIsec personal access token |
| `repo-path` | No | `.` | Repository root to analyze |
| `dry-run` | No | `false` | Analyze only; do not upload |
| `config-path` | No | `.codediscovery.yml` | Ignored |
| `host-url` | No | | Ignored; set the instance host in the APIsec console |
| `pr-title` | No | | Ignored; no spec PR is opened |
| `pr-body` | No | | Ignored; no spec PR is opened |

## Outputs

| Output | Description |
|--------|-------------|
| `spec-path` | Path to generated OpenAPI specification (`apisec-bolt-code-discovery/openapi_spec.yaml`) |
| `application-id` | Application ID from API (if uploaded) |
| `instance-id` | Instance ID from API (if uploaded) |
| `pr-url` | URL of created pull request |
| `success` | Whether discovery succeeded |
| `success` | `true` only when the scan completed |
| `application-id` | APIsec application id after a successful upload |
| `endpoints-count` | Number of API routes found |
| `frameworks-detected` | Comma-separated frameworks |
| `spec-path` | Empty (the spec is published by APIsec) |
| `instance-id` | Empty |
| `pr-url` | Empty |

## Required Permissions
The Action never fails the workflow. Check `success` if a later step should stop.

This action requires the following GitHub permissions:
## How it works

- `contents: write` - To commit generated files
- `pull-requests: write` - To create pull requests
1. Installs Python 3.11 and Surface CLI `1.0.0`
2. Registers or reuses one APIsec application per GitHub repository
3. Uploads the Surface analysis; APIsec publishes the OpenAPI spec

Add these permissions to your workflow:
After the first run, set the instance host URL in the APIsec console if the default `/` is not your API base.

```yaml
permissions:
contents: write
pull-requests: write
```

## How It Works

1. **Install CLI** - Installs Code Discovery CLI (version 0.7.2)
2. **Configure Credentials** - Sets up API credentials from inputs
3. **Run Discovery** - Scans repository and generates OpenAPI spec
4. **Create PR** - Creates a new branch, commits files, and opens a pull request

### Generated Files

The action generates files in the `apisec-bolt-code-discovery/` directory:

- `openapi_spec.yaml` - OpenAPI 3.0 specification
- `state.yaml` - State file tracking application and instance IDs

Both files are automatically committed to the pull request.

## State Management

The action uses state management to track your application across runs:

- **First Run**: Creates a new application and stores IDs in `state.yaml`
- **Subsequent Runs**: Updates the existing application using stored IDs

The state file (`apisec-bolt-code-discovery/state.yaml`) is safe to commit and contains no sensitive data.
## Changes from Code Discovery (`v0.1.x`)

## Error Handling
- No pull request is opened and no files are committed to your repository.
- `host-url`, `config-path`, `pr-title` and `pr-body` are accepted but ignored.
- `spec-path`, `instance-id` and `pr-url` outputs are empty.

The action is designed to be non-blocking:
## Supported frameworks

- ⚠️ Discovery warnings don't fail the workflow
- ⚠️ API errors are logged but don't stop execution
- ✅ Workflow continues even if discovery encounters issues

## Supported Frameworks

- **Java**: Spring Boot, Micronaut, Argos
- **Java**: Spring Boot, Micronaut, JAX-RS (Jersey, Quarkus, RESTEasy), Servlet
- **Python**: FastAPI, Flask, Django
- **Node.js**: Express
- **.NET**: ASP.NET Core
- **Go**: Gin

More frameworks coming soon!

## Requirements

- Python 3.9+ (available on GitHub Actions runners)
- Git (for PR creation)
- GitHub CLI (`gh`) - pre-installed on GitHub Actions runners

## License

MIT License - see [LICENSE](LICENSE) file for details.

## Support

For issues and questions, please open an issue in the [repository](https://github.com/apisec-inc/apisec-bolt-code-discovery-github-action).

## Quick Start

1. **Add workflow file** `.github/workflows/api-discovery.yml`:
```yaml
name: API Discovery
on:
push:
branches: [main]
jobs:
discover:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: apisec-inc/apisec-bolt-code-discovery-github-action@v0.1.7
with:
api-endpoint: ${{ secrets.API_DISCOVERY_ENDPOINT }}
api-token: ${{ secrets.API_DISCOVERY_TOKEN }}
```
- **JavaScript / TypeScript**: Express, NestJS, Fastify, Koa
- **.NET**: ASP.NET Core, ASP.NET MVC / Web API, Web Forms, gRPC, WCF
- **Ruby**: Rails, Sinatra, Grape, Hanami, Roda, Padrino
- **GraphQL**

2. **Configure secrets** in repository Settings → Secrets:
- `API_DISCOVERY_ENDPOINT` - Your API endpoint URL
- `API_DISCOVERY_TOKEN` - Your Bearer token
Go (Gin) and Argos are not yet supported in Surface. Keep those repositories on `@v0.1.9` until they are.

3. **Push to trigger** - The action will run automatically!
## Rollback

Pin `@v0.1.9` to run Code Discovery again.
Loading
Loading