feat: link commits, branches and pull requests to tickets

A project can turn on a webhook for GitHub, Gitea or GitLab. Pushes and
pull or merge requests that name a ticket key show on that ticket under
Desarrollo, with the state of each pull request; the secret is shown and
rotated from the project settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 15:28:12 +02:00
parent 24b37b6628
commit 046d77c813
48 changed files with 2638 additions and 12 deletions

View File

@@ -151,10 +151,33 @@ export interface Issue extends IssueSummary {
/** People following the ticket. */
watchers: UserRef[];
checklist: ChecklistItem[];
/** Commits, branches and pull requests that mention it. */
devLinks: DevLink[];
allowedTransitions: string[];
createdAt: string;
}
/** A commit, branch or pull request that mentions a ticket. */
export interface DevLink {
kind: 'COMMIT' | 'BRANCH' | 'PULL_REQUEST';
url: string;
title: string;
/** Short SHA, branch or PR number. */
ref: string;
state: 'OPEN' | 'MERGED' | 'CLOSED' | null;
provider: string;
author: string | null;
at: string;
}
/** The project's webhook for GitHub, Gitea or GitLab. */
export interface GitIntegration {
enabled: boolean;
/** Only for owners and admins. */
secret: string | null;
webhookPath: string;
}
export interface Comment {
id: string;
issueId: string;

View File

@@ -5,6 +5,7 @@ import {
BoardColumn,
Comment,
Epic,
GitIntegration,
SavedFilter,
Sprint,
SprintBurndown,
@@ -130,6 +131,14 @@ export abstract class IssuesGateway {
): Observable<CommandResult>;
}
/** The project's Git webhook (owners and admins configure it). */
export abstract class GitGateway {
abstract integration(projectId: string): Observable<GitIntegration>;
/** On with a new secret (also to rotate it). */
abstract enable(projectId: string): Observable<GitIntegration>;
abstract disable(projectId: string): Observable<void>;
}
/** Saved views of a project's board (mine and the shared ones). */
export abstract class SavedFiltersGateway {
abstract list(projectId: string): Observable<SavedFilter[]>;