diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..02a33cb --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,158 @@ +# GitArmor +GitArmor is a TypeScript Node.js project that functions as both a GitHub Action and CLI tool for security assessments of GitHub repositories and organizations. It transforms DevOps platform security policies into YAML policies as code and runs checks against GitHub environments. + +Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. + +## Working Effectively + +### Bootstrap and Build +- Check Node.js version (requires v18+): `node --version` +- Install dependencies: `npm install` -- takes ~5 seconds. NEVER CANCEL. Set timeout to 60+ seconds. +- Build the project: `npm run build` -- takes ~11 seconds. NEVER CANCEL. Set timeout to 60+ seconds. + - This runs: `npm run clean && tsc && ncc build ./src/main.ts -o dist --license licenses.txt` + - Compiles TypeScript source in `src/` to JavaScript + - Bundles everything into `dist/index.js` using ncc for GitHub Action distribution + +### Code Quality and Formatting +- Check code formatting: `npm run prettier:check` -- takes ~1 second +- Fix code formatting: `npm run prettier:write` -- takes ~1 second +- Check security vulnerabilities: `npm audit` -- takes ~1 second +- **DO NOT run `npm audit fix`** -- it introduces TypeScript compilation errors due to dependency version conflicts + +### Configuration and Setup +- Copy `.env.sample` to `.env` and configure: + ```bash + cp .env.sample .env + ``` +- Required environment variables in `.env`: + - `TOKEN`: GitHub Personal Access Token with repo:admin and org:admin permissions + - `LEVEL`: `repository_only`, `organization_only`, or `organization_and_repository` + - `REPO`: Repository name (when using repository-level checks) + - `ORG`: Organization name + - `DEBUG`: `true` or `false` + - `POLICY_DIR`: Path to policies directory (default: `./policies`) + +### Running the Application +- CLI mode: `npm run start` -- builds and runs, takes ~11 seconds + runtime. NEVER CANCEL. Set timeout to 300+ seconds. +- Direct execution after build: `node ./dist/index.js` + +## Validation + +### Manual Testing Scenarios +ALWAYS test these scenarios after making changes: + +1. **Build Validation**: + ```bash + npm install + npm run build + ``` + - Build should complete successfully in ~11 seconds + - Should generate `dist/index.js` and `dist/licenses.txt` + +2. **Code Quality Validation**: + ```bash + npm run prettier:check + npm run prettier:write + npm audit + ``` + - Prettier should pass or auto-fix formatting issues + - npm audit will show 4 moderate vulnerabilities (known issue, do not fix) + +3. **CLI Functionality Test**: + ```bash + # Create test .env with fake token + echo "TOKEN=fake_token_for_testing + LEVEL=repository_only + REPO=gitarmor + ORG=dcodx + DEBUG=true + POLICY_DIR=./policies" > .env + + npm run start + ``` + - Should start successfully, load policies, and fail with "Blocked by DNS monitoring proxy" or authentication error (expected with fake token) + - Should show GitArmor banner and debug information + +4. **Policy Loading Test**: + - Verify `policies/repository.yml` and `policies/organization.yml` exist and are valid YAML + - Application should load policies without errors during startup + +### GitHub Action Testing +- The project includes example workflows in `.github/workflows/`: + - `gitarmor-on-demand.yml` - Manual trigger workflow + - `gitarmor-scheduled.yml` - Scheduled daily workflow +- Action defined in `action.yml` with Node 20 runtime +- Outputs: `check-results-json` and `check-results-text` + +## Common Tasks + +### Repository Structure +``` +ls -la +.env.sample +.github/ # GitHub workflows and documentation +.gitignore +LICENSE +README.md +action.yml # GitHub Action definition +dist/ # Built artifacts (created by npm run build) +package.json # Dependencies and scripts +policies/ # YAML policy definitions +src/ # TypeScript source code +tsconfig.json # TypeScript configuration +``` + +### Key Source Directories +``` +ls -la src/ +evaluators/ # Policy evaluation logic +github/ # GitHub API interaction +main.ts # Application entry point +reporting/ # Report generation +types/ # TypeScript type definitions +utils/ # Utility functions (logger, input parsing, etc.) +``` + +### Policy Files +``` +ls -la policies/ +organization.yml # Organization-level security policies +organization.readme.md +organization.threats.md +repository.yml # Repository-level security policies +repository.readme.md +repository.threats.md +``` + +### Package.json Scripts +- `npm run test` -- Currently not implemented (exits with error) +- `npm run clean` -- Removes dist directory contents +- `npm run build` -- Full build: clean + compile + bundle +- `npm run prettier:write` -- Auto-fix code formatting +- `npm run prettier:check` -- Check code formatting +- `npm run start` -- Build and run CLI application + +## Important Notes + +### Critical Warnings +- **NEVER CANCEL** any build or test command. Set timeouts of 60+ seconds minimum. +- **DO NOT run `npm audit fix`** - it breaks the build due to dependency version conflicts. +- Always run `npm run prettier:write` before committing to ensure consistent formatting. +- The `.env` file contains sensitive tokens - it's already in `.gitignore`. + +### Known Issues +- 4 moderate security vulnerabilities in dependencies (@octokit packages and undici) +- No test suite currently implemented +- TypeScript import paths are case-sensitive (use lowercase: `logger`, `input`) + +### Working with GitHub API +- Requires valid GitHub token with appropriate permissions +- Tool makes extensive API calls - organization_and_repository level may hit rate limits +- Supports repository-only, organization-only, or both levels of analysis +- Generates reports in both JSON and Markdown formats (`output-report.json`, `output-report.md`) + +### Development Tips +- Check `src/utils/input.ts` for understanding input parameter parsing +- Policy definitions in `policies/` directory control what security checks are performed +- Logger configuration in `src/utils/logger.ts` - set DEBUG=true for verbose output +- Main application logic in `src/main.ts` coordinates policy evaluation and reporting \ No newline at end of file diff --git a/dist/evaluators/OrgPolicyEvaluator.js b/dist/evaluators/OrgPolicyEvaluator.js index ad13600..abc437a 100644 --- a/dist/evaluators/OrgPolicyEvaluator.js +++ b/dist/evaluators/OrgPolicyEvaluator.js @@ -1,7 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OrgPolicyEvaluator = void 0; -const Logger_1 = require("../utils/Logger"); +const logger_1 = require("../utils/logger"); const OrgGHASChecks_1 = require("./organization/OrgGHASChecks"); const OrgAuthenticationChecks_1 = require("./organization/OrgAuthenticationChecks"); const OrgCustomRolesChecks_1 = require("./organization/OrgCustomRolesChecks"); @@ -19,43 +19,43 @@ class OrgPolicyEvaluator { } // This method evaluates the policy for the repository async evaluatePolicy() { - Logger_1.logger.info("Running checks for organization policy against: " + + logger_1.logger.info("Running checks for organization policy against: " + this.organization.name); - Logger_1.logger.debug("Organization policy for org: " + this.organization.name); + logger_1.logger.debug("Organization policy for org: " + this.organization.name); // Get the organization data from the API this.organization.data = await (0, Organization_1.getOrganization)(this.organization.name); // Check MemberPrivileges policy rule if (this.policy.member_privileges) { const member_privileges = await new PrivilegesChecks_1.PrivilegesChecks(this.organization, this.policy).checkPrivileges(); - Logger_1.logger.debug(`Member privileges results: ${JSON.stringify(member_privileges)}`); + logger_1.logger.debug(`Member privileges results: ${JSON.stringify(member_privileges)}`); this.orgCheckResults.push(member_privileges); } // Check org level GHAS settings if (this.policy.advanced_security) { const ghas_checks = await new OrgGHASChecks_1.OrgGHASChecks(this.policy, this.organization, this.organization.data).evaluate(); - Logger_1.logger.debug(`Org GHAS results: ${JSON.stringify(ghas_checks)}`); + logger_1.logger.debug(`Org GHAS results: ${JSON.stringify(ghas_checks)}`); this.orgCheckResults.push(ghas_checks); } // check authentication settings if (this.policy.authentication) { const authentication_checks = await new OrgAuthenticationChecks_1.OrgAuthenticationChecks(this.policy, this.organization, this.organization.data).evaluate(); - Logger_1.logger.debug(`Org Authentication results: ${JSON.stringify(authentication_checks)}`); + logger_1.logger.debug(`Org Authentication results: ${JSON.stringify(authentication_checks)}`); this.orgCheckResults.push(authentication_checks); } // check custom repository roles if (this.policy.custom_roles) { const custom_roles_checks = await new OrgCustomRolesChecks_1.OrgCustomRolesChecks(this.policy, this.organization, this.organization.data).evaluate(); - Logger_1.logger.debug(`Org Custom Roles results: ${JSON.stringify(custom_roles_checks)}`); + logger_1.logger.debug(`Org Custom Roles results: ${JSON.stringify(custom_roles_checks)}`); this.orgCheckResults.push(custom_roles_checks); } } printCheckResults() { - Logger_1.logger.info("------------------------------------------------------------------------"); - Logger_1.logger.info(`Organization policy results - ${this.organization.name}:`); - Logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info(`Organization policy results - ${this.organization.name}:`); + logger_1.logger.info("------------------------------------------------------------------------"); this.orgCheckResults.forEach((checkResult) => { const emoji = checkResult.pass === null ? "😐" : checkResult.pass ? "✅" : "❌"; - Logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); + logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); }); } getCheckResults() { diff --git a/dist/evaluators/RepoPolicyEvaluator.js b/dist/evaluators/RepoPolicyEvaluator.js index 8911b21..3ff9138 100644 --- a/dist/evaluators/RepoPolicyEvaluator.js +++ b/dist/evaluators/RepoPolicyEvaluator.js @@ -1,7 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RepoPolicyEvaluator = void 0; -const Logger_1 = require("./../utils/Logger"); +const logger_1 = require("./../utils/logger"); const BranchProtectionChecks_1 = require("./repository/BranchProtectionChecks"); const GHASChecks_1 = require("./repository/GHASChecks"); const Repositories_1 = require("../github/Repositories"); @@ -27,64 +27,65 @@ class RepoPolicyEvaluator { async evaluatePolicy() { // Get the repository data from the API this.repositoryData = await (0, Repositories_1.getRepository)(this.repository.owner, this.repository.name); - Logger_1.logger.debug("Repository policy for repo: " + this.repository.name); + logger_1.logger.debug("Repository policy for repo: " + this.repository.name); // Check the branch protection policy rule - if (this.policy.protected_branches && this.policy.protected_branches.length > 0) { + if (this.policy.protected_branches && + this.policy.protected_branches.length > 0) { const branch_protection = new BranchProtectionChecks_1.BranchProtectionChecks(this.policy, this.repository); const branch_protection_results = await branch_protection.checkBranchProtection(); - Logger_1.logger.debug(`Branch protection rule results: ${JSON.stringify(branch_protection_results, null, 2)}`); + logger_1.logger.debug(`Branch protection rule results: ${JSON.stringify(branch_protection_results, null, 2)}`); this.repositoryCheckResults.push(branch_protection_results); // Check if require pull request before merging is enabled for the protected branches const branch_protection_pull_request_results = await branch_protection.checkRequirePullRequest(); - Logger_1.logger.debug(`Branch protection pull requests rule results: ${JSON.stringify(branch_protection_pull_request_results, null, 2)}`); + logger_1.logger.debug(`Branch protection pull requests rule results: ${JSON.stringify(branch_protection_pull_request_results, null, 2)}`); this.repositoryCheckResults.push(branch_protection_pull_request_results); } // Check the files exist policy rule if (this.policy.file_exists && this.policy.file_exists.length > 0) { const files_exist = await new FilesExistChecks_1.FilesExistChecks(this.repository, this.policy).checkFilesExist(); - Logger_1.logger.debug(`Files exists results: ${JSON.stringify(files_exist)}`); + logger_1.logger.debug(`Files exists results: ${JSON.stringify(files_exist)}`); this.repositoryCheckResults.push(files_exist); } //Run the GHAS checks if (this.policy.advanced_security) { const ghas_checks = await new GHASChecks_1.GHASChecks(this.policy, this.repository, this.repositoryData).evaluate(); - Logger_1.logger.debug(`GHAS results: ${JSON.stringify(ghas_checks)}`); + logger_1.logger.debug(`GHAS results: ${JSON.stringify(ghas_checks)}`); this.repositoryCheckResults.push(ghas_checks); } //Run Actions checks if (this.policy.allowed_actions) { const actions_checks = await new ActionsChecks_1.ActionsChecks(this.policy, this.repository).checkActionsPermissions(); - Logger_1.logger.debug(`Action checks results: ${JSON.stringify(actions_checks)}`); + logger_1.logger.debug(`Action checks results: ${JSON.stringify(actions_checks)}`); this.repositoryCheckResults.push(actions_checks); } //Run workflow checks if (this.policy.workflows) { const workflow_checks = await new WorkflowsChecks_1.WorkflowsChecks(this.policy, this.repository).checkWorkflowsDefaultPermissions(); - Logger_1.logger.debug(`Workflow checks results: ${JSON.stringify(workflow_checks)}`); + logger_1.logger.debug(`Workflow checks results: ${JSON.stringify(workflow_checks)}`); //This check only applies to private and internal repositories const workflow_access_checks = await new WorkflowsChecks_1.WorkflowsChecks(this.policy, this.repository).checkWorkflowsAccessPermissions(); - Logger_1.logger.debug(`Workflow access checks results: ${JSON.stringify(workflow_access_checks)}`); + logger_1.logger.debug(`Workflow access checks results: ${JSON.stringify(workflow_access_checks)}`); } //Run runner checks if (this.policy.runners) { const runner_checks = await new RunnersChecks_1.RunnersChecks(this.policy, this.repository).checkRunnersPermissions(); - Logger_1.logger.debug(`Runner checks results: ${JSON.stringify(runner_checks)}`); + logger_1.logger.debug(`Runner checks results: ${JSON.stringify(runner_checks)}`); this.repositoryCheckResults.push(runner_checks); } if (this.policy.webhooks) { const webhook_checks = await new WebHooksChecks_1.WebHooksChecks(this.policy, this.repository).checkWebHooks(); - Logger_1.logger.debug(`Webhook checks results: ${JSON.stringify(webhook_checks)}`); + logger_1.logger.debug(`Webhook checks results: ${JSON.stringify(webhook_checks)}`); this.repositoryCheckResults.push(webhook_checks); } } // Run webhook checks printCheckResults() { - Logger_1.logger.info("------------------------------------------------------------------------"); - Logger_1.logger.info(`Repository policy results - ${this.getFullRepositoryName()}:`); - Logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info(`Repository policy results - ${this.getFullRepositoryName()}:`); + logger_1.logger.info("------------------------------------------------------------------------"); this.repositoryCheckResults.forEach((checkResult) => { const emoji = checkResult.pass === null ? "😐" : checkResult.pass ? "✅" : "❌"; - Logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); + logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); }); } getFullRepositoryName() { diff --git a/dist/evaluators/repository/ActionsChecks.js b/dist/evaluators/repository/ActionsChecks.js index 4d08f4d..bd21911 100644 --- a/dist/evaluators/repository/ActionsChecks.js +++ b/dist/evaluators/repository/ActionsChecks.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.ActionsChecks = void 0; const Actions_1 = require("../../github/Actions"); -const Logger_1 = require("../../utils/Logger"); +const logger_1 = require("../../utils/logger"); const POLICY_VALUES = ["none", "all", "local_only", "selected"]; class ActionsChecks { policy; @@ -22,7 +22,7 @@ class ActionsChecks { switch (actionsPermissionsPolicy) { case "selected": if (!this.policy.allowed_actions.selected.patterns_allowed) { - Logger_1.logger.error("error: the policy (.yml) should have the list of patterns_allowed when permission is 'selected'"); + logger_1.logger.error("error: the policy (.yml) should have the list of patterns_allowed when permission is 'selected'"); return this.createResult(false, actionsPermissionsAllowedActions, actionsPermissionsPolicy); } if (actionsPermissionsAllowedActions !== "selected") @@ -42,7 +42,7 @@ class ActionsChecks { case "none": return this.createResult(actionsPermissionsPolicy === actionsPermissionsAllowedActions, actionsPermissionsAllowedActions, actionsPermissionsPolicy); default: - Logger_1.logger.error(`error: invalid policy value '${actionsPermissionsPolicy}'. It should be one of ${POLICY_VALUES.join(", ")}.`); + logger_1.logger.error(`error: invalid policy value '${actionsPermissionsPolicy}'. It should be one of ${POLICY_VALUES.join(", ")}.`); } } createResult(actions_permissions, github_allowed_actions, policy_allowed_actions) { diff --git a/dist/evaluators/repository/BranchProtectionChecks.js b/dist/evaluators/repository/BranchProtectionChecks.js index f79748d..516cead 100644 --- a/dist/evaluators/repository/BranchProtectionChecks.js +++ b/dist/evaluators/repository/BranchProtectionChecks.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.BranchProtectionChecks = void 0; const Repositories_1 = require("../../github/Repositories"); -const Logger_1 = require("../../utils/Logger"); +const logger_1 = require("../../utils/logger"); class BranchProtectionChecks { policy; repository; @@ -97,7 +97,7 @@ class BranchProtectionChecks { } getProtectedBranchesToCheck(branchesToCheck, protectedBranches) { const branchesAvailable = branchesToCheck.filter((branch) => protectedBranches.map((branch) => branch.name).includes(branch)); - Logger_1.logger.debug("Only these branches will be checked against branch protection rules: " + + logger_1.logger.debug("Only these branches will be checked against branch protection rules: " + branchesAvailable); return branchesAvailable; } @@ -125,7 +125,7 @@ class BranchProtectionChecks { } catch (error) { // If the branch is protected but no rules are set. - Logger_1.logger.debug(`Exception: ${error}`); + logger_1.logger.debug(`Exception: ${error}`); results[branch] = { error: "No branch protection rules set for this branch", }; diff --git a/dist/evaluators/repository/GHASChecks.js b/dist/evaluators/repository/GHASChecks.js index 243c687..1c53f33 100644 --- a/dist/evaluators/repository/GHASChecks.js +++ b/dist/evaluators/repository/GHASChecks.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.GHASChecks = void 0; const Repositories_1 = require("../../github/Repositories"); -const Logger_1 = require("../../utils/Logger"); +const logger_1 = require("../../utils/logger"); class GHASChecks { policy; repository; @@ -13,7 +13,7 @@ class GHASChecks { this.repositoryData = repositoryData; } checkRepositoryGHASstatus() { - Logger_1.logger.debug(`Checking GHAS status for ${this.repository.owner}/${this.repository.name}`); + logger_1.logger.debug(`Checking GHAS status for ${this.repository.owner}/${this.repository.name}`); if (this.policy.advanced_security.ghas) { return this.getStatusForFeature("advanced_security"); } diff --git a/dist/evaluators/repository/WorkflowsChecks.js b/dist/evaluators/repository/WorkflowsChecks.js index 6111214..e98bfd2 100644 --- a/dist/evaluators/repository/WorkflowsChecks.js +++ b/dist/evaluators/repository/WorkflowsChecks.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkflowsChecks = void 0; const Actions_1 = require("../../github/Actions"); -const Logger_1 = require("../../utils/Logger"); +const logger_1 = require("../../utils/logger"); class WorkflowsChecks { policy; repository; @@ -23,12 +23,12 @@ class WorkflowsChecks { try { const workflowsAccessPermissions = await (0, Actions_1.getRepoWorkflowAccessPermissions)(this.repository.owner, this.repository.name); const workflowsAccessPermissionsResult = workflowsAccessPermissions.access_level; - Logger_1.logger.debug(`Workflow access permissions result: ${workflowsAccessPermissionsResult}`); + logger_1.logger.debug(`Workflow access permissions result: ${workflowsAccessPermissionsResult}`); const workflowsAccessPermissionsPolicy = this.policy.workflows.access_level; return this.createWorkflowsAccessPermissionsResult(workflowsAccessPermissionsResult == workflowsAccessPermissionsPolicy); } catch (error) { - Logger_1.logger.error(`not available for public repositories`); + logger_1.logger.error(`not available for public repositories`); return this.createWorkflowsAccessPermissionsResult(false, "not available for public repositories"); } } diff --git a/dist/github/Actions.js b/dist/github/Actions.js index 4adff29..4f39365 100644 --- a/dist/github/Actions.js +++ b/dist/github/Actions.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getRepoWorkflowActions = exports.getRepoWorkflows = exports.getRepoWorkflowAccessPermissions = exports.getRepoDefaultWorkflowsPermissions = exports.getRepoSelectedActions = exports.getRepoActionsPermissions = void 0; const GitArmorKit_1 = require("./GitArmorKit"); -const Logger_1 = require("../utils/Logger"); +const logger_1 = require("../utils/logger"); //Get GitHub Actions permissions for a repository const getRepoActionsPermissions = async (owner, repo) => { try { @@ -14,7 +14,7 @@ const getRepoActionsPermissions = async (owner, repo) => { return response.data; } catch (error) { - Logger_1.logger.error(error.message); + logger_1.logger.error(error.message); throw error; } }; diff --git a/dist/github/GitArmorKit.js b/dist/github/GitArmorKit.js index 4e61d02..f88e1d5 100644 --- a/dist/github/GitArmorKit.js +++ b/dist/github/GitArmorKit.js @@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.GitArmorKit = void 0; const rest_1 = require("@octokit/rest"); const dotenv = __importStar(require("dotenv")); -const Logger_1 = require("../utils/Logger"); +const logger_1 = require("../utils/logger"); const core_1 = require("@actions/core"); dotenv.config(); class GitArmorKit extends rest_1.Octokit { @@ -38,14 +38,14 @@ class GitArmorKit extends rest_1.Octokit { onRateLimit: (retryAfter, options, octokit) => { octokit.log.warn(`Request quota exhausted for request ${options.method} ${options.url}`); if (options.request.retryCount <= 2) { - Logger_1.logger.debug(`Retrying after ${retryAfter} seconds!`); + logger_1.logger.debug(`Retrying after ${retryAfter} seconds!`); return true; } }, onSecondaryRateLimit: (retryAfter, options, octokit) => { octokit.log.warn(`Secondary rate limit for request ${options.method} ${options.url}`); if (options.request.retryCount <= 2) { - Logger_1.logger.debug(`Secondary Limit - Retrying after ${retryAfter} seconds!`); + logger_1.logger.debug(`Secondary Limit - Retrying after ${retryAfter} seconds!`); return true; } }, diff --git a/dist/github/Organization.js b/dist/github/Organization.js index 08c5382..10e3442 100644 --- a/dist/github/Organization.js +++ b/dist/github/Organization.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getCustomRolesForOrg = exports.getSecurityTeamsForOrg = exports.getOrganization = exports.getRepositoriesForOrg = void 0; const GitArmorKit_1 = require("./GitArmorKit"); -const Logger_1 = require("../utils/Logger"); +const logger_1 = require("../utils/logger"); // Get all repositories for an organization const getRepositoriesForOrg = async (org) => { const octokit = new GitArmorKit_1.GitArmorKit(); @@ -42,7 +42,7 @@ const getCustomRolesForOrg = async (org) => { return data; } catch (error) { - Logger_1.logger.error(`Error in getCustomRolesForOrg: ${error.message}`); + logger_1.logger.error(`Error in getCustomRolesForOrg: ${error.message}`); return { total_count: 0, custom_roles: [] }; } }; diff --git a/dist/github/Repositories.js b/dist/github/Repositories.js index 04abb04..89d7fca 100644 --- a/dist/github/Repositories.js +++ b/dist/github/Repositories.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getRepositoryCodeScanningAnalysis = exports.getRepoDependabotSecurityUpdates = exports.getRepoDependabotAlerts = exports.getRepoFile = exports.getRepoBranchProtection = exports.getRepoProtectedBranches = exports.getRepoBranch = exports.getRepoCollaborators = exports.getRepoPullRequests = exports.getRepository = exports.getRepositoriesForTeamAsAdmin = void 0; const GitArmorKit_1 = require("./GitArmorKit"); -const Logger_1 = require("../utils/Logger"); +const logger_1 = require("../utils/logger"); const getRepositoriesForTeamAsAdmin = async (org, teamSlug) => { const octokit = new GitArmorKit_1.GitArmorKit(); //get team id from slug @@ -138,7 +138,7 @@ const getRepositoryCodeScanningAnalysis = async (owner, repo) => { return response.data; } catch (error) { - Logger_1.logger.debug(`Code scanning analysis fetching error: ${error.message}`); + logger_1.logger.debug(`Code scanning analysis fetching error: ${error.message}`); if ((error.status === 403 && error.message.includes("Code scanning is not enabled for this repository")) || error.message.includes("Advanced Security must be enabled for this repository to use code scanning.") || diff --git a/dist/github/WebHooks.js b/dist/github/WebHooks.js index 15a7892..089fde4 100644 --- a/dist/github/WebHooks.js +++ b/dist/github/WebHooks.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getWebHookConfig = exports.getWebHooks = void 0; const GitArmorKit_1 = require("./GitArmorKit"); -const Logger_1 = require("../utils/Logger"); +const logger_1 = require("../utils/logger"); const getWebHooks = async (owner, repository) => { let res = []; try { @@ -17,7 +17,7 @@ const getWebHooks = async (owner, repository) => { res = iterator; } catch (error) { - Logger_1.logger.error(`There was an error. Please check the logs ${error}`); + logger_1.logger.error(`There was an error. Please check the logs ${error}`); } return res; }; @@ -38,7 +38,7 @@ const getWebHookConfig = async (owner, repository, hook_id) => { res = response.data; } catch (error) { - Logger_1.logger.error(`There was an error. Please check the logs ${error}`); + logger_1.logger.error(`There was an error. Please check the logs ${error}`); } return res; }; diff --git a/dist/index.js b/dist/index.js index c1c7b06..e032705 100644 --- a/dist/index.js +++ b/dist/index.js @@ -47793,7 +47793,7 @@ function wrappy (fn, cb) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.OrgPolicyEvaluator = void 0; -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const OrgGHASChecks_1 = __nccwpck_require__(7137); const OrgAuthenticationChecks_1 = __nccwpck_require__(7124); const OrgCustomRolesChecks_1 = __nccwpck_require__(8731); @@ -47811,43 +47811,43 @@ class OrgPolicyEvaluator { } // This method evaluates the policy for the repository async evaluatePolicy() { - Logger_1.logger.info("Running checks for organization policy against: " + + logger_1.logger.info("Running checks for organization policy against: " + this.organization.name); - Logger_1.logger.debug("Organization policy for org: " + this.organization.name); + logger_1.logger.debug("Organization policy for org: " + this.organization.name); // Get the organization data from the API this.organization.data = await (0, Organization_1.getOrganization)(this.organization.name); // Check MemberPrivileges policy rule if (this.policy.member_privileges) { const member_privileges = await new PrivilegesChecks_1.PrivilegesChecks(this.organization, this.policy).checkPrivileges(); - Logger_1.logger.debug(`Member privileges results: ${JSON.stringify(member_privileges)}`); + logger_1.logger.debug(`Member privileges results: ${JSON.stringify(member_privileges)}`); this.orgCheckResults.push(member_privileges); } // Check org level GHAS settings if (this.policy.advanced_security) { const ghas_checks = await new OrgGHASChecks_1.OrgGHASChecks(this.policy, this.organization, this.organization.data).evaluate(); - Logger_1.logger.debug(`Org GHAS results: ${JSON.stringify(ghas_checks)}`); + logger_1.logger.debug(`Org GHAS results: ${JSON.stringify(ghas_checks)}`); this.orgCheckResults.push(ghas_checks); } // check authentication settings if (this.policy.authentication) { const authentication_checks = await new OrgAuthenticationChecks_1.OrgAuthenticationChecks(this.policy, this.organization, this.organization.data).evaluate(); - Logger_1.logger.debug(`Org Authentication results: ${JSON.stringify(authentication_checks)}`); + logger_1.logger.debug(`Org Authentication results: ${JSON.stringify(authentication_checks)}`); this.orgCheckResults.push(authentication_checks); } // check custom repository roles if (this.policy.custom_roles) { const custom_roles_checks = await new OrgCustomRolesChecks_1.OrgCustomRolesChecks(this.policy, this.organization, this.organization.data).evaluate(); - Logger_1.logger.debug(`Org Custom Roles results: ${JSON.stringify(custom_roles_checks)}`); + logger_1.logger.debug(`Org Custom Roles results: ${JSON.stringify(custom_roles_checks)}`); this.orgCheckResults.push(custom_roles_checks); } } printCheckResults() { - Logger_1.logger.info("------------------------------------------------------------------------"); - Logger_1.logger.info(`Organization policy results - ${this.organization.name}:`); - Logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info(`Organization policy results - ${this.organization.name}:`); + logger_1.logger.info("------------------------------------------------------------------------"); this.orgCheckResults.forEach((checkResult) => { const emoji = checkResult.pass === null ? "😐" : checkResult.pass ? "✅" : "❌"; - Logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); + logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); }); } getCheckResults() { @@ -47869,7 +47869,7 @@ exports.OrgPolicyEvaluator = OrgPolicyEvaluator; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.RepoPolicyEvaluator = void 0; -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const BranchProtectionChecks_1 = __nccwpck_require__(8377); const GHASChecks_1 = __nccwpck_require__(7161); const Repositories_1 = __nccwpck_require__(3354); @@ -47895,64 +47895,65 @@ class RepoPolicyEvaluator { async evaluatePolicy() { // Get the repository data from the API this.repositoryData = await (0, Repositories_1.getRepository)(this.repository.owner, this.repository.name); - Logger_1.logger.debug("Repository policy for repo: " + this.repository.name); + logger_1.logger.debug("Repository policy for repo: " + this.repository.name); // Check the branch protection policy rule - if (this.policy.protected_branches && this.policy.protected_branches.length > 0) { + if (this.policy.protected_branches && + this.policy.protected_branches.length > 0) { const branch_protection = new BranchProtectionChecks_1.BranchProtectionChecks(this.policy, this.repository); const branch_protection_results = await branch_protection.checkBranchProtection(); - Logger_1.logger.debug(`Branch protection rule results: ${JSON.stringify(branch_protection_results, null, 2)}`); + logger_1.logger.debug(`Branch protection rule results: ${JSON.stringify(branch_protection_results, null, 2)}`); this.repositoryCheckResults.push(branch_protection_results); // Check if require pull request before merging is enabled for the protected branches const branch_protection_pull_request_results = await branch_protection.checkRequirePullRequest(); - Logger_1.logger.debug(`Branch protection pull requests rule results: ${JSON.stringify(branch_protection_pull_request_results, null, 2)}`); + logger_1.logger.debug(`Branch protection pull requests rule results: ${JSON.stringify(branch_protection_pull_request_results, null, 2)}`); this.repositoryCheckResults.push(branch_protection_pull_request_results); } // Check the files exist policy rule if (this.policy.file_exists && this.policy.file_exists.length > 0) { const files_exist = await new FilesExistChecks_1.FilesExistChecks(this.repository, this.policy).checkFilesExist(); - Logger_1.logger.debug(`Files exists results: ${JSON.stringify(files_exist)}`); + logger_1.logger.debug(`Files exists results: ${JSON.stringify(files_exist)}`); this.repositoryCheckResults.push(files_exist); } //Run the GHAS checks if (this.policy.advanced_security) { const ghas_checks = await new GHASChecks_1.GHASChecks(this.policy, this.repository, this.repositoryData).evaluate(); - Logger_1.logger.debug(`GHAS results: ${JSON.stringify(ghas_checks)}`); + logger_1.logger.debug(`GHAS results: ${JSON.stringify(ghas_checks)}`); this.repositoryCheckResults.push(ghas_checks); } //Run Actions checks if (this.policy.allowed_actions) { const actions_checks = await new ActionsChecks_1.ActionsChecks(this.policy, this.repository).checkActionsPermissions(); - Logger_1.logger.debug(`Action checks results: ${JSON.stringify(actions_checks)}`); + logger_1.logger.debug(`Action checks results: ${JSON.stringify(actions_checks)}`); this.repositoryCheckResults.push(actions_checks); } //Run workflow checks if (this.policy.workflows) { const workflow_checks = await new WorkflowsChecks_1.WorkflowsChecks(this.policy, this.repository).checkWorkflowsDefaultPermissions(); - Logger_1.logger.debug(`Workflow checks results: ${JSON.stringify(workflow_checks)}`); + logger_1.logger.debug(`Workflow checks results: ${JSON.stringify(workflow_checks)}`); //This check only applies to private and internal repositories const workflow_access_checks = await new WorkflowsChecks_1.WorkflowsChecks(this.policy, this.repository).checkWorkflowsAccessPermissions(); - Logger_1.logger.debug(`Workflow access checks results: ${JSON.stringify(workflow_access_checks)}`); + logger_1.logger.debug(`Workflow access checks results: ${JSON.stringify(workflow_access_checks)}`); } //Run runner checks if (this.policy.runners) { const runner_checks = await new RunnersChecks_1.RunnersChecks(this.policy, this.repository).checkRunnersPermissions(); - Logger_1.logger.debug(`Runner checks results: ${JSON.stringify(runner_checks)}`); + logger_1.logger.debug(`Runner checks results: ${JSON.stringify(runner_checks)}`); this.repositoryCheckResults.push(runner_checks); } if (this.policy.webhooks) { const webhook_checks = await new WebHooksChecks_1.WebHooksChecks(this.policy, this.repository).checkWebHooks(); - Logger_1.logger.debug(`Webhook checks results: ${JSON.stringify(webhook_checks)}`); + logger_1.logger.debug(`Webhook checks results: ${JSON.stringify(webhook_checks)}`); this.repositoryCheckResults.push(webhook_checks); } } // Run webhook checks printCheckResults() { - Logger_1.logger.info("------------------------------------------------------------------------"); - Logger_1.logger.info(`Repository policy results - ${this.getFullRepositoryName()}:`); - Logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info("------------------------------------------------------------------------"); + logger_1.logger.info(`Repository policy results - ${this.getFullRepositoryName()}:`); + logger_1.logger.info("------------------------------------------------------------------------"); this.repositoryCheckResults.forEach((checkResult) => { const emoji = checkResult.pass === null ? "😐" : checkResult.pass ? "✅" : "❌"; - Logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); + logger_1.logger.info(`[${emoji}] Check: ${checkResult.name} - Pass: ${checkResult.pass} \n${JSON.stringify(checkResult.data, null, 3)}`); }); } getFullRepositoryName() { @@ -48297,7 +48298,7 @@ exports.PrivilegesChecks = PrivilegesChecks; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ActionsChecks = void 0; const Actions_1 = __nccwpck_require__(5248); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const POLICY_VALUES = ["none", "all", "local_only", "selected"]; class ActionsChecks { policy; @@ -48317,7 +48318,7 @@ class ActionsChecks { switch (actionsPermissionsPolicy) { case "selected": if (!this.policy.allowed_actions.selected.patterns_allowed) { - Logger_1.logger.error("error: the policy (.yml) should have the list of patterns_allowed when permission is 'selected'"); + logger_1.logger.error("error: the policy (.yml) should have the list of patterns_allowed when permission is 'selected'"); return this.createResult(false, actionsPermissionsAllowedActions, actionsPermissionsPolicy); } if (actionsPermissionsAllowedActions !== "selected") @@ -48337,7 +48338,7 @@ class ActionsChecks { case "none": return this.createResult(actionsPermissionsPolicy === actionsPermissionsAllowedActions, actionsPermissionsAllowedActions, actionsPermissionsPolicy); default: - Logger_1.logger.error(`error: invalid policy value '${actionsPermissionsPolicy}'. It should be one of ${POLICY_VALUES.join(", ")}.`); + logger_1.logger.error(`error: invalid policy value '${actionsPermissionsPolicy}'. It should be one of ${POLICY_VALUES.join(", ")}.`); } } createResult(actions_permissions, github_allowed_actions, policy_allowed_actions) { @@ -48415,7 +48416,7 @@ exports.ActionsChecks = ActionsChecks; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.BranchProtectionChecks = void 0; const Repositories_1 = __nccwpck_require__(3354); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); class BranchProtectionChecks { policy; repository; @@ -48510,7 +48511,7 @@ class BranchProtectionChecks { } getProtectedBranchesToCheck(branchesToCheck, protectedBranches) { const branchesAvailable = branchesToCheck.filter((branch) => protectedBranches.map((branch) => branch.name).includes(branch)); - Logger_1.logger.debug("Only these branches will be checked against branch protection rules: " + + logger_1.logger.debug("Only these branches will be checked against branch protection rules: " + branchesAvailable); return branchesAvailable; } @@ -48538,7 +48539,7 @@ class BranchProtectionChecks { } catch (error) { // If the branch is protected but no rules are set. - Logger_1.logger.debug(`Exception: ${error}`); + logger_1.logger.debug(`Exception: ${error}`); results[branch] = { error: "No branch protection rules set for this branch", }; @@ -48665,7 +48666,7 @@ exports.BranchProtectionChecks = BranchProtectionChecks; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.GHASChecks = void 0; const Repositories_1 = __nccwpck_require__(3354); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); class GHASChecks { policy; repository; @@ -48676,7 +48677,7 @@ class GHASChecks { this.repositoryData = repositoryData; } checkRepositoryGHASstatus() { - Logger_1.logger.debug(`Checking GHAS status for ${this.repository.owner}/${this.repository.name}`); + logger_1.logger.debug(`Checking GHAS status for ${this.repository.owner}/${this.repository.name}`); if (this.policy.advanced_security.ghas) { return this.getStatusForFeature("advanced_security"); } @@ -48957,7 +48958,7 @@ exports.WebHooksChecks = WebHooksChecks; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.WorkflowsChecks = void 0; const Actions_1 = __nccwpck_require__(5248); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); class WorkflowsChecks { policy; repository; @@ -48978,12 +48979,12 @@ class WorkflowsChecks { try { const workflowsAccessPermissions = await (0, Actions_1.getRepoWorkflowAccessPermissions)(this.repository.owner, this.repository.name); const workflowsAccessPermissionsResult = workflowsAccessPermissions.access_level; - Logger_1.logger.debug(`Workflow access permissions result: ${workflowsAccessPermissionsResult}`); + logger_1.logger.debug(`Workflow access permissions result: ${workflowsAccessPermissionsResult}`); const workflowsAccessPermissionsPolicy = this.policy.workflows.access_level; return this.createWorkflowsAccessPermissionsResult(workflowsAccessPermissionsResult == workflowsAccessPermissionsPolicy); } catch (error) { - Logger_1.logger.error(`not available for public repositories`); + logger_1.logger.error(`not available for public repositories`); return this.createWorkflowsAccessPermissionsResult(false, "not available for public repositories"); } } @@ -49030,7 +49031,7 @@ exports.WorkflowsChecks = WorkflowsChecks; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getRepoWorkflowActions = exports.getRepoWorkflows = exports.getRepoWorkflowAccessPermissions = exports.getRepoDefaultWorkflowsPermissions = exports.getRepoSelectedActions = exports.getRepoActionsPermissions = void 0; const GitArmorKit_1 = __nccwpck_require__(2009); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); //Get GitHub Actions permissions for a repository const getRepoActionsPermissions = async (owner, repo) => { try { @@ -49042,7 +49043,7 @@ const getRepoActionsPermissions = async (owner, repo) => { return response.data; } catch (error) { - Logger_1.logger.error(error.message); + logger_1.logger.error(error.message); throw error; } }; @@ -49142,7 +49143,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.GitArmorKit = void 0; const rest_1 = __nccwpck_require__(5375); const dotenv = __importStar(__nccwpck_require__(2437)); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const core_1 = __nccwpck_require__(2186); dotenv.config(); class GitArmorKit extends rest_1.Octokit { @@ -49154,14 +49155,14 @@ class GitArmorKit extends rest_1.Octokit { onRateLimit: (retryAfter, options, octokit) => { octokit.log.warn(`Request quota exhausted for request ${options.method} ${options.url}`); if (options.request.retryCount <= 2) { - Logger_1.logger.debug(`Retrying after ${retryAfter} seconds!`); + logger_1.logger.debug(`Retrying after ${retryAfter} seconds!`); return true; } }, onSecondaryRateLimit: (retryAfter, options, octokit) => { octokit.log.warn(`Secondary rate limit for request ${options.method} ${options.url}`); if (options.request.retryCount <= 2) { - Logger_1.logger.debug(`Secondary Limit - Retrying after ${retryAfter} seconds!`); + logger_1.logger.debug(`Secondary Limit - Retrying after ${retryAfter} seconds!`); return true; } }, @@ -49182,7 +49183,7 @@ exports.GitArmorKit = GitArmorKit; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getCustomRolesForOrg = exports.getSecurityTeamsForOrg = exports.getOrganization = exports.getRepositoriesForOrg = void 0; const GitArmorKit_1 = __nccwpck_require__(2009); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); // Get all repositories for an organization const getRepositoriesForOrg = async (org) => { const octokit = new GitArmorKit_1.GitArmorKit(); @@ -49222,7 +49223,7 @@ const getCustomRolesForOrg = async (org) => { return data; } catch (error) { - Logger_1.logger.error(`Error in getCustomRolesForOrg: ${error.message}`); + logger_1.logger.error(`Error in getCustomRolesForOrg: ${error.message}`); return { total_count: 0, custom_roles: [] }; } }; @@ -49239,7 +49240,7 @@ exports.getCustomRolesForOrg = getCustomRolesForOrg; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getRepositoryCodeScanningAnalysis = exports.getRepoDependabotSecurityUpdates = exports.getRepoDependabotAlerts = exports.getRepoFile = exports.getRepoBranchProtection = exports.getRepoProtectedBranches = exports.getRepoBranch = exports.getRepoCollaborators = exports.getRepoPullRequests = exports.getRepository = exports.getRepositoriesForTeamAsAdmin = void 0; const GitArmorKit_1 = __nccwpck_require__(2009); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const getRepositoriesForTeamAsAdmin = async (org, teamSlug) => { const octokit = new GitArmorKit_1.GitArmorKit(); //get team id from slug @@ -49375,7 +49376,7 @@ const getRepositoryCodeScanningAnalysis = async (owner, repo) => { return response.data; } catch (error) { - Logger_1.logger.debug(`Code scanning analysis fetching error: ${error.message}`); + logger_1.logger.debug(`Code scanning analysis fetching error: ${error.message}`); if ((error.status === 403 && error.message.includes("Code scanning is not enabled for this repository")) || error.message.includes("Advanced Security must be enabled for this repository to use code scanning.") || @@ -49422,7 +49423,7 @@ exports.getRepoRunners = getRepoRunners; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getWebHookConfig = exports.getWebHooks = void 0; const GitArmorKit_1 = __nccwpck_require__(2009); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const getWebHooks = async (owner, repository) => { let res = []; try { @@ -49437,7 +49438,7 @@ const getWebHooks = async (owner, repository) => { res = iterator; } catch (error) { - Logger_1.logger.error(`There was an error. Please check the logs ${error}`); + logger_1.logger.error(`There was an error. Please check the logs ${error}`); } return res; }; @@ -49458,7 +49459,7 @@ const getWebHookConfig = async (owner, repository, hook_id) => { res = response.data; } catch (error) { - Logger_1.logger.error(`There was an error. Please check the logs ${error}`); + logger_1.logger.error(`There was an error. Please check the logs ${error}`); } return res; }; @@ -49496,16 +49497,16 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -const Input_1 = __nccwpck_require__(9378); +const input_1 = __nccwpck_require__(5073); const Organization_1 = __nccwpck_require__(7155); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const RepoPolicyEvaluator_1 = __nccwpck_require__(8949); const OrgPolicyEvaluator_1 = __nccwpck_require__(5411); const Report_1 = __nccwpck_require__(9382); const policies_1 = __nccwpck_require__(7700); const core = __importStar(__nccwpck_require__(2186)); const run = async () => { - Logger_1.logger.info(` + logger_1.logger.info(` GitArmor by dcodx.com - version 1.0 @@ -49514,21 +49515,21 @@ const run = async () => { // Adjusted part of the run function try { const startTime = process.hrtime(); - const inputs = (0, Input_1.parseInputs)(); + const inputs = (0, input_1.parseInputs)(); const policies = await (0, policies_1.loadPolicy)(inputs); - Logger_1.logger.debug("DEBUG MODE: " + inputs.debug); + logger_1.logger.debug("DEBUG MODE: " + inputs.debug); let report = new Report_1.Report(); report.addInput(inputs); report.addPolicy(policies); if (inputs.level === "organization_only") { - Logger_1.logger.info("Running organization level checks only"); + logger_1.logger.info("Running organization level checks only"); const organizationPolicyEvaluator = new OrgPolicyEvaluator_1.OrgPolicyEvaluator(inputs.org, policies.org); await organizationPolicyEvaluator.evaluatePolicy(); organizationPolicyEvaluator.printCheckResults(); report.addOrgEvaluator(organizationPolicyEvaluator); } else if (inputs.level === "repository_only") { - Logger_1.logger.info("Running repository level checks only"); + logger_1.logger.info("Running repository level checks only"); const repository = { name: inputs.repo, owner: inputs.org, @@ -49539,8 +49540,8 @@ const run = async () => { report.addOneRepoEvaluator(repoPolicyEvaluator); } else if (inputs.level === "organization_and_repository") { - Logger_1.logger.info("Running both organization and repository level checks"); - Logger_1.logger.warn("⚠️ Running the tool with 'organization_and_repository' level might trigger the GitHub API rate limit. Please use it with caution."); + logger_1.logger.info("Running both organization and repository level checks"); + logger_1.logger.warn("⚠️ Running the tool with 'organization_and_repository' level might trigger the GitHub API rate limit. Please use it with caution."); // Organization checks const organizationPolicyEvaluator = new OrgPolicyEvaluator_1.OrgPolicyEvaluator(inputs.org, policies.org); await organizationPolicyEvaluator.evaluatePolicy(); @@ -49548,7 +49549,7 @@ const run = async () => { report.addOrgEvaluator(organizationPolicyEvaluator); // Repository checks within the organization const repos = await (0, Organization_1.getRepositoriesForOrg)(inputs.org); - Logger_1.logger.info("Total Repos: " + repos.length); + logger_1.logger.info("Total Repos: " + repos.length); await Promise.all(repos.map(async (repo) => { const repository = { name: repo.name, @@ -49561,7 +49562,7 @@ const run = async () => { })); } else { - Logger_1.logger.info("Invalid level specified"); + logger_1.logger.info("Invalid level specified"); } report.prepareReports(); report.writeReportToFile(); @@ -49570,14 +49571,14 @@ const run = async () => { core.setOutput("check-results-text", report.getReportText()); } const endTime = process.hrtime(startTime); - Logger_1.logger.debug(`Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`); + logger_1.logger.debug(`Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`); } catch (error) { if (process.env.GITHUB_ACTIONS) { core.setFailed(error); } else { - Logger_1.logger.error(error.message); + logger_1.logger.error(error.message); } } }; @@ -49596,7 +49597,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Report = void 0; -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const fs_1 = __importDefault(__nccwpck_require__(7147)); class Report { orgEvaluators; @@ -49632,10 +49633,10 @@ class Report { if (this.finalReportText && this.finalReportJson) { fs_1.default.writeFileSync("output-report.md", this.finalReportText); fs_1.default.writeFileSync("output-report.json", JSON.stringify(this.finalReportJson, null, 2)); - Logger_1.logger.info("Report written to file: output-report.md and output-report.json"); + logger_1.logger.info("Report written to file: output-report.md and output-report.json"); } else { - Logger_1.logger.error("No report to write"); + logger_1.logger.error("No report to write"); } } addOneRepoEvaluator(repoEvaluator) { @@ -49761,7 +49762,7 @@ exports.Report = Report; /***/ }), -/***/ 9378: +/***/ 5073: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -49769,7 +49770,7 @@ exports.Report = Report; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.parseInputs = void 0; const core_1 = __nccwpck_require__(2186); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const parseInputs = () => { // read inputs from .env file or action inputs const inputs = { @@ -49788,7 +49789,7 @@ const parseInputs = () => { throw new Error("You must provide required inputs. Current inputs: " + JSON.stringify(inputs)); } - Logger_1.logger.debug("Inputs: " + JSON.stringify(inputs)); + logger_1.logger.debug("Inputs: " + JSON.stringify(inputs)); return inputs; }; exports.parseInputs = parseInputs; @@ -49796,7 +49797,7 @@ exports.parseInputs = parseInputs; /***/ }), -/***/ 7674: +/***/ 8836: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -49836,11 +49837,11 @@ exports.loadPolicy = void 0; const fs_1 = __importDefault(__nccwpck_require__(7147)); const path_1 = __importDefault(__nccwpck_require__(1017)); const js_yaml_1 = __importDefault(__nccwpck_require__(1917)); -const Logger_1 = __nccwpck_require__(7674); +const logger_1 = __nccwpck_require__(8836); const loadPolicy = async (inputs) => { let policy = {}; try { - Logger_1.logger.debug(`Loading policies from: ${inputs.policy_dir}`); + logger_1.logger.debug(`Loading policies from: ${inputs.policy_dir}`); if (inputs.level === "organization_only") { const orgPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "organization.yml"), "utf8"); policy.org = js_yaml_1.default.load(orgPolicyFile); @@ -49857,11 +49858,11 @@ const loadPolicy = async (inputs) => { const repoPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "repository.yml"), "utf8"); policy.repo = js_yaml_1.default.load(repoPolicyFile); } - Logger_1.logger.debug("Policy:"); - Logger_1.logger.debug(js_yaml_1.default.dump(policy)); + logger_1.logger.debug("Policy:"); + logger_1.logger.debug(js_yaml_1.default.dump(policy)); } catch (error) { - Logger_1.logger.error("Error loading the policy file. Please check the logs: " + error); + logger_1.logger.error("Error loading the policy file. Please check the logs: " + error); } return policy; }; diff --git a/dist/main.js b/dist/main.js index 00d19f0..b3b1316 100644 --- a/dist/main.js +++ b/dist/main.js @@ -23,16 +23,16 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -const Input_1 = require("./utils/Input"); +const input_1 = require("./utils/input"); const Organization_1 = require("./github/Organization"); -const Logger_1 = require("./utils/Logger"); +const logger_1 = require("./utils/logger"); const RepoPolicyEvaluator_1 = require("./evaluators/RepoPolicyEvaluator"); const OrgPolicyEvaluator_1 = require("./evaluators/OrgPolicyEvaluator"); const Report_1 = require("./reporting/Report"); const policies_1 = require("./utils/policies"); const core = __importStar(require("@actions/core")); const run = async () => { - Logger_1.logger.info(` + logger_1.logger.info(` GitArmor by dcodx.com - version 1.0 @@ -41,21 +41,21 @@ const run = async () => { // Adjusted part of the run function try { const startTime = process.hrtime(); - const inputs = (0, Input_1.parseInputs)(); + const inputs = (0, input_1.parseInputs)(); const policies = await (0, policies_1.loadPolicy)(inputs); - Logger_1.logger.debug("DEBUG MODE: " + inputs.debug); + logger_1.logger.debug("DEBUG MODE: " + inputs.debug); let report = new Report_1.Report(); report.addInput(inputs); report.addPolicy(policies); if (inputs.level === "organization_only") { - Logger_1.logger.info("Running organization level checks only"); + logger_1.logger.info("Running organization level checks only"); const organizationPolicyEvaluator = new OrgPolicyEvaluator_1.OrgPolicyEvaluator(inputs.org, policies.org); await organizationPolicyEvaluator.evaluatePolicy(); organizationPolicyEvaluator.printCheckResults(); report.addOrgEvaluator(organizationPolicyEvaluator); } else if (inputs.level === "repository_only") { - Logger_1.logger.info("Running repository level checks only"); + logger_1.logger.info("Running repository level checks only"); const repository = { name: inputs.repo, owner: inputs.org, @@ -66,8 +66,8 @@ const run = async () => { report.addOneRepoEvaluator(repoPolicyEvaluator); } else if (inputs.level === "organization_and_repository") { - Logger_1.logger.info("Running both organization and repository level checks"); - Logger_1.logger.warn("⚠️ Running the tool with 'organization_and_repository' level might trigger the GitHub API rate limit. Please use it with caution."); + logger_1.logger.info("Running both organization and repository level checks"); + logger_1.logger.warn("⚠️ Running the tool with 'organization_and_repository' level might trigger the GitHub API rate limit. Please use it with caution."); // Organization checks const organizationPolicyEvaluator = new OrgPolicyEvaluator_1.OrgPolicyEvaluator(inputs.org, policies.org); await organizationPolicyEvaluator.evaluatePolicy(); @@ -75,7 +75,7 @@ const run = async () => { report.addOrgEvaluator(organizationPolicyEvaluator); // Repository checks within the organization const repos = await (0, Organization_1.getRepositoriesForOrg)(inputs.org); - Logger_1.logger.info("Total Repos: " + repos.length); + logger_1.logger.info("Total Repos: " + repos.length); await Promise.all(repos.map(async (repo) => { const repository = { name: repo.name, @@ -88,7 +88,7 @@ const run = async () => { })); } else { - Logger_1.logger.info("Invalid level specified"); + logger_1.logger.info("Invalid level specified"); } report.prepareReports(); report.writeReportToFile(); @@ -97,14 +97,14 @@ const run = async () => { core.setOutput("check-results-text", report.getReportText()); } const endTime = process.hrtime(startTime); - Logger_1.logger.debug(`Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`); + logger_1.logger.debug(`Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`); } catch (error) { if (process.env.GITHUB_ACTIONS) { core.setFailed(error); } else { - Logger_1.logger.error(error.message); + logger_1.logger.error(error.message); } } }; diff --git a/dist/reporting/Report.js b/dist/reporting/Report.js index 64a4bc4..d58b340 100644 --- a/dist/reporting/Report.js +++ b/dist/reporting/Report.js @@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Report = void 0; -const Logger_1 = require("./../utils/Logger"); +const logger_1 = require("./../utils/logger"); const fs_1 = __importDefault(require("fs")); class Report { orgEvaluators; @@ -40,10 +40,10 @@ class Report { if (this.finalReportText && this.finalReportJson) { fs_1.default.writeFileSync("output-report.md", this.finalReportText); fs_1.default.writeFileSync("output-report.json", JSON.stringify(this.finalReportJson, null, 2)); - Logger_1.logger.info("Report written to file: output-report.md and output-report.json"); + logger_1.logger.info("Report written to file: output-report.md and output-report.json"); } else { - Logger_1.logger.error("No report to write"); + logger_1.logger.error("No report to write"); } } addOneRepoEvaluator(repoEvaluator) { diff --git a/dist/utils/Input.js b/dist/utils/input.js similarity index 90% rename from dist/utils/Input.js rename to dist/utils/input.js index 14a7e4d..9acec47 100644 --- a/dist/utils/Input.js +++ b/dist/utils/input.js @@ -2,7 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.parseInputs = void 0; const core_1 = require("@actions/core"); -const Logger_1 = require("./Logger"); +const logger_1 = require("./logger"); const parseInputs = () => { // read inputs from .env file or action inputs const inputs = { @@ -21,7 +21,7 @@ const parseInputs = () => { throw new Error("You must provide required inputs. Current inputs: " + JSON.stringify(inputs)); } - Logger_1.logger.debug("Inputs: " + JSON.stringify(inputs)); + logger_1.logger.debug("Inputs: " + JSON.stringify(inputs)); return inputs; }; exports.parseInputs = parseInputs; diff --git a/dist/utils/Logger.js b/dist/utils/logger.js similarity index 100% rename from dist/utils/Logger.js rename to dist/utils/logger.js diff --git a/dist/utils/policies.js b/dist/utils/policies.js index 133df0a..4d2813f 100644 --- a/dist/utils/policies.js +++ b/dist/utils/policies.js @@ -7,11 +7,11 @@ exports.loadPolicy = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const js_yaml_1 = __importDefault(require("js-yaml")); -const Logger_1 = require("./Logger"); +const logger_1 = require("./logger"); const loadPolicy = async (inputs) => { let policy = {}; try { - Logger_1.logger.debug(`Loading policies from: ${inputs.policy_dir}`); + logger_1.logger.debug(`Loading policies from: ${inputs.policy_dir}`); if (inputs.level === "organization_only") { const orgPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "organization.yml"), "utf8"); policy.org = js_yaml_1.default.load(orgPolicyFile); @@ -28,11 +28,11 @@ const loadPolicy = async (inputs) => { const repoPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "repository.yml"), "utf8"); policy.repo = js_yaml_1.default.load(repoPolicyFile); } - Logger_1.logger.debug("Policy:"); - Logger_1.logger.debug(js_yaml_1.default.dump(policy)); + logger_1.logger.debug("Policy:"); + logger_1.logger.debug(js_yaml_1.default.dump(policy)); } catch (error) { - Logger_1.logger.error("Error loading the policy file. Please check the logs: " + error); + logger_1.logger.error("Error loading the policy file. Please check the logs: " + error); } return policy; }; diff --git a/src/evaluators/OrgPolicyEvaluator.ts b/src/evaluators/OrgPolicyEvaluator.ts index d8c50ec..b50743d 100644 --- a/src/evaluators/OrgPolicyEvaluator.ts +++ b/src/evaluators/OrgPolicyEvaluator.ts @@ -1,4 +1,4 @@ -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; import { OrgPolicy, Organization, CheckResult } from "../types/common/main"; import { OrgGHASChecks } from "./organization/OrgGHASChecks"; import { OrgAuthenticationChecks } from "./organization/OrgAuthenticationChecks"; diff --git a/src/evaluators/RepoPolicyEvaluator.ts b/src/evaluators/RepoPolicyEvaluator.ts index f8e6627..42fa5a5 100644 --- a/src/evaluators/RepoPolicyEvaluator.ts +++ b/src/evaluators/RepoPolicyEvaluator.ts @@ -1,4 +1,4 @@ -import { logger } from "./../utils/Logger"; +import { logger } from "./../utils/logger"; import { RepoPolicy, Repository, CheckResult } from "../types/common/main"; import { BranchProtectionChecks } from "./repository/BranchProtectionChecks"; import { GHASChecks } from "./repository/GHASChecks"; @@ -34,7 +34,10 @@ export class RepoPolicyEvaluator { logger.debug("Repository policy for repo: " + this.repository.name); // Check the branch protection policy rule - if (this.policy.protected_branches && this.policy.protected_branches.length > 0) { + if ( + this.policy.protected_branches && + this.policy.protected_branches.length > 0 + ) { const branch_protection = new BranchProtectionChecks( this.policy, this.repository, diff --git a/src/evaluators/repository/ActionsChecks.ts b/src/evaluators/repository/ActionsChecks.ts index 78b5d44..d6e4e95 100644 --- a/src/evaluators/repository/ActionsChecks.ts +++ b/src/evaluators/repository/ActionsChecks.ts @@ -3,7 +3,7 @@ import { getRepoActionsPermissions, getRepoSelectedActions, } from "../../github/Actions"; -import { logger } from "../../utils/Logger"; +import { logger } from "../../utils/logger"; const POLICY_VALUES = ["none", "all", "local_only", "selected"]; diff --git a/src/evaluators/repository/BranchProtectionChecks.ts b/src/evaluators/repository/BranchProtectionChecks.ts index 495c5dd..195b80f 100644 --- a/src/evaluators/repository/BranchProtectionChecks.ts +++ b/src/evaluators/repository/BranchProtectionChecks.ts @@ -4,7 +4,7 @@ import { getRepoBranch, } from "../../github/Repositories"; import { Repository, CheckResult } from "../../types/common/main"; -import { logger } from "../../utils/Logger"; +import { logger } from "../../utils/logger"; export class BranchProtectionChecks { private policy: any; diff --git a/src/evaluators/repository/GHASChecks.ts b/src/evaluators/repository/GHASChecks.ts index 7e22aa4..14dba33 100644 --- a/src/evaluators/repository/GHASChecks.ts +++ b/src/evaluators/repository/GHASChecks.ts @@ -5,7 +5,7 @@ import { getRepositoryCodeScanningAnalysis, } from "../../github/Repositories"; import { Repository, CheckResult } from "../../types/common/main"; -import { logger } from "../../utils/Logger"; +import { logger } from "../../utils/logger"; export class GHASChecks { private policy: any; diff --git a/src/evaluators/repository/RunnersChecks.ts b/src/evaluators/repository/RunnersChecks.ts index 537d18a..faa5b08 100644 --- a/src/evaluators/repository/RunnersChecks.ts +++ b/src/evaluators/repository/RunnersChecks.ts @@ -1,6 +1,6 @@ import { CheckResult, Repository } from "../../types/common/main"; import { getRepoRunners } from "../../github/Runners"; -import { logger } from "../../utils/Logger"; +import { logger } from "../../utils/logger"; export class RunnersChecks { private policy: any; diff --git a/src/evaluators/repository/WorkflowsChecks.ts b/src/evaluators/repository/WorkflowsChecks.ts index 94e602e..d722bcc 100644 --- a/src/evaluators/repository/WorkflowsChecks.ts +++ b/src/evaluators/repository/WorkflowsChecks.ts @@ -3,7 +3,7 @@ import { getRepoDefaultWorkflowsPermissions, getRepoWorkflowAccessPermissions, } from "../../github/Actions"; -import { logger } from "../../utils/Logger"; +import { logger } from "../../utils/logger"; export class WorkflowsChecks { private policy: any; diff --git a/src/github/Actions.ts b/src/github/Actions.ts index c7be3c0..df66852 100644 --- a/src/github/Actions.ts +++ b/src/github/Actions.ts @@ -1,6 +1,6 @@ import { Endpoints } from "@octokit/types"; import { GitArmorKit } from "./GitArmorKit"; -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; //Get GitHub Actions permissions for a repository export const getRepoActionsPermissions = async ( diff --git a/src/github/DependabotAlerts.ts b/src/github/DependabotAlerts.ts index 6e2fa1e..8b15de4 100644 --- a/src/github/DependabotAlerts.ts +++ b/src/github/DependabotAlerts.ts @@ -1,6 +1,6 @@ import { GitArmorKit } from "./GitArmorKit"; import { DependancyAlert } from "../types/common/main"; -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; export const DependabotAlerts = async ( owner: string, diff --git a/src/github/GitArmorKit.ts b/src/github/GitArmorKit.ts index 584305a..66ecf27 100644 --- a/src/github/GitArmorKit.ts +++ b/src/github/GitArmorKit.ts @@ -1,7 +1,7 @@ import { Octokit } from "@octokit/rest"; import { throttling } from "@octokit/plugin-throttling"; import * as dotenv from "dotenv"; -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; import { getInput } from "@actions/core"; dotenv.config(); diff --git a/src/github/Organization.ts b/src/github/Organization.ts index a4c3d01..a5d6261 100644 --- a/src/github/Organization.ts +++ b/src/github/Organization.ts @@ -1,7 +1,7 @@ import { Endpoints } from "@octokit/types"; import { CustomRepositoryRoles } from "../types/common/main"; import { GitArmorKit } from "./GitArmorKit"; -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; // Get all repositories for an organization export const getRepositoriesForOrg = async ( diff --git a/src/github/Repositories.ts b/src/github/Repositories.ts index af7194b..e96b21e 100644 --- a/src/github/Repositories.ts +++ b/src/github/Repositories.ts @@ -1,6 +1,6 @@ import { Endpoints } from "@octokit/types"; import { GitArmorKit } from "./GitArmorKit"; -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; export const getRepositoriesForTeamAsAdmin = async ( org: string, diff --git a/src/github/Runners.ts b/src/github/Runners.ts index e525188..fac8320 100644 --- a/src/github/Runners.ts +++ b/src/github/Runners.ts @@ -1,6 +1,6 @@ import { Endpoints } from "@octokit/types"; import { GitArmorKit } from "./GitArmorKit"; -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; //List self-hosted runners for a repository export const getRepoRunners = async ( diff --git a/src/github/WebHooks.ts b/src/github/WebHooks.ts index a56d256..b8f835b 100644 --- a/src/github/WebHooks.ts +++ b/src/github/WebHooks.ts @@ -1,6 +1,6 @@ import { GitArmorKit } from "./GitArmorKit"; import { WebHook, WebHookConfig } from "../types/common/main"; -import { logger } from "../utils/Logger"; +import { logger } from "../utils/logger"; export const getWebHooks = async ( owner: string, diff --git a/src/main.ts b/src/main.ts index d566dc0..914390a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,6 @@ -import { parseInputs } from "./utils/Input"; +import { parseInputs } from "./utils/input"; import { getRepositoriesForOrg } from "./github/Organization"; -import { logger } from "./utils/Logger"; +import { logger } from "./utils/logger"; import { RepoPolicyEvaluator } from "./evaluators/RepoPolicyEvaluator"; import { OrgPolicyEvaluator } from "./evaluators/OrgPolicyEvaluator"; import { Report } from "./reporting/Report"; @@ -26,10 +26,13 @@ const run = async (): Promise => { let report = new Report(); report.addInput(inputs); report.addPolicy(policies); - + if (inputs.level === "organization_only") { logger.info("Running organization level checks only"); - const organizationPolicyEvaluator = new OrgPolicyEvaluator(inputs.org, policies.org as OrgPolicy); + const organizationPolicyEvaluator = new OrgPolicyEvaluator( + inputs.org, + policies.org as OrgPolicy, + ); await organizationPolicyEvaluator.evaluatePolicy(); organizationPolicyEvaluator.printCheckResults(); report.addOrgEvaluator(organizationPolicyEvaluator); @@ -39,43 +42,59 @@ const run = async (): Promise => { name: inputs.repo, owner: inputs.org, }; - const repoPolicyEvaluator = new RepoPolicyEvaluator(repository, policies.repo as RepoPolicy); + const repoPolicyEvaluator = new RepoPolicyEvaluator( + repository, + policies.repo as RepoPolicy, + ); await repoPolicyEvaluator.evaluatePolicy(); repoPolicyEvaluator.printCheckResults(); report.addOneRepoEvaluator(repoPolicyEvaluator); } else if (inputs.level === "organization_and_repository") { logger.info("Running both organization and repository level checks"); - logger.warn("⚠️ Running the tool with 'organization_and_repository' level might trigger the GitHub API rate limit. Please use it with caution."); + logger.warn( + "⚠️ Running the tool with 'organization_and_repository' level might trigger the GitHub API rate limit. Please use it with caution.", + ); // Organization checks - const organizationPolicyEvaluator = new OrgPolicyEvaluator(inputs.org, policies.org as OrgPolicy); + const organizationPolicyEvaluator = new OrgPolicyEvaluator( + inputs.org, + policies.org as OrgPolicy, + ); await organizationPolicyEvaluator.evaluatePolicy(); organizationPolicyEvaluator.printCheckResults(); report.addOrgEvaluator(organizationPolicyEvaluator); // Repository checks within the organization const repos = await getRepositoriesForOrg(inputs.org); logger.info("Total Repos: " + repos.length); - await Promise.all(repos.map(async (repo) => { - const repository: Repository = { - name: repo.name, - owner: inputs.org, - }; - const repoPolicyEvaluator = new RepoPolicyEvaluator(repository, policies.repo as RepoPolicy); - await repoPolicyEvaluator.evaluatePolicy(); - repoPolicyEvaluator.printCheckResults(); - report.addRepoEvaluatorToOrg(organizationPolicyEvaluator, repoPolicyEvaluator); - })); + await Promise.all( + repos.map(async (repo) => { + const repository: Repository = { + name: repo.name, + owner: inputs.org, + }; + const repoPolicyEvaluator = new RepoPolicyEvaluator( + repository, + policies.repo as RepoPolicy, + ); + await repoPolicyEvaluator.evaluatePolicy(); + repoPolicyEvaluator.printCheckResults(); + report.addRepoEvaluatorToOrg( + organizationPolicyEvaluator, + repoPolicyEvaluator, + ); + }), + ); } else { logger.info("Invalid level specified"); } - + report.prepareReports(); report.writeReportToFile(); if (process.env.GITHUB_ACTIONS) { core.setOutput("check-results-json", report.getReportJson()); core.setOutput("check-results-text", report.getReportText()); } - + const endTime = process.hrtime(startTime); logger.debug(`Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`); } catch (error) { diff --git a/src/reporting/Report.ts b/src/reporting/Report.ts index 67d3124..3eff5cc 100644 --- a/src/reporting/Report.ts +++ b/src/reporting/Report.ts @@ -1,7 +1,7 @@ import { Policy, Inputs } from "../types/common/main"; import { OrgPolicyEvaluator } from "../evaluators/OrgPolicyEvaluator"; import { RepoPolicyEvaluator } from "../evaluators/RepoPolicyEvaluator"; -import { logger } from "./../utils/Logger"; +import { logger } from "./../utils/logger"; import fs from "fs"; export class Report { @@ -96,14 +96,16 @@ export class Report { report += this.formatOrgEvaluator(orgEvaluator, repoEvaluators); }); - const orgEvaluatorsJson = Array.from(this.orgEvaluators.entries()).map(([orgEvaluator]) => ({ - orgEvaluator: JSON.stringify(orgEvaluator), - })); + const orgEvaluatorsJson = Array.from(this.orgEvaluators.entries()).map( + ([orgEvaluator]) => ({ + orgEvaluator: JSON.stringify(orgEvaluator), + }), + ); jsonReport.orgEvaluators = orgEvaluatorsJson; } else if (this.inputs.level === "organization_and_repository") { report += "### 🏢 Organization Evaluator\n\n"; this.orgEvaluators.forEach((repoEvaluators, orgEvaluator) => { - report += this.formatOrgEvaluator(orgEvaluator,repoEvaluators); + report += this.formatOrgEvaluator(orgEvaluator, repoEvaluators); repoEvaluators.forEach((repoEvaluator) => { report += this.formatRepoEvaluator(repoEvaluator); }); diff --git a/src/utils/input.ts b/src/utils/input.ts index 1500415..e6dfbaf 100644 --- a/src/utils/input.ts +++ b/src/utils/input.ts @@ -1,6 +1,6 @@ import { Inputs } from "../types/common/main"; import { getInput } from "@actions/core"; -import { logger } from "./Logger"; +import { logger } from "./logger"; export const parseInputs = (): Inputs => { // read inputs from .env file or action inputs diff --git a/src/utils/policies.ts b/src/utils/policies.ts index 98a59af..e51c656 100644 --- a/src/utils/policies.ts +++ b/src/utils/policies.ts @@ -1,7 +1,7 @@ import fs from "fs"; import path from "path"; import yaml from "js-yaml"; -import { logger } from "./Logger"; +import { logger } from "./logger"; import { Policy, OrgPolicy, RepoPolicy, Inputs } from "../types/common/main"; export const loadPolicy = async (inputs: Inputs): Promise => { @@ -34,7 +34,7 @@ export const loadPolicy = async (inputs: Inputs): Promise => { ); policy.repo = yaml.load(repoPolicyFile) as RepoPolicy; } - + logger.debug("Policy:"); logger.debug(yaml.dump(policy)); } catch (error) {