Release ForgeFlow 0.8.1
Add advanced Git and deployment workflows, secure backups and auditing, live Gitea integration, desktop notifications, connection validation, and the premium responsive UX refresh.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { normalizeBaseUrl } = require('../shared/validation.cjs');
|
||||
const { normalizeBaseUrl, assertBranchName } = require('../shared/validation.cjs');
|
||||
const { redactSecrets } = require('./log-redaction.cjs');
|
||||
|
||||
class GiteaService {
|
||||
@@ -107,6 +107,44 @@ class GiteaService {
|
||||
return (await this.request(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/branches/${encodeURIComponent(branch)}`)).data;
|
||||
}
|
||||
|
||||
async getBranchProtection(owner, repo, branch) {
|
||||
const branchInfo = await this.getBranch(owner, repo, branch);
|
||||
let rule = null;
|
||||
try {
|
||||
const result = await this.request(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/branch_protections`);
|
||||
const rules = Array.isArray(result.data) ? result.data : [];
|
||||
rule = rules.find((item) => item.branch_name === branch || item.rule_name === branch) || null;
|
||||
} catch (error) {
|
||||
if (![403, 404].includes(error.status)) throw error;
|
||||
}
|
||||
return {
|
||||
branch,
|
||||
protected: Boolean(branchInfo?.protected || rule),
|
||||
enablePush: rule?.enable_push ?? null,
|
||||
enableForcePush: rule?.enable_force_push ?? false,
|
||||
requiredApprovals: Number(rule?.required_approvals || 0),
|
||||
requireSignedCommits: Boolean(rule?.require_signed_commits),
|
||||
rule
|
||||
};
|
||||
}
|
||||
|
||||
async listPullRequests({ owner, repo, state = 'open', limit = 30 } = {}) {
|
||||
const query = new URLSearchParams({ state, limit: String(Math.min(Math.max(Number(limit) || 30, 1), 50)) });
|
||||
const result = await this.request(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls?${query}`);
|
||||
return Array.isArray(result.data) ? result.data : [];
|
||||
}
|
||||
|
||||
async createPullRequest({ owner, repo, head, base, title, body = '' }) {
|
||||
const cleanTitle = String(title || '').trim();
|
||||
if (!cleanTitle || cleanTitle.length > 255) throw new Error('Pull request title must contain 1-255 characters.');
|
||||
const cleanBody = String(body || '').trim().slice(0, 50_000);
|
||||
const source = assertBranchName(head);
|
||||
const target = assertBranchName(base);
|
||||
if (source === target) throw new Error('Pull request source and target branches must be different.');
|
||||
const result = await this.request(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls`, { method: 'POST', body: { head: source, base: target, title: cleanTitle, body: cleanBody }, timeout: 60_000 });
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async getRepositoryFile({ owner, repo, filePath, ref }) {
|
||||
const encodedPath = String(filePath || '').split('/').map(encodeURIComponent).join('/');
|
||||
const query = ref ? `?ref=${encodeURIComponent(ref)}` : '';
|
||||
|
||||
Reference in New Issue
Block a user