# GitHub Release Risk Monitor (`lynchest/tr-github-release-collector`) Actor

Track GitHub releases and extract structured risk signals: breaking changes, security fixes, migrations, custom keyword flags, and importance scoring. Built for AI agents, CI/CD pipelines, dependency monitoring, and product research.

- **URL**: https://apify.com/lynchest/tr-github-release-collector.md
- **Developed by:** [Eren Senses](https://apify.com/lynchest) (community)
- **Categories:** Developer tools, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## GitHub Release Risk Monitor

[![Apify](https://img.shields.io/badge/Apify-Actor-5B45FF?logo=apify)](https://apify.com)

**Track GitHub releases and detect breaking changes, security fixes, migrations, and important keywords — for AI agents, DevOps workflows, dependency monitoring, and product research.**

Not a release collector. A **risk signal extractor** that turns raw changelogs into structured, scorable intelligence.

> **Intelligence is rule-based, not AI-generated.** Risk flags, keyword matching, and importance scoring use deterministic regex + an additive formula — no LLM calls, no model inference. The `intelligence` input field accepts JSON overrides for custom rules, not prompt configuration.

### Why this exists

Raw release data is cheap. **Analyzed, risk-flagged, ready-to-consume signals are premium.**

This Actor gives you:

- **SemVer classification** — `major` / `minor` / `patch` from tag names
- **Breaking change detection** — `BREAKING CHANGE`, `migration required`, `backwards incompatible`
- **Security fix detection** — `CVE-*`, `security patch`, `vulnerability`
- **Custom keyword flags** — your watchlist, auto-detected in every release
- **Importance scoring** — 0–100 rule-based score (breaking+50, security+40, migration+30, major+25, keyword+10 each)
- **Only flagged mode** — skip routine patches, emit only what matters
- **Stateful monitoring** — cross-run tracking; second run emits zero duplicates
- **Rate-limit logging** — reads `X-RateLimit-Remaining` headers, warns on low quota
- **Request delay** — configurable ms between repos to smooth traffic

### 🎯 Use Cases

#### Monitor dependencies weekly

```json
{
  "repositories": ["vercel/next.js", "nestjs/nest", "microsoft/vscode", "apache/httpd"],
  "onlyFlagged": true,
  "outputFormat": "compact",
  "requestDelayMs": 250
}
```

→ Get a clean weekly briefing: what changed, what's risky, what needs migration.

#### Find security releases across 50 repos

```json
{
  "repositories": ["expressjs/express", "fastify/fastify", "h5bp/html5-boilerplate"],
  "onlyFlagged": true,
  "customKeywords": ["security", "CVE", "vulnerability"],
  "outputFormat": "compact"
}
```

→ Security team gets a focused list of releases that need review.

#### Feed release signals into AI agents / MCP workflows

```json
{
  "repositories": ["apify/apify-sdk-js", "apify/crawlee", "apify/apify-cli"],
  "outputFormat": "compact",
  "sinceDate": "2026-06-01"
}
```

→ AI agent receives structured release intelligence: `{releaseType, importanceScore, riskFlags, shortSummary}` — no raw markdown to parse.

### ⚙️ Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `repositories` | `string[]` | **required** | `owner/repo` or full GitHub URL |
| `token` | `string` (secret) | — | GitHub PAT (5,000 req/h, private repos) |
| `maxReleases` | `int` | `10` | Per repo (1–100) |
| `includePrereleases` | `bool` | `false` | Include alpha/beta/rc |
| `onlyFlagged` | `bool` | `false` | Emit only releases with risk/keyword flags |
| `sinceDate` | `string` | — | ISO 8601 start date (e.g. `"2026-07-01"`) |
| `customKeywords` | `string[]` | — | Extra keywords to detect |
| `requestDelayMs` | `int` | `0` | Delay between repo API calls (ms) |
| `outputFormat` | `enum` | `compact` | `compact` or `full` |

### 📦 Output

| Field | Type | Example |
|-------|------|---------|
| `repo` | `string` | `nestjs/nest` |
| `tagName` | `string` | `v11.1.27` |
| `releaseName` | `string` | `v11.1.27` |
| `releaseType` | `enum` | `patch` |
| **`importanceScore`** | `int (0–100)` | **`10`** |
| **`riskFlags`** | `string[]` | **`["migration"]`** |
| **`keywordFlags`** | `string[]` | **`["deprecated"]`** |
| `truncatedBody` | `string` | Cleaned first 300 chars |
| `publishedAt` | `string` | `2026-06-15T09:17:02Z` |
| `isPrerelease` | `bool` | `false` |
| `isBotRelease` | `bool` | `false` |
| `author` | `string` | `kamilmysliwiec` |
| `htmlUrl` | `string` | `https://github.com/...` |
| `body` | `string` | *full mode only* |
| `repoStars` | `int` | `68400` |
| `repoLastCommitDate` | `string` | `2026-07-03T14:22:01Z` |
| `repoDefaultBranch` | `string` | `main` |
| `rulesetVersion` | `string` | `1.0` |

**Bold** = intelligence fields. `isBreaking`/`isSecurityFix` booleans removed — use `riskFlags.includes('breaking-change')` / `riskFlags.includes('security')` instead.

Full schema defined in [`.actor/dataset_schema.json`](.actor/dataset_schema.json) with two views: **Signals** (quick triage) and **Full Details**.

### 🧪 Local Development

```bash
cd tr-github-release-collector
npm install
npm run build

## Create local input
mkdir -p storage/key_value_stores/default
cat > storage/key_value_stores/default/INPUT.json << 'EOF'
{"repositories":["nestjs/nest"],"maxReleases":3,"onlyFlagged":false}
EOF

## Run
APIFY_LOCAL_STORAGE_DIR=./storage npm start

## Second run — stateful, no duplicate output
APIFY_LOCAL_STORAGE_DIR=./storage npm start

## View output
cat storage/datasets/default/000000001.json
```

#### Resetting state

Delete the state file to reset all tracking:

```bash
rm -f storage/GITHUB_RELEASE_MONITOR_STATE.json
```

Or on the Apify platform, clear the default key-value store.

### 🚀 Deploy

```bash
apify login
apify push
```

### ⚠️ Rate Limits

**Unauthenticated** GitHub API usage is limited to **60 requests/hour**.\
This Actor makes **2 API calls per repository per run** (one for releases, one for repo metadata), so monitoring **~25 repositories** in a single run will exhaust the free quota.

- **For monitoring more than ~25 repos per run**, provide a GitHub token via the `token` input field (raises limit to 5,000 req/h, enough for ~2,500 repos).
- The `requestDelayMs` option helps avoid bursty requests, but does **not** increase the hourly GitHub API quota.
- The Actor logs `X-RateLimit-Remaining` headers on every API call and warns when quota is low.

### 🔍 Intelligence Details

#### Importance Score

Additive rule-based formula, **capped to \[0, 100]** via `Math.max(0, Math.min(100, score))`:

| Signal | Weight |
|--------|--------|
| Baseline | 10 |
| `breaking-change` flag | +50 |
| `security` flag | +40 |
| `migration` flag | +30 |
| `major` SemVer | +25 |
| `minor` SemVer | +5 |
| Each custom keyword match | +10 each |
| Prerelease | −15 |

Overflow example: breaking(50) + security(40) + major(25) = 115 → capped to **100**.\
Calibration: 100 = multi-risk critical release. Single minor patches score ~0.

#### State / Dedup

Cross-run dedup compares `publishedAt` timestamps. A release seen in a previous run is skipped.

> ⚠️ **If a maintainer edits a release body after publication** (e.g. adds CVE details later), the Actor **will not reprocess it** — the timestamp doesn't change. For critical dependencies, periodically reset the state file (see [Local Development](#-local-development)).

#### Custom Keywords

Matching is **case-insensitive substring**. Example: `"security"` matches `"Security"`, `"securityContext"`, `"cybersecurity"`. Use specific phrases like `"security fix"`, `"CVE-2024"` to reduce false positives.

### 🧱 Stack

- Node.js 22 + TypeScript
- Apify SDK 3.7
- GitHub REST API (no scraping libs)
- File-based state persistence

### 📄 License

MIT

# Actor input Schema

## `repositories` (type: `array`):

GitHub repositories to monitor. Use "owner/repo" format (e.g. "vercel/next.js") or full GitHub URL.

## `token` (type: `string`):

Optional GitHub PAT. Increases rate limit from 60 to 5,000 req/h and enables private repo access.

## `maxReleases` (type: `integer`):

Maximum number of latest releases to fetch per repository.

## `includePrereleases` (type: `boolean`):

Include prereleases (alpha, beta, rc) in the results.

## `intelligence` (type: `object`):

JSON object overriding default intelligence logic: risk flags, importance thresholds, keyword matching rules, and model-based classification. Leave empty to use built-in defaults.

## `onlyFlagged` (type: `boolean`):

Only emit releases that have risk flags (breaking, security, migration) or keyword matches. Quiet releases are still tracked in state but excluded from output.

## `sinceDate` (type: `string`):

Only process releases published on or after this date (ISO 8601, e.g. "2026-07-01"). Useful for controlled first-run start dates.

## `customKeywords` (type: `array`):

Extra keywords/phrases to flag in release notes (case-insensitive).

## `requestDelayMs` (type: `integer`):

Delay between GitHub API calls per repo (milliseconds). Use 250–500 for large repo lists to avoid rate limiting without a token.

## `outputFormat` (type: `string`):

Select output verbosity. Compact includes intelligence fields + summary without release body; Full includes the complete release body text.

## Actor input object example

```json
{
  "repositories": [
    "vercel/next.js",
    "nestjs/nest",
    "microsoft/vscode"
  ],
  "maxReleases": 10,
  "includePrereleases": false,
  "onlyFlagged": false,
  "customKeywords": [
    "migration",
    "deprecated",
    "removed",
    "requires"
  ],
  "requestDelayMs": 0,
  "outputFormat": "compact"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "repositories": [
        "vercel/next.js",
        "nestjs/nest",
        "microsoft/vscode"
    ],
    "customKeywords": [
        "migration",
        "deprecated",
        "removed",
        "requires"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lynchest/tr-github-release-collector").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "repositories": [
        "vercel/next.js",
        "nestjs/nest",
        "microsoft/vscode",
    ],
    "customKeywords": [
        "migration",
        "deprecated",
        "removed",
        "requires",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("lynchest/tr-github-release-collector").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "repositories": [
    "vercel/next.js",
    "nestjs/nest",
    "microsoft/vscode"
  ],
  "customKeywords": [
    "migration",
    "deprecated",
    "removed",
    "requires"
  ]
}' |
apify call lynchest/tr-github-release-collector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=lynchest/tr-github-release-collector",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/9kvdP72o2E3nykQLB/builds/oJpgFeLwvwaqQ0tpk/openapi.json
