UNPKG

mediumroast_api

Version:

Mediumroast for Git(Hub) SDK covering all categories of function.

204 lines (180 loc) 6.07 kB
/** * @fileoverview Billing operations for GitHub * @license Apache-2.0 * @version 3.0.0 * @author Michael Hay <michael.hay@mediumroast.io> * @copyright 2025 Mediumroast, Inc. All rights reserved. */ import ResponseFactory from './response.js'; /** * Manages GitHub billing operations */ class BillingManager { /** * @constructor * @param {Object} octokit - Octokit instance * @param {String} orgName - GitHub organization name */ constructor(octokit, orgName) { this.octokit = octokit; this.orgName = orgName; this.repoName = `${orgName}_discovery`; // Default repo name, can be overridden } /** * Gets GitHub Actions billing information for the organization * @returns {Promise<Array>} ResponseFactory result */ async getActionsBillings() { try { const response = await this.octokit.rest.billing.getGithubActionsBillingOrg({ org: this.orgName, }); return ResponseFactory.success( `Successfully retrieved Actions billing information for organization ${this.orgName}`, response.data ); } catch (err) { return ResponseFactory.error( `Failed to retrieve Actions billing information: ${err.message}`, err, err.status || 500 ); } } /** * Gets GitHub Packages storage billing information for the organization * @returns {Promise<Array>} ResponseFactory result */ async getStorageBillings() { try { const response = await this.octokit.rest.billing.getSharedStorageBillingOrg({ org: this.orgName, }); return ResponseFactory.success( `Successfully retrieved storage billing information for organization ${this.orgName}`, response.data ); } catch (err) { return ResponseFactory.error( `Failed to retrieve storage billing information: ${err.message}`, err, err.status || 500 ); } } /** * Gets GitHub Packages billing information for the organization * @returns {Promise<Array>} ResponseFactory result */ async getPackagesBillings() { try { const response = await this.octokit.rest.billing.getGithubPackagesBillingOrg({ org: this.orgName, }); return ResponseFactory.success( `Successfully retrieved Packages billing information for organization ${this.orgName}`, response.data ); } catch (err) { return ResponseFactory.error( `Failed to retrieve Packages billing information: ${err.message}`, err, err.status || 500 ); } } /** * Gets all billing information for the organization * @returns {Promise<Array>} ResponseFactory result with combined billing data */ async getAllBillings() { try { const [actionsResult, storageResult, packagesResult] = await Promise.all([ this.getActionsBillings(), this.getStorageBillings(), this.getPackagesBillings() ]); if (!actionsResult[0] || !storageResult[0] || !packagesResult[0]) { const failedRequests = []; if (!actionsResult[0]) failedRequests.push('Actions'); if (!storageResult[0]) failedRequests.push('Storage'); if (!packagesResult[0]) failedRequests.push('Packages'); return ResponseFactory.error( `Failed to retrieve some billing information: ${failedRequests.join(', ')}`, { actionsResult, storageResult, packagesResult }, 500 ); } const combinedData = { actions: actionsResult[2], storage: storageResult[2], packages: packagesResult[2] }; return ResponseFactory.success( `Successfully retrieved all billing information for organization ${this.orgName}`, combinedData ); } catch (err) { return ResponseFactory.error( `Failed to retrieve billing information: ${err.message}`, err ); } } /** * Gets workflow runs for a specific repository in the organization * @param {string} repoName - Repository name * @returns {Promise<Array>} ResponseFactory result with workflow runs data */ async getWorkflowRuns(repoName) { try { const response = await this.octokit.rest.actions.listWorkflowRunsForRepo({ owner: this.orgName, repo: repoName }); const workflowList = []; let totalRunTimeThisMonth = 0; const currentMonth = new Date().getMonth(); for (const workflow of response.data.workflow_runs) { // Calculate runtime in minutes (minimum 1 minute) const runTime = Math.ceil( (new Date(workflow.updated_at) - new Date(workflow.created_at)) / 1000 / 60 ) || 1; // Skip workflows not from current month if (new Date(workflow.updated_at).getMonth() !== currentMonth) { continue; } totalRunTimeThisMonth += runTime; // Add formatted workflow data to list workflowList.push({ name: workflow.path.replace('.github/workflows/', '').replace('.yml', ''), title: workflow.display_title, id: workflow.id, workflowId: workflow.workflow_id, runTimeMinutes: runTime, status: workflow.status, conclusion: workflow.conclusion, event: workflow.event, path: workflow.path }); } // Sort by updated_at (most recent first) workflowList.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at)); return ResponseFactory.success( `Discovered ${workflowList.length} workflow runs for repository ${repoName}`, { workflowList, totalRunTimeThisMonth, repository: repoName } ); } catch (err) { return ResponseFactory.error( `Failed to retrieve workflow runs: ${err.message}`, err, err.status || 500 ); } } } export default BillingManager;