The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/scripts/todo-issue
Guilherme Gazzo fd5b687ca7
ci(todo-issue): implement TODO issue creation and management workflow (#39015)
5 days ago
..
src ci(todo-issue): implement TODO issue creation and management workflow (#39015) 5 days ago
README.md ci(todo-issue): implement TODO issue creation and management workflow (#39015) 5 days ago
bun.lock ci(todo-issue): implement TODO issue creation and management workflow (#39015) 5 days ago
package.json ci(todo-issue): implement TODO issue creation and management workflow (#39015) 5 days ago
tsconfig.json ci(todo-issue): implement TODO issue creation and management workflow (#39015) 5 days ago

README.md

todo-issue

Scans code for TODO comments and automatically creates, closes, updates, and references GitHub Issues.

Runs as a GitHub Actions workflow via Bun with a single dependency (parse-diff).

How it works

When code is pushed to develop, the script diffs the changes and:

  • Creates a new issue for each new TODO comment
  • Closes the issue when a TODO is removed
  • Updates the issue title when a TODO is edited (detected via similarity matching)
  • References an existing issue when a duplicate TODO is added (adds a comment instead of creating a duplicate)

Every issue created by the script receives the todo label, which is also used to efficiently query only relevant issues.

TODO syntax

Any comment style works (//, #, --, /* */, etc.) as long as only symbols and whitespace appear before the TODO keyword. The keyword is case-insensitive.

Examples

Minimal -- title only:

// TODO: Fix the race condition in token refresh

Extracted data:

Field Value
Title Fix the race condition in token refresh
Body (none)
Labels todo

With body -- continuation lines using the same comment prefix:

// TODO: Refactor the auth flow
// The current token refresh logic has race conditions
// when multiple tabs are open simultaneously

Extracted data:

Field Value
Title Refactor the auth flow
Body The current token refresh logic has race conditions
when multiple tabs are open simultaneously
Labels todo

The body stops at the first line that doesn't share the same comment prefix or is empty.


With custom labels:

// TODO: Make this button red [frontend] [ui]

Extracted data:

Field Value
Title Make this button red
Body (none)
Labels todo, frontend, ui

Labels are extracted from [square brackets] at the end of the title. The todo label is always included.


Full example -- body + labels in different languages:

# TODO: Add retry logic for S3 uploads [infra] [backend]
# Currently fails silently on timeout
# See https://github.com/org/repo/issues/42

Extracted data:

Field Value
Title Add retry logic for S3 uploads
Body Currently fails silently on timeout
See https://github.com/org/repo/issues/42
Labels todo, infra, backend

Block comments:

/**
 * TODO: Should we reinvent the wheel here?
 * We already have a good one in @rocket.chat/core
 */

Extracted data:

Field Value
Title Should we reinvent the wheel here?
Body We already have a good one in @rocket.chat/core
Labels todo

Assignees

Mention GitHub usernames with @ to automatically assign the issue:

// TODO: Fix flaky test @john-doe [testing]

Extracted data:

Field Value
Title Fix flaky test
Body (none)
Labels todo, testing
Assignees john-doe

Mentions in the title are removed from the issue title. Mentions in the body are also collected as assignees but kept in the body text:

// TODO: Migrate to new payments API
// @alice should review the Stripe integration
// @bob handles the webhook setup

Extracted data:

Field Value
Title Migrate to new payments API
Body @alice should review the Stripe integration
@bob handles the webhook setup
Labels todo
Assignees alice, bob

What is NOT captured

// This is not a TODO because the keyword is not at the start after the prefix
// See the TODO documentation for more info

const todo = 'strings containing TODO are ignored';

// TODONT -- partial keyword matches are ignored

Trigger modes

The workflow supports four modes, configured via workflow_dispatch inputs or automatic push events.

Push (automatic)

Triggers on every push to develop. Compares BEFORE_SHA...GITHUB_SHA to detect added/removed TODOs.

SHA (manual)

Process a specific commit or range of commits.

Input Behavior
a1b2c3d Diffs commit against its parent (a1b2c3d~1...a1b2c3d)
a1b2c3d...f4e5d6a Diffs the full range

Path (manual)

Import all TODOs from a specific file or directory:

apps/meteor/client
packages/core-typings/src/IMessage.ts

Only creates issues (no close/update). Skips TODOs that already have a matching issue.

Import all (manual)

Scans the entire codebase for TODOs. Only creates issues for TODOs that don't already have a matching issue. Use with caution on large codebases.

Matching logic

The script compares found TODOs against existing issues using:

  1. Exact title match -- identical titles are considered the same TODO
  2. Similarity match -- titles within 80% Levenshtein similarity are considered the same TODO (catches typo fixes and small edits)

When a TODO is both added and deleted in the same diff:

  • Same title -- treated as a move (no action)
  • Similar title -- treated as an edit (updates the existing issue title)

When a new TODO matches an existing open issue, a reference comment is added to the issue instead of creating a duplicate.

Rate limiting

The script reads x-ratelimit-remaining and x-ratelimit-reset from GitHub API response headers and automatically waits when approaching the limit.

Project structure

scripts/todo-issue/
├── package.json
├── tsconfig.json
└── src/
    ├── index.ts        # Entry point, config loading, diff resolution, orchestration
    ├── types.ts        # Shared interfaces (Config, TodoItem, GitHubIssue, MatchResult)
    ├── diff.ts         # Diff parsing (parse-diff), TODO extraction, body/label parsing
    ├── matcher.ts      # Match found TODOs against existing issues
    ├── similarity.ts   # Levenshtein distance and similarity check
    └── github.ts       # GitHub API (REST + GraphQL), rate limiting, issue CRUD