Skip to content

Add per-user per-workflow rate limiting with automatic event inference for programmatic events - #14940

Merged
pelikhan merged 17 commits into
mainfrom
copilot/add-user-per-workflow-rate-limiting
Feb 11, 2026
Merged

Add per-user per-workflow rate limiting with automatic event inference for programmatic events#14940
pelikhan merged 17 commits into
mainfrom
copilot/add-user-per-workflow-rate-limiting

Conversation

CopilotAI commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Rate Limiting Implementation - Complete ✅

Successfully implemented per-user per-workflow rate limiting for programmatically triggered events in GitHub Agentic Workflows with automatic event inference and applied it to production workflows.

🎯 Key Features

Per-User Per-Workflow Rate Limiting

  • Limits how frequently each user can trigger a workflow
  • Required max field (1-10 runs) with optional time window (up to 3 hours)
  • Automatic event inference from on: triggers - no manual configuration needed! 🚀
  • Automatic workflow cancellation when limit exceeded
  • Excludes cancelled runs (using conclusion: 'cancelled') ✨
  • Excludes runs shorter than 15 seconds
  • Smart programmatic event detection 🎯

Smart Implementation

  • Automatically infers events from workflow's on: section
  • Uses workflow file from GITHUB_WORKFLOW_REF (fixes API compatibility)
  • Progressive pagination with short-circuit logic
  • Extensive logging for debugging
  • Fail-open on API errors (safety)
  • Integrated into pre-activation job with actions: read permission

Developer Experience

  • Minimal YAML configuration - just specify max (events inferred automatically!)
  • JSON schema validation (max required, range 1-10)
  • Comprehensive test suite (18 JavaScript + 5 Go tests)
  • Detailed documentation

📋 Implementation Details

Go Changes

  • pkg/constants/constants.go: Added rate limit constants
  • pkg/workflow/frontmatter_types.go: Added RateLimitConfig type
  • pkg/workflow/compiler_types.go: Added rate limit to WorkflowData
  • pkg/workflow/role_checks.go: Added extraction, generation, and automatic event inference functions
  • pkg/workflow/compiler_activation_jobs.go: Integrated into preactivation job with actions: read permission
  • pkg/parser/schemas/main_workflow_schema.json: Schema with required max (1-10), window max 180 minutes
  • pkg/workflow/role_checks_test.go: Added comprehensive tests for event inference

JavaScript Implementation

  • actions/setup/js/check_rate_limit.cjs: Rate limiting with proper API usage
    • Uses workflow file from GITHUB_WORKFLOW_REF
    • Checks conclusion: 'cancelled' (not status)
    • Filters programmatic events
    • Excludes runs < 15s
  • actions/setup/js/check_rate_limit.test.cjs: 18 comprehensive tests

Documentation

  • docs/RATE_LIMITING.md: Complete feature documentation with automatic inference examples

🔧 Configuration Example

Minimal Configuration (Recommended)

---
name: My Workflowengine: copiloton:
issues:
types: [opened]issue_comment:
types: [created]rate-limit:
max: 5# REQUIRED: 1-10 runs# window: 60 (default)# events: automatically inferred as [issues, issue_comment]
---

Explicit Override (Optional)

rate-limit:
max: 3window: 30events: [workflow_dispatch] # Override automatic inference
---

✅ Applied to Production Workflows

Rate limiting (max: 5, window: 60, events auto-inferred) now protects:

  • ai-moderator.md - Inferred events: [issues, issue_comment, workflow_dispatch]
  • auto-triage-issues.md - Inferred events: [issues, workflow_dispatch]
  • example-custom-error-patterns.md - Inferred events: [issues]
  • workflow-generator.md - Inferred events: [issues]

All 148 workflows successfully compiled with automatic event inference.

✅ Testing & Validation

  • 18 JavaScript unit tests (all passing)
  • 5 Go unit tests for event inference (all passing)
  • 148 workflows recompiled successfully
  • Code formatting and linting passed
  • Schema validation tested (required max, max range 1-10, window max 180)
  • Permissions verified (actions: read added automatically)
  • Code review passed with no issues
  • Security scan passed with no vulnerabilities

📊 Test Results

JavaScript Tests

✓ check_rate_limit.test.cjs (18 tests) 35ms
✓ should pass when no recent runs by actor
✓ should pass when recent runs are below limit
✓ should fail when rate limit is exceeded
✓ should only count runs by the same actor
✓ should exclude runs older than the time window
✓ should exclude the current run from the count
✓ should exclude cancelled runs from the count ⭐
✓ should exclude runs that lasted less than 15 seconds ⚡
✓ should only count specified event types when events filter is set
✓ should skip rate limiting if current event is not in the events filter
✓ should use custom max and window values
✓ should short-circuit when max is exceeded during pagination
✓ should fail-open on API errors
✓ should continue even if cancellation fails
✓ should provide breakdown by event type
✓ should skip rate limiting for non-programmatic events 🎯
✓ should use workflow file from GITHUB_WORKFLOW_REF 📁
✓ should fall back to workflow name when ref not parseable 📁

Go Tests

✓ TestInferEventsFromTriggers (5 test cases)
✓ infer from map with multiple triggers
✓ infer only programmatic triggers
✓ no triggers
✓ missing on section
✓ all programmatic triggers

🚀 Key Implementation Details

Automatic Event Inference 🚀

  • Events automatically inferred from workflow's on: section
  • Only programmatic triggers included (issues, issue_comment, workflow_dispatch, etc.)
  • Non-programmatic triggers (push, schedule, merge_group) excluded
  • Can be overridden by explicitly specifying events field
  • Simplifies configuration - just specify max and you're done!

Required Max Field: 1-10 runs

  • max is a required field (schema enforced)
  • Range restricted to 1-10 runs for tighter abuse prevention
  • No default value - must be explicitly specified

Maximum Window: 3 Hours

  • Window parameter capped at 180 minutes (3 hours)
  • Default: 60 minutes (1 hour)
  • Schema validation enforces the maximum

Smart Filtering

  • Cancelled workflow runs don't count (uses conclusion: 'cancelled')
  • Runs lasting < 15 seconds excluded (treated as failed fast)
  • All exclusions explicitly logged for debugging

Correct API Usage

  • Uses workflow file from GITHUB_WORKFLOW_REF for API compatibility
  • Falls back to workflow name if ref unavailable
  • Programmatic events filter prevents unintended rate limiting
  • Environment variables properly quoted for YAML robustness
  • actions: read permission automatically added
Original prompt

Add support for generating per-user per workflow rate limiting for events that can be triggered programmatically.

In preactivation job, after role, checks,

  • name: Check User Rate Limit
    uses: actions/github-script@v8
    if: check event type
    with:
    script: | # move to separate file
    const actor = context.actor;
    const owner = context.repo.owner;
    const repo = context.repo.repo;
    const workflow_id = context.workflow;

    const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();
    

collect each event type separately, aggregate filter progressively , check max item in loop to shortcut

 const runs = await github.rest.actions.listWorkflowRuns({
owner,
repo,
workflow_id,
event_type: ...
per_page: 100
});
const recentByActor = runs.data.workflow_runs.filter(run =>
run.actor?.login === actor &&
run.created_at > oneHourAgo
);
if (recentByActor.length >= 10) { # default is 5
Code to cancel }
  • extensive logging
  • emit multiple steps for each

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.


Changeset

  • Type: patch
  • Description: Adds per-user per-workflow rate limiting for programmatic events with automatic inference, filtering, and window controls

Generated by Changeset Generator

CopilotAIand others added 2 commits February 11, 2026 12:26
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
- Add rate-limit configuration to FrontmatterConfig and WorkflowData
- Add extractRateLimitConfig to parse rate-limit from frontmatter
- Add generateRateLimitCheck to create rate limit check step
- Implement check_rate_limit.cjs with comprehensive rate limiting logic
- Add 13 test cases covering various scenarios
- Add constants: CheckRateLimitStepID, RateLimitOkOutput
- Add default rate limit constants (5 runs per 60 minutes)
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR Triage Results

Category: feature | Risk: low | Priority: 32/100

Scores Breakdown

  • Impact: 25/50 - Standard feature changes
  • Urgency: 0/30 - Normal urgency
  • Quality: 7/20 - CI pending, draft WIP

📋 Recommended Action: DEFER

Work in Progress

This PR is marked as draft and will be re-triaged when ready for review.


Triaged by PR Triage Agent on 2026-02-11 | Run #21904909325

AI generated by PR Triage Agent

CopilotAIand others added 3 commits February 11, 2026 12:34
- Update extractRateLimitConfig to handle uint64, int64, int, and float64
- Add rate-limit schema definition to main_workflow_schema.json
- Create test-rate-limit.md workflow demonstrating rate limiting
- Rebuild binary to embed updated schema
- Successfully compile test workflow with rate limits (max=3, window=30)
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Update TestGetActionPinsSorting to expect 39 pins (added docker/build-push-action@v6)
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
- Document rate-limit configuration options
- Explain how rate limiting works internally
- Provide usage examples for different scenarios
- Include troubleshooting guide
- Add testing instructions
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
CopilotAI changed the title [WIP] Add support for user per workflow rate limitingAdd per-user per-workflow rate limiting for programmatic eventsFeb 11, 2026
CopilotAI requested a review from pelikhanFebruary 11, 2026 12:44
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot filter out workflow runs that were cancelled in calculation

@github-actions

Copy link
Copy Markdown
Contributor

PR titles:
chore: refactor tokens page
Revert unintended action pin changes from documentation PR
GitHub MCP (2 merged PRs): ✅
Serena activate/find_symbol: ✅
Playwright github title: ✅
File write + cat: ✅
Build (make build): ✅
Overall status: PASS

AI generated by Smoke Codex

- Skip runs with status "cancelled" when counting toward rate limit
- Add test case to verify cancelled runs are excluded
- Update documentation to reflect this behavior
- Cancelled runs are now explicitly logged as skipped
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

CopilotAI commented Feb 11, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot filter out workflow runs that were cancelled in calculation

Done! Cancelled workflow runs are now filtered out from the rate limit calculation. The check now skips runs with status === "cancelled" and logs them explicitly. Added test coverage in commit 5b7584f.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot max window length is 3h

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot the rate-limiting.events field should be optimal . Inferred if missing

- Add inferEventsFromTriggers() to automatically detect programmatic triggers
- Infer events from workflow's 'on:' section when not explicitly specified
- Only programmatic triggers are inferred (issues, issue_comment, workflow_dispatch, etc.)
- Non-programmatic triggers (push, schedule, etc.) are filtered out
- Remove explicit events from production workflows (now inferred automatically)
- Update documentation to explain automatic inference
- Add comprehensive tests for event inference (5 test cases, all passing)
Production workflows updated:
- ai-moderator: infers [issues, issue_comment, workflow_dispatch]
- auto-triage-issues: infers [issues, workflow_dispatch]
- example-custom-error-patterns: infers [issues]
- workflow-generator: infers [issues]
All 148 workflows recompiled successfully with automatic event inference.
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

CopilotAI commented Feb 11, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot the rate-limiting.events field should be optimal . Inferred if missing

Done in commit 9c9fc7d! The events field is now optional and automatically inferred from the workflow's on: triggers.

Example:

on:
issues:
types: [opened]issue_comment:
types: [created]rate-limit:
max: 5# events automatically inferred as [issues, issue_comment]

Only programmatic triggers are inferred. Non-programmatic events (push, schedule) are excluded. Can still be explicitly set to override inference. Added 5 Go tests for inference logic.

CopilotAI changed the title Add per-user per-workflow rate limiting for programmatic eventsAdd per-user per-workflow rate limiting with automatic event inference for programmatic eventsFeb 11, 2026
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot merge main, recompile and do a code review to improvise new code

CopilotAI commented Feb 11, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot merge main, recompile and do a code review to improvise new code

Completed in merge commit ea1dbfa:

  • ✅ Merged main branch successfully
  • ✅ Rebuilt binary with merged changes
  • ✅ Recompiled all 148 workflows successfully
  • ✅ Code review passed with no issues
  • ✅ Security scan passed with no vulnerabilities

All rate limiting functionality working correctly after merge. Ready for production.

@github-actions

github-actionsBot commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Changeset Generator completed successfully!

@github-actions

github-actionsBot commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

🎬 THE ENDSmoke ClaudeMISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Smoke Project is now testing project operations...

@github-actions

Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions

github-actionsBot commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions

Copy link
Copy Markdown
Contributor

Agent Container Tool Check ✅

All development tools are available in the agent container environment.

ToolStatusVersion
bash5.2.21
shavailable
git2.52.0
jq1.7
yqv4.52.2
curl8.5.0
gh2.86.0
nodev20.20.0
python33.12.3
gogo1.24.12
java21.0.10
dotnet10.0.102

Result: 12/12 tools available ✅

Status: PASS - All required development tools are present and functional.

AI generated by Agent Container Smoke Test

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Project completed successfully. All project operations validated.

@github-actions

Copy link
Copy Markdown
Contributor

PR titles: Add bot detection workflow; Add temporary ID resolution for create-project item_url and update-project content_number
GitHub MCP (2 merged PRs): ✅
Serena MCP (activate + find_symbol>=3): ✅
Playwright (github.com title contains GitHub): ✅
File write + bash cat: ✅
Build (make build): ✅
Overall: PASS

AI generated by Smoke Codex

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results

Status: ✅ PASS

PRs Reviewed:

Tests:
✅ GitHub MCP | ✅ Safe Inputs | ✅ Serena MCP | ✅ Playwright
✅ File Writing | ✅ Bash | ✅ Discussion | ✅ Build | ✅ Workflow Dispatch

§21924325015

AI generated by Smoke Copilot

@github-actions

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@pelikhan
pelikhan merged commit 06d4b85 into mainFeb 11, 2026
1 check passed
@pelikhan
pelikhan deleted the copilot/add-user-per-workflow-rate-limiting branch February 11, 2026 21:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@pelikhan