Skip to content

Comments

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

Merged
pelikhan merged 17 commits intomainfrom
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 intomainfrom
copilot/add-user-per-workflow-rate-limiting

Conversation

Copy link
Contributor

Copilot AI commented Feb 11, 2026

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 Workflow
engine: copilot
on:
  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: 3
  window: 30
  events: [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

Copilot AI and 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
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

Copilot AI and 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>
Copilot AI changed the title [WIP] Add support for user per workflow rate limiting Add per-user per-workflow rate limiting for programmatic events Feb 11, 2026
Copilot AI requested a review from pelikhan February 11, 2026 12:44
@pelikhan
Copy link
Contributor

@copilot filter out workflow runs that were cancelled in calculation

@github-actions
Copy link
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>
Copy link
Contributor Author

Copilot AI commented Feb 11, 2026

@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
Contributor

@copilot max window length is 3h

@pelikhan
Copy link
Contributor

@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>
Copy link
Contributor Author

Copilot AI commented Feb 11, 2026

@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.

Copilot AI changed the title Add per-user per-workflow rate limiting for programmatic events Add per-user per-workflow rate limiting with automatic event inference for programmatic events Feb 11, 2026
@pelikhan
Copy link
Contributor

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

Copy link
Contributor Author

Copilot AI commented Feb 11, 2026

@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
Copy link
Contributor

github-actions bot commented Feb 11, 2026

Changeset Generator completed successfully!

@github-actions
Copy link
Contributor

github-actions bot commented Feb 11, 2026

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

@github-actions
Copy link
Contributor

🧪 Smoke Project is now testing project operations...

@github-actions
Copy link
Contributor

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

@github-actions
Copy link
Contributor

github-actions bot commented Feb 11, 2026

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

@github-actions
Copy link
Contributor

Agent Container Tool Check ✅

All development tools are available in the agent container environment.

Tool Status Version
bash 5.2.21
sh available
git 2.52.0
jq 1.7
yq v4.52.2
curl 8.5.0
gh 2.86.0
node v20.20.0
python3 3.12.3
go go1.24.12
java 21.0.10
dotnet 10.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
Contributor

Smoke Project completed successfully. All project operations validated.

@github-actions
Copy link
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
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
Contributor

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

@pelikhan pelikhan merged commit 06d4b85 into main Feb 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 free to 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.

2 participants