/** * GiteaClient - Low-level API wrapper for Gitea Git Hosting */ /** * Helper to ensure the base URL always points to the Gitea API root (/api/v1) * @return {string} Normalized API base URL */ function getGiteaApiBaseUrl_() { const config = getGiteaConfig(); let baseUrl = config.baseUrl.replace(/\/$/, ''); // Remove trailing slash // Ensure the URL ends with /api/v1 if (!baseUrl.endsWith('/api/v1')) { baseUrl += '/api/v1'; } return baseUrl; } function giteaRequest_(method, path, payload = null) { const apiBaseUrl = getGiteaApiBaseUrl_(); const config = getGiteaConfig(); // Ensure path starts with a single slash const normalizedPath = path.startsWith('/') ? path : '/' + path; const url = `${apiBaseUrl}${normalizedPath}`; console.log(`Gitea Request: [${method}] ${url}`); const options = { method: method, headers: { 'Authorization': `token ${config.token}`, 'Content-Type': 'application/json' }, muteHttpExceptions: true }; if (payload) { options.payload = JSON.stringify(payload); } try { const response = UrlFetchApp.fetch(url, options); const code = response.getResponseCode(); const rawContent = response.getContentText(); let json; try { json = JSON.parse(rawContent); } catch (e) { json = null; // Not a JSON response } if (code >= 200 && code < 300) { return { ok: true, data: json || rawContent }; } // Return structured error with raw body if JSON parsing failed return { ok: false, message: json && json.message ? json.message : `Gitea API Error ${code}`, code: code, rawBody: rawContent }; } catch (e) { return { ok: false, message: `Gitea Connection Error: ${e.message}` }; } } function getGiteaRepo() { const config = getGiteaConfig(); // Path is relative to /api/v1 return giteaRequest_('GET', `/repos/${config.owner}/${config.repo}`); } function createGiteaIssue(title, body) { const config = getGiteaConfig(); return giteaRequest_('POST', `/repos/${config.owner}/${config.repo}/issues`, { title: title, body: body }); } function createOrUpdateRepoFile(path, content, message, branch) { const config = getGiteaConfig(); const targetBranch = branch || config.branch; // Gitea requires SHA for updates. This is a simplified boilerplate. return giteaRequest_('POST', `/repos/${config.owner}/${config.repo}/contents/${path}`, { content: content, message: message, branch: targetBranch }); } function createReleaseTag(tagName, name, body, target) { const config = getGiteaConfig(); return giteaRequest_('POST', `/repos/${config.owner}/${config.repo}/releases`, { tag_name: tagName, name: name, body: body, target_commitish: target || config.branch }); }