@codefresh-io/gitops-release 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +397 -0
  2. package/dist/commands/cherry-pick.d.ts +14 -0
  3. package/dist/commands/cherry-pick.d.ts.map +1 -0
  4. package/dist/commands/cherry-pick.js +337 -0
  5. package/dist/commands/cherry-pick.js.map +1 -0
  6. package/dist/commands/cherry-pick.test.d.ts +2 -0
  7. package/dist/commands/cherry-pick.test.d.ts.map +1 -0
  8. package/dist/commands/cherry-pick.test.js +377 -0
  9. package/dist/commands/cherry-pick.test.js.map +1 -0
  10. package/dist/commands/completion.d.ts +11 -0
  11. package/dist/commands/completion.d.ts.map +1 -0
  12. package/dist/commands/completion.js +195 -0
  13. package/dist/commands/completion.js.map +1 -0
  14. package/dist/commands/completion.test.d.ts +2 -0
  15. package/dist/commands/completion.test.d.ts.map +1 -0
  16. package/dist/commands/completion.test.js +142 -0
  17. package/dist/commands/completion.test.js.map +1 -0
  18. package/dist/commands/create.d.ts +15 -0
  19. package/dist/commands/create.d.ts.map +1 -0
  20. package/dist/commands/create.js +107 -0
  21. package/dist/commands/create.js.map +1 -0
  22. package/dist/commands/create.test.d.ts +2 -0
  23. package/dist/commands/create.test.d.ts.map +1 -0
  24. package/dist/commands/create.test.js +274 -0
  25. package/dist/commands/create.test.js.map +1 -0
  26. package/dist/commands/list.d.ts +14 -0
  27. package/dist/commands/list.d.ts.map +1 -0
  28. package/dist/commands/list.js +69 -0
  29. package/dist/commands/list.js.map +1 -0
  30. package/dist/commands/notes.d.ts +15 -0
  31. package/dist/commands/notes.d.ts.map +1 -0
  32. package/dist/commands/notes.js +374 -0
  33. package/dist/commands/notes.js.map +1 -0
  34. package/dist/commands/publish.d.ts +14 -0
  35. package/dist/commands/publish.d.ts.map +1 -0
  36. package/dist/commands/publish.js +220 -0
  37. package/dist/commands/publish.js.map +1 -0
  38. package/dist/commands/publish.test.d.ts +2 -0
  39. package/dist/commands/publish.test.d.ts.map +1 -0
  40. package/dist/commands/publish.test.js +371 -0
  41. package/dist/commands/publish.test.js.map +1 -0
  42. package/dist/commands/status.d.ts +8 -0
  43. package/dist/commands/status.d.ts.map +1 -0
  44. package/dist/commands/status.js +258 -0
  45. package/dist/commands/status.js.map +1 -0
  46. package/dist/context.d.ts +35 -0
  47. package/dist/context.d.ts.map +1 -0
  48. package/dist/context.js +48 -0
  49. package/dist/context.js.map +1 -0
  50. package/dist/index.d.ts +4 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +152 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/output/formatter.d.ts +161 -0
  55. package/dist/output/formatter.d.ts.map +1 -0
  56. package/dist/output/formatter.js +398 -0
  57. package/dist/output/formatter.js.map +1 -0
  58. package/dist/output/formatter.test.d.ts +2 -0
  59. package/dist/output/formatter.test.d.ts.map +1 -0
  60. package/dist/output/formatter.test.js +223 -0
  61. package/dist/output/formatter.test.js.map +1 -0
  62. package/dist/services/ai.d.ts +69 -0
  63. package/dist/services/ai.d.ts.map +1 -0
  64. package/dist/services/ai.js +235 -0
  65. package/dist/services/ai.js.map +1 -0
  66. package/dist/services/ai.test.d.ts +2 -0
  67. package/dist/services/ai.test.d.ts.map +1 -0
  68. package/dist/services/ai.test.js +101 -0
  69. package/dist/services/ai.test.js.map +1 -0
  70. package/dist/services/github.d.ts +200 -0
  71. package/dist/services/github.d.ts.map +1 -0
  72. package/dist/services/github.js +465 -0
  73. package/dist/services/github.js.map +1 -0
  74. package/dist/services/github.test.d.ts +2 -0
  75. package/dist/services/github.test.d.ts.map +1 -0
  76. package/dist/services/github.test.js +64 -0
  77. package/dist/services/github.test.js.map +1 -0
  78. package/dist/services/version.d.ts +106 -0
  79. package/dist/services/version.d.ts.map +1 -0
  80. package/dist/services/version.js +158 -0
  81. package/dist/services/version.js.map +1 -0
  82. package/dist/services/version.test.d.ts +2 -0
  83. package/dist/services/version.test.d.ts.map +1 -0
  84. package/dist/services/version.test.js +136 -0
  85. package/dist/services/version.test.js.map +1 -0
  86. package/dist/utils/errors.d.ts +66 -0
  87. package/dist/utils/errors.d.ts.map +1 -0
  88. package/dist/utils/errors.js +154 -0
  89. package/dist/utils/errors.js.map +1 -0
  90. package/dist/utils/errors.test.d.ts +2 -0
  91. package/dist/utils/errors.test.d.ts.map +1 -0
  92. package/dist/utils/errors.test.js +147 -0
  93. package/dist/utils/errors.test.js.map +1 -0
  94. package/dist/utils/prompts.d.ts +54 -0
  95. package/dist/utils/prompts.d.ts.map +1 -0
  96. package/dist/utils/prompts.js +108 -0
  97. package/dist/utils/prompts.js.map +1 -0
  98. package/package.json +70 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.test.js","sourceRoot":"","sources":["../../src/services/ai.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Repository identifier parsed from "owner/repo" format.
3
+ */
4
+ export interface RepoIdentifier {
5
+ owner: string;
6
+ repo: string;
7
+ }
8
+ /**
9
+ * Branch information returned from GitHub.
10
+ */
11
+ export interface BranchInfo {
12
+ name: string;
13
+ sha: string;
14
+ protected: boolean;
15
+ }
16
+ /**
17
+ * GitHub release information.
18
+ */
19
+ export interface ReleaseInfo {
20
+ id: number;
21
+ tag: string;
22
+ name: string;
23
+ draft: boolean;
24
+ prerelease: boolean;
25
+ publishedAt: string | null;
26
+ url: string;
27
+ body: string | null;
28
+ }
29
+ /**
30
+ * Pull request information.
31
+ */
32
+ export interface PullRequestInfo {
33
+ number: number;
34
+ title: string;
35
+ state: "open" | "closed";
36
+ draft: boolean;
37
+ headBranch: string;
38
+ baseBranch: string;
39
+ url: string;
40
+ labels: string[];
41
+ mergeable: boolean | null;
42
+ createdAt: string;
43
+ updatedAt: string;
44
+ }
45
+ /**
46
+ * Check run status for a PR or commit.
47
+ */
48
+ export interface CheckStatus {
49
+ totalCount: number;
50
+ passing: number;
51
+ failing: number;
52
+ pending: number;
53
+ allPassing: boolean;
54
+ checks: Array<{
55
+ name: string;
56
+ status: "queued" | "in_progress" | "completed";
57
+ conclusion: string | null;
58
+ }>;
59
+ }
60
+ /**
61
+ * Commit information.
62
+ */
63
+ export interface CommitInfo {
64
+ sha: string;
65
+ message: string;
66
+ author: string;
67
+ date: string;
68
+ url: string;
69
+ }
70
+ /**
71
+ * Options for listing pull requests.
72
+ */
73
+ export interface ListPullRequestsOptions {
74
+ state?: "open" | "closed" | "all";
75
+ head?: string;
76
+ base?: string;
77
+ sort?: "created" | "updated" | "popularity" | "long-running";
78
+ direction?: "asc" | "desc";
79
+ }
80
+ /**
81
+ * Parses a repository string in "owner/repo" format.
82
+ */
83
+ export declare function parseRepo(repo: string): RepoIdentifier;
84
+ /**
85
+ * GitHub API service wrapping Octokit.
86
+ */
87
+ export declare class GitHubService {
88
+ private octokit;
89
+ private repo;
90
+ constructor(token: string, repo: string);
91
+ /**
92
+ * Gets the repository identifier.
93
+ */
94
+ getRepo(): RepoIdentifier;
95
+ /**
96
+ * Gets information about a branch.
97
+ * Returns null if the branch doesn't exist.
98
+ */
99
+ getBranch(name: string): Promise<BranchInfo | null>;
100
+ /**
101
+ * Creates a new branch from a commit SHA.
102
+ */
103
+ createBranch(name: string, sha: string): Promise<BranchInfo>;
104
+ /**
105
+ * Gets the SHA of a ref (branch, tag, or commit).
106
+ */
107
+ getRefSha(ref: string): Promise<string>;
108
+ /**
109
+ * Lists GitHub releases.
110
+ */
111
+ listReleases(includeDrafts?: boolean): Promise<ReleaseInfo[]>;
112
+ /**
113
+ * Gets a specific release by tag name.
114
+ */
115
+ getRelease(tag: string): Promise<ReleaseInfo | null>;
116
+ /**
117
+ * Gets a draft release by tag name (searches all releases).
118
+ */
119
+ getDraftRelease(tag: string): Promise<ReleaseInfo | null>;
120
+ /**
121
+ * Updates a release's body (release notes).
122
+ */
123
+ updateRelease(releaseId: number, body: string): Promise<void>;
124
+ /**
125
+ * Lists pull requests with optional filters.
126
+ */
127
+ listPullRequests(options?: ListPullRequestsOptions): Promise<PullRequestInfo[]>;
128
+ /**
129
+ * Gets a specific pull request by number.
130
+ */
131
+ getPullRequest(number: number): Promise<PullRequestInfo | null>;
132
+ /**
133
+ * Finds a pull request by head branch.
134
+ */
135
+ findPullRequestByHead(headBranch: string): Promise<PullRequestInfo | null>;
136
+ /**
137
+ * Gets check run status for a PR.
138
+ */
139
+ getPullRequestChecks(prNumber: number): Promise<CheckStatus>;
140
+ /**
141
+ * Gets check run status for a commit or ref.
142
+ */
143
+ getCommitChecks(ref: string): Promise<CheckStatus>;
144
+ /**
145
+ * Merges a pull request using squash merge.
146
+ */
147
+ mergePullRequest(prNumber: number, commitTitle?: string): Promise<void>;
148
+ /**
149
+ * Creates a new pull request.
150
+ */
151
+ createPullRequest(options: {
152
+ title: string;
153
+ head: string;
154
+ base: string;
155
+ body?: string;
156
+ labels?: string[];
157
+ }): Promise<PullRequestInfo>;
158
+ /**
159
+ * Gets commits since a tag (for release notes generation).
160
+ */
161
+ getCommitsSince(tag: string, branch: string): Promise<CommitInfo[]>;
162
+ /**
163
+ * Gets file content from a branch.
164
+ */
165
+ getFileContent(path: string, ref: string): Promise<string | null>;
166
+ /**
167
+ * Updates a file on a branch.
168
+ */
169
+ updateFile(path: string, content: string, message: string, branch: string): Promise<void>;
170
+ /**
171
+ * Lists branches matching a pattern.
172
+ * Uses pagination to fetch all branches from the repository.
173
+ */
174
+ listBranches(pattern?: string): Promise<BranchInfo[]>;
175
+ /**
176
+ * Maps GitHub API release data to our ReleaseInfo type.
177
+ */
178
+ private mapRelease;
179
+ /**
180
+ * Maps GitHub API PR data to our PullRequestInfo type.
181
+ */
182
+ private mapPullRequest;
183
+ /**
184
+ * Checks if an error has a specific HTTP status code.
185
+ */
186
+ private hasStatusCode;
187
+ /**
188
+ * Checks if an error is a GitHub 404 Not Found error.
189
+ */
190
+ private isNotFoundError;
191
+ /**
192
+ * Checks if an error is a GitHub 422 Already Exists error.
193
+ */
194
+ private isAlreadyExistsError;
195
+ /**
196
+ * Wraps an unknown error into a GitHubError.
197
+ */
198
+ private wrapError;
199
+ }
200
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/services/github.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,465 @@
1
+ // ABOUTME: GitHub API wrapper using Octokit for all repository operations.
2
+ // ABOUTME: Provides methods for branches, releases, PRs, and file operations.
3
+ import { Octokit } from "octokit";
4
+ import { GitHubError, NotFoundError } from "../utils/errors.js";
5
+ /**
6
+ * Parses a repository string in "owner/repo" format.
7
+ */
8
+ export function parseRepo(repo) {
9
+ const parts = repo.split("/");
10
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
11
+ throw new GitHubError(`Invalid repository format '${repo}'. Expected: owner/repo (e.g., codefresh-io/gitops-runtime-helm)`);
12
+ }
13
+ return { owner: parts[0], repo: parts[1] };
14
+ }
15
+ /**
16
+ * GitHub API service wrapping Octokit.
17
+ */
18
+ export class GitHubService {
19
+ octokit;
20
+ repo;
21
+ constructor(token, repo) {
22
+ this.octokit = new Octokit({ auth: token });
23
+ this.repo = parseRepo(repo);
24
+ }
25
+ /**
26
+ * Gets the repository identifier.
27
+ */
28
+ getRepo() {
29
+ return this.repo;
30
+ }
31
+ /**
32
+ * Gets information about a branch.
33
+ * Returns null if the branch doesn't exist.
34
+ */
35
+ async getBranch(name) {
36
+ try {
37
+ const { data } = await this.octokit.rest.repos.getBranch({
38
+ ...this.repo,
39
+ branch: name,
40
+ });
41
+ return {
42
+ name: data.name,
43
+ sha: data.commit.sha,
44
+ protected: data.protected,
45
+ };
46
+ }
47
+ catch (error) {
48
+ if (this.isNotFoundError(error)) {
49
+ return null;
50
+ }
51
+ throw this.wrapError(error, `Failed to get branch '${name}'`);
52
+ }
53
+ }
54
+ /**
55
+ * Creates a new branch from a commit SHA.
56
+ */
57
+ async createBranch(name, sha) {
58
+ try {
59
+ await this.octokit.rest.git.createRef({
60
+ ...this.repo,
61
+ ref: `refs/heads/${name}`,
62
+ sha,
63
+ });
64
+ const branch = await this.getBranch(name);
65
+ if (!branch) {
66
+ throw new GitHubError(`Branch '${name}' was created but not found`);
67
+ }
68
+ return branch;
69
+ }
70
+ catch (error) {
71
+ if (this.isAlreadyExistsError(error)) {
72
+ throw new GitHubError(`Branch '${name}' already exists`);
73
+ }
74
+ throw this.wrapError(error, `Failed to create branch '${name}'`);
75
+ }
76
+ }
77
+ /**
78
+ * Gets the SHA of a ref (branch, tag, or commit).
79
+ */
80
+ async getRefSha(ref) {
81
+ try {
82
+ const { data } = await this.octokit.rest.repos.getCommit({
83
+ ...this.repo,
84
+ ref,
85
+ });
86
+ return data.sha;
87
+ }
88
+ catch (error) {
89
+ if (this.isNotFoundError(error)) {
90
+ throw new NotFoundError(`Ref '${ref}'`);
91
+ }
92
+ throw this.wrapError(error, `Failed to get ref '${ref}'`);
93
+ }
94
+ }
95
+ /**
96
+ * Lists GitHub releases.
97
+ */
98
+ async listReleases(includeDrafts = false) {
99
+ try {
100
+ const { data } = await this.octokit.rest.repos.listReleases({
101
+ ...this.repo,
102
+ per_page: 100,
103
+ });
104
+ const releases = data.map((r) => this.mapRelease(r));
105
+ if (includeDrafts) {
106
+ return releases;
107
+ }
108
+ return releases.filter((r) => !r.draft);
109
+ }
110
+ catch (error) {
111
+ throw this.wrapError(error, "Failed to list releases");
112
+ }
113
+ }
114
+ /**
115
+ * Gets a specific release by tag name.
116
+ */
117
+ async getRelease(tag) {
118
+ try {
119
+ const { data } = await this.octokit.rest.repos.getReleaseByTag({
120
+ ...this.repo,
121
+ tag,
122
+ });
123
+ return this.mapRelease(data);
124
+ }
125
+ catch (error) {
126
+ if (this.isNotFoundError(error)) {
127
+ return null;
128
+ }
129
+ throw this.wrapError(error, `Failed to get release '${tag}'`);
130
+ }
131
+ }
132
+ /**
133
+ * Gets a draft release by tag name (searches all releases).
134
+ */
135
+ async getDraftRelease(tag) {
136
+ const releases = await this.listReleases(true);
137
+ return releases.find((r) => r.tag === tag && r.draft) ?? null;
138
+ }
139
+ /**
140
+ * Updates a release's body (release notes).
141
+ */
142
+ async updateRelease(releaseId, body) {
143
+ try {
144
+ await this.octokit.rest.repos.updateRelease({
145
+ ...this.repo,
146
+ release_id: releaseId,
147
+ body,
148
+ });
149
+ }
150
+ catch (error) {
151
+ throw this.wrapError(error, `Failed to update release ${releaseId}`);
152
+ }
153
+ }
154
+ /**
155
+ * Lists pull requests with optional filters.
156
+ */
157
+ async listPullRequests(options = {}) {
158
+ try {
159
+ const { data } = await this.octokit.rest.pulls.list({
160
+ ...this.repo,
161
+ state: options.state ?? "open",
162
+ head: options.head,
163
+ base: options.base,
164
+ sort: options.sort ?? "created",
165
+ direction: options.direction ?? "desc",
166
+ per_page: 100,
167
+ });
168
+ return data.map((pr) => this.mapPullRequest(pr));
169
+ }
170
+ catch (error) {
171
+ throw this.wrapError(error, "Failed to list pull requests");
172
+ }
173
+ }
174
+ /**
175
+ * Gets a specific pull request by number.
176
+ */
177
+ async getPullRequest(number) {
178
+ try {
179
+ const { data } = await this.octokit.rest.pulls.get({
180
+ ...this.repo,
181
+ pull_number: number,
182
+ });
183
+ return this.mapPullRequest(data);
184
+ }
185
+ catch (error) {
186
+ if (this.isNotFoundError(error)) {
187
+ return null;
188
+ }
189
+ throw this.wrapError(error, `Failed to get PR #${number}`);
190
+ }
191
+ }
192
+ /**
193
+ * Finds a pull request by head branch.
194
+ */
195
+ async findPullRequestByHead(headBranch) {
196
+ const fullHead = `${this.repo.owner}:${headBranch}`;
197
+ const prs = await this.listPullRequests({ head: fullHead, state: "open" });
198
+ return prs[0] ?? null;
199
+ }
200
+ /**
201
+ * Gets check run status for a PR.
202
+ */
203
+ async getPullRequestChecks(prNumber) {
204
+ const pr = await this.getPullRequest(prNumber);
205
+ if (!pr) {
206
+ throw new NotFoundError(`PR #${prNumber}`);
207
+ }
208
+ return this.getCommitChecks(pr.headBranch);
209
+ }
210
+ /**
211
+ * Gets check run status for a commit or ref.
212
+ */
213
+ async getCommitChecks(ref) {
214
+ try {
215
+ const { data } = await this.octokit.rest.checks.listForRef({
216
+ ...this.repo,
217
+ ref,
218
+ });
219
+ const checks = data.check_runs.map((cr) => ({
220
+ name: cr.name,
221
+ status: cr.status,
222
+ conclusion: cr.conclusion,
223
+ }));
224
+ const passing = checks.filter((c) => c.status === "completed" && c.conclusion === "success").length;
225
+ const failing = checks.filter((c) => c.status === "completed" &&
226
+ c.conclusion !== "success" &&
227
+ c.conclusion !== "skipped" &&
228
+ c.conclusion !== "neutral").length;
229
+ const pending = checks.filter((c) => c.status !== "completed").length;
230
+ return {
231
+ totalCount: checks.length,
232
+ passing,
233
+ failing,
234
+ pending,
235
+ allPassing: failing === 0 && pending === 0 && checks.length > 0,
236
+ checks,
237
+ };
238
+ }
239
+ catch (error) {
240
+ throw this.wrapError(error, `Failed to get checks for '${ref}'`);
241
+ }
242
+ }
243
+ /**
244
+ * Merges a pull request using squash merge.
245
+ */
246
+ async mergePullRequest(prNumber, commitTitle) {
247
+ try {
248
+ await this.octokit.rest.pulls.merge({
249
+ ...this.repo,
250
+ pull_number: prNumber,
251
+ merge_method: "squash",
252
+ commit_title: commitTitle,
253
+ });
254
+ }
255
+ catch (error) {
256
+ throw this.wrapError(error, `Failed to merge PR #${prNumber}`);
257
+ }
258
+ }
259
+ /**
260
+ * Creates a new pull request.
261
+ */
262
+ async createPullRequest(options) {
263
+ try {
264
+ const { data } = await this.octokit.rest.pulls.create({
265
+ ...this.repo,
266
+ title: options.title,
267
+ head: options.head,
268
+ base: options.base,
269
+ body: options.body,
270
+ });
271
+ // Add labels if specified
272
+ if (options.labels && options.labels.length > 0) {
273
+ await this.octokit.rest.issues.addLabels({
274
+ ...this.repo,
275
+ issue_number: data.number,
276
+ labels: options.labels,
277
+ });
278
+ }
279
+ // Fetch the PR again to get updated labels
280
+ const pr = await this.getPullRequest(data.number);
281
+ if (!pr) {
282
+ throw new GitHubError(`PR #${data.number} was created but not found`);
283
+ }
284
+ return pr;
285
+ }
286
+ catch (error) {
287
+ throw this.wrapError(error, "Failed to create pull request");
288
+ }
289
+ }
290
+ /**
291
+ * Gets commits since a tag (for release notes generation).
292
+ */
293
+ async getCommitsSince(tag, branch) {
294
+ try {
295
+ const { data } = await this.octokit.rest.repos.compareCommits({
296
+ ...this.repo,
297
+ base: tag,
298
+ head: branch,
299
+ });
300
+ return data.commits.map((c) => ({
301
+ sha: c.sha,
302
+ message: c.commit.message,
303
+ author: c.commit.author?.name ?? "Unknown",
304
+ date: c.commit.author?.date ?? "",
305
+ url: c.html_url,
306
+ }));
307
+ }
308
+ catch (error) {
309
+ if (this.isNotFoundError(error)) {
310
+ throw new NotFoundError(`Tag '${tag}' or branch '${branch}'`);
311
+ }
312
+ throw this.wrapError(error, `Failed to get commits between '${tag}' and '${branch}'`);
313
+ }
314
+ }
315
+ /**
316
+ * Gets file content from a branch.
317
+ */
318
+ async getFileContent(path, ref) {
319
+ try {
320
+ const { data } = await this.octokit.rest.repos.getContent({
321
+ ...this.repo,
322
+ path,
323
+ ref,
324
+ });
325
+ if ("content" in data && data.type === "file") {
326
+ return Buffer.from(data.content, "base64").toString("utf-8");
327
+ }
328
+ return null;
329
+ }
330
+ catch (error) {
331
+ if (this.isNotFoundError(error)) {
332
+ return null;
333
+ }
334
+ throw this.wrapError(error, `Failed to get file '${path}'`);
335
+ }
336
+ }
337
+ /**
338
+ * Updates a file on a branch.
339
+ */
340
+ async updateFile(path, content, message, branch) {
341
+ try {
342
+ // First get the current file to get its SHA
343
+ const { data: currentFile } = await this.octokit.rest.repos.getContent({
344
+ ...this.repo,
345
+ path,
346
+ ref: branch,
347
+ });
348
+ if (!("sha" in currentFile)) {
349
+ throw new GitHubError(`Path '${path}' is not a file`);
350
+ }
351
+ await this.octokit.rest.repos.createOrUpdateFileContents({
352
+ ...this.repo,
353
+ path,
354
+ message,
355
+ content: Buffer.from(content).toString("base64"),
356
+ sha: currentFile.sha,
357
+ branch,
358
+ });
359
+ }
360
+ catch (error) {
361
+ throw this.wrapError(error, `Failed to update file '${path}'`);
362
+ }
363
+ }
364
+ /**
365
+ * Lists branches matching a pattern.
366
+ * Uses pagination to fetch all branches from the repository.
367
+ */
368
+ async listBranches(pattern) {
369
+ try {
370
+ const allBranches = [];
371
+ // Use pagination to get all branches
372
+ for await (const response of this.octokit.paginate.iterator(this.octokit.rest.repos.listBranches, {
373
+ ...this.repo,
374
+ per_page: 100,
375
+ })) {
376
+ for (const b of response.data) {
377
+ const branch = {
378
+ name: b.name,
379
+ sha: b.commit.sha,
380
+ protected: b.protected,
381
+ };
382
+ // If pattern is provided, only add matching branches
383
+ if (pattern) {
384
+ const regex = new RegExp(pattern);
385
+ if (regex.test(branch.name)) {
386
+ allBranches.push(branch);
387
+ }
388
+ }
389
+ else {
390
+ allBranches.push(branch);
391
+ }
392
+ }
393
+ }
394
+ return allBranches;
395
+ }
396
+ catch (error) {
397
+ throw this.wrapError(error, "Failed to list branches");
398
+ }
399
+ }
400
+ /**
401
+ * Maps GitHub API release data to our ReleaseInfo type.
402
+ */
403
+ mapRelease(data) {
404
+ return {
405
+ id: data.id,
406
+ tag: data.tag_name,
407
+ name: data.name ?? data.tag_name,
408
+ draft: data.draft,
409
+ prerelease: data.prerelease,
410
+ publishedAt: data.published_at,
411
+ url: data.html_url,
412
+ body: data.body ?? null,
413
+ };
414
+ }
415
+ /**
416
+ * Maps GitHub API PR data to our PullRequestInfo type.
417
+ */
418
+ mapPullRequest(data) {
419
+ return {
420
+ number: data.number,
421
+ title: data.title,
422
+ state: data.state,
423
+ draft: data.draft ?? false,
424
+ headBranch: data.head.ref,
425
+ baseBranch: data.base.ref,
426
+ url: data.html_url,
427
+ labels: data.labels.map((l) => l.name ?? "").filter(Boolean),
428
+ mergeable: data.mergeable ?? null,
429
+ createdAt: data.created_at,
430
+ updatedAt: data.updated_at,
431
+ };
432
+ }
433
+ /**
434
+ * Checks if an error has a specific HTTP status code.
435
+ */
436
+ hasStatusCode(error, statusCode) {
437
+ return (error instanceof Error && "status" in error && error.status === statusCode);
438
+ }
439
+ /**
440
+ * Checks if an error is a GitHub 404 Not Found error.
441
+ */
442
+ isNotFoundError(error) {
443
+ return this.hasStatusCode(error, 404);
444
+ }
445
+ /**
446
+ * Checks if an error is a GitHub 422 Already Exists error.
447
+ */
448
+ isAlreadyExistsError(error) {
449
+ return this.hasStatusCode(error, 422);
450
+ }
451
+ /**
452
+ * Wraps an unknown error into a GitHubError.
453
+ */
454
+ wrapError(error, context) {
455
+ if (error instanceof GitHubError) {
456
+ return error;
457
+ }
458
+ const message = error instanceof Error ? error.message : "Unknown error occurred";
459
+ const statusCode = error instanceof Error && "status" in error
460
+ ? error.status
461
+ : undefined;
462
+ return new GitHubError(`${context}: ${message}`, statusCode);
463
+ }
464
+ }
465
+ //# sourceMappingURL=github.js.map