23 lines · 1.0 KB
const ISSUE_KEY = /(?:^|[^A-Za-z0-9])([A-Za-z][A-Za-z0-9]{0,9})-(\d{1,7})(?![A-Za-z0-9])/g;
const MAX_KEYS = 10;

/**
 * Finds Linear issue keys (`ENG-123`) in branch names, PR titles and commit messages. Branches are usually
 * lower-cased (`eng-123-fix-login`), so matching is case-insensitive and keys are upper-cased. `teams`, when
 * given, limits matches to known team keys so `utf-8` or `sha-256` are not mistaken for issues.
 */
export function extractIssueKeys(texts: Array<string | null | undefined>, teams: string[] = []): string[] {
  const allowed = new Set(teams.map((team) => team.toUpperCase()));
  const found = new Set<string>();
  for (const text of texts) {
    if (!text) continue;
    for (const match of text.matchAll(ISSUE_KEY)) {
      const team = match[1].toUpperCase();
      if (allowed.size > 0 ? !allowed.has(team) : !/^[A-Z][A-Z0-9]*$/.test(match[1])) continue;
      found.add(`${team}-${Number(match[2])}`);
      if (found.size >= MAX_KEYS) return [...found];
    }
  }
  return [...found];
}