UNPKG

remcode

Version:

Turn your AI assistant into a codebase expert. Intelligent code analysis, semantic search, and software engineering guidance through MCP integration.

139 lines (138 loc) 5.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GitHubActions = void 0; const logger_1 = require("../utils/logger"); const logger = (0, logger_1.getLogger)('GitHubActions'); class GitHubActions { constructor(client) { this.client = client; } /** * List workflows in a repository */ async listWorkflows(owner, repo) { logger.info(`Listing workflows for ${owner}/${repo}`); const response = await this.client.makeRequest(`/repos/${owner}/${repo}/actions/workflows`); return response.workflows || []; } /** * Get workflow by ID or filename */ async getWorkflow(owner, repo, workflowIdOrFilename) { // Handle both numeric IDs and filename paths const isNumeric = /^\d+$/.test(workflowIdOrFilename); const endpoint = `/repos/${owner}/${repo}/actions/workflows/${workflowIdOrFilename}`; logger.info(`Getting workflow ${workflowIdOrFilename} for ${owner}/${repo}`); return this.client.makeRequest(endpoint); } /** * List workflow runs for a specific workflow or all workflows in a repo */ async getWorkflowRuns(owner, repo, workflowId, options = {}) { let endpoint = workflowId ? `/repos/${owner}/${repo}/actions/workflows/${workflowId}/runs` : `/repos/${owner}/${repo}/actions/runs`; // Add query parameters for branch and status filtering const queryParams = []; if (options.branch) { queryParams.push(`branch=${options.branch}`); } if (options.status) { queryParams.push(`status=${options.status}`); } if (queryParams.length > 0) { endpoint += `?${queryParams.join('&')}`; } logger.info(`Getting workflow runs for ${owner}/${repo}${workflowId ? `/${workflowId}` : ''}`); const response = await this.client.makeRequest(endpoint); return response.workflow_runs || []; } /** * Trigger a workflow dispatch event */ async triggerWorkflow(owner, repo, workflowId, ref = 'main', inputs) { logger.info(`Triggering workflow: ${workflowId} on ref ${ref}`); await this.client.createWorkflowDispatch(owner, repo, workflowId, ref, inputs); logger.info(`Successfully triggered workflow ${workflowId}`); } /** * Get the status of a specific workflow run */ async getWorkflowStatus(owner, repo, runId) { try { logger.info(`Getting workflow run status: ${runId}`); const workflowRun = await this.client.makeRequest(`/repos/${owner}/${repo}/actions/runs/${runId}`); return workflowRun; } catch (error) { logger.error(`Failed to get workflow run status: ${error instanceof Error ? error.message : String(error)}`); return null; } } /** * Get jobs for a specific workflow run */ async getWorkflowJobs(owner, repo, runId) { logger.info(`Getting jobs for workflow run: ${runId}`); const response = await this.client.makeRequest(`/repos/${owner}/${repo}/actions/runs/${runId}/jobs`); return response.jobs || []; } /** * Download workflow run logs */ async downloadWorkflowLogs(owner, repo, runId) { logger.info(`Downloading logs for workflow run: ${runId}`); const response = await this.client.makeRequest(`/repos/${owner}/${repo}/actions/runs/${runId}/logs`, 'GET', undefined, { responseType: 'arraybuffer' }); return Buffer.from(response); } /** * Cancel a workflow run */ async cancelWorkflowRun(owner, repo, runId) { logger.info(`Cancelling workflow run: ${runId}`); await this.client.makeRequest(`/repos/${owner}/${repo}/actions/runs/${runId}/cancel`, 'POST'); logger.info(`Successfully cancelled workflow run ${runId}`); } /** * Re-run a workflow */ async rerunWorkflow(owner, repo, runId, onlyFailedJobs = false) { const endpoint = onlyFailedJobs ? `/repos/${owner}/${repo}/actions/runs/${runId}/rerun-failed-jobs` : `/repos/${owner}/${repo}/actions/runs/${runId}/rerun`; logger.info(`Re-running workflow run: ${runId}${onlyFailedJobs ? ' (failed jobs only)' : ''}`); await this.client.makeRequest(endpoint, 'POST'); logger.info(`Successfully re-ran workflow run ${runId}`); } /** * Wait for a workflow run to complete, with polling and timeout */ async waitForWorkflowCompletion(owner, repo, runId, timeoutMs = 300000, pollIntervalMs = 5000) { logger.info(`Waiting for workflow completion: ${runId} (timeout: ${timeoutMs}ms, polling: ${pollIntervalMs}ms)`); const startTime = Date.now(); let lastStatus = ''; while (true) { // Check if we've timed out if (Date.now() - startTime > timeoutMs) { throw new Error(`Workflow run ${runId} did not complete within the timeout period (${timeoutMs}ms)`); } // Get the current status const run = await this.getWorkflowStatus(owner, repo, runId); if (!run) { throw new Error(`Workflow run ${runId} not found`); } // Log status changes if (run.status !== lastStatus) { logger.info(`Workflow run ${runId} status: ${run.status}${run.conclusion ? ` (${run.conclusion})` : ''}`); lastStatus = run.status; } // Check if the workflow has completed if (run.status === 'completed') { return run; } // Wait before polling again await new Promise(resolve => setTimeout(resolve, pollIntervalMs)); } } } exports.GitHubActions = GitHubActions;