Skip to content

Commit

Permalink
Merge pull request #20 from dcodx/feature/issue-15
Browse files Browse the repository at this point in the history
added settings to only run org checks without repositories
  • Loading branch information
theztefan authored Dec 9, 2024
2 parents 51354c0 + 26d42b9 commit daee7d4
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 102 deletions.
2 changes: 1 addition & 1 deletion .env.sample
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
TOKEN=ghp_TKN
LEVEL=organization # repository, organization
LEVEL=organization_only # repository_only, organization_only, or organization_and_repository
REPO=repo-name
ORG=org-name
DEBUG=true
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,17 @@ npm install
Create a `.env` file by using our sample configuration file `.env.sample`:
```text
TOKEN=ghp_TKN
LEVEL=repository
LEVEL=repository_only # repository_only, organization_only, or organization_and_repository
REPO=repo-name
ORG=org-name
DEBUG=false
POLICIES_PATH=policies
```

where `LEVEL` is the scope of the checks:
- `repository` for repository-level checks
- `organization` for organization-level checks
- `repository_only` for repository-level checks
- `organization_only` for organization-level checks
- `organization_and_repository` for organization-level and repositorty_level checks for all the repos in the organization

Next, generate a Personal Access Token (PAT) from GitHub and input your settings into the `.env` file. Ensure your token has these permissions:
- `repo: admin`
Expand Down Expand Up @@ -120,7 +121,7 @@ jobs:
repo: ${{ github.repository }}
org: ${{ github.repository_owner }}
token: ${{ TOKEN }}
level: 'organization'
level: 'organization_only'
policy-dir: './policies'
```
Expand Down
72 changes: 50 additions & 22 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49511,6 +49511,7 @@ const run = async () => {
by dcodx.com - version 1.0

`);
// Adjusted part of the run function
try {
const startTime = process.hrtime();
const inputs = (0, Input_1.parseInputs)();
Expand All @@ -49519,13 +49520,33 @@ const run = async () => {
let report = new Report_1.Report();
report.addInput(inputs);
report.addPolicy(policies);
// depending on which input.level is provided, run the appropriate checks
if (inputs.level === "organization") {
Logger_1.logger.info("Running org level checks");
if (inputs.level === "organization_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");
const repository = {
name: inputs.repo,
owner: inputs.org,
};
const repoPolicyEvaluator = new RepoPolicyEvaluator_1.RepoPolicyEvaluator(repository, policies.repo);
await repoPolicyEvaluator.evaluatePolicy();
repoPolicyEvaluator.printCheckResults();
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.");
// Organization checks
const organizationPolicyEvaluator = new OrgPolicyEvaluator_1.OrgPolicyEvaluator(inputs.org, policies.org);
await organizationPolicyEvaluator.evaluatePolicy();
organizationPolicyEvaluator.printCheckResults();
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);
await Promise.all(repos.map(async (repo) => {
Expand All @@ -49539,20 +49560,8 @@ const run = async () => {
report.addRepoEvaluatorToOrg(organizationPolicyEvaluator, repoPolicyEvaluator);
}));
}
else if (inputs.level === "repository") {
const repository = {
name: inputs.repo,
owner: inputs.org,
};
Logger_1.logger.info("Running repo level checks");
const policyEvaluator = new RepoPolicyEvaluator_1.RepoPolicyEvaluator(repository, policies.repo);
await policyEvaluator.evaluatePolicy();
policyEvaluator.printCheckResults();
report.addOneRepoEvaluator(policyEvaluator);
}
else {
// TODO: Implement enterprise level checks
Logger_1.logger.info("Running enterprise level checks => Not implemented yet");
Logger_1.logger.info("Invalid level specified");
}
report.prepareReports();
report.writeReportToFile();
Expand Down Expand Up @@ -49647,15 +49656,28 @@ class Report {
let jsonReport = {};
// Evaluation section
report += "## 📑 Detailed Evaluation Findings \n\n";
if (this.inputs.level === "repository") {
if (this.inputs.level === "repository_only") {
report += "### 📁 Repository Evaluator\n\n";
report += this.formatRepoEvaluator(this.repoEvaluator);
jsonReport.repoEvalator = this.repoEvaluator;
jsonReport.repoEvaluator = this.repoEvaluator; // Corrected typo from 'repoEvalator' to 'repoEvaluator'
}
else if (this.inputs.level === "organization_only") {
report += "### 🏢 Organization Evaluator\n\n";
this.orgEvaluators.forEach((repoEvaluators, orgEvaluator) => {
report += this.formatOrgEvaluator(orgEvaluator, repoEvaluators);
});
const orgEvaluatorsJson = Array.from(this.orgEvaluators.entries()).map(([orgEvaluator]) => ({
orgEvaluator: JSON.stringify(orgEvaluator),
}));
jsonReport.orgEvaluators = orgEvaluatorsJson;
}
else if (this.inputs.level === "organization") {
report += `### 🏢 Organization Evaluator\n\n`;
else if (this.inputs.level === "organization_and_repository") {
report += "### 🏢 Organization Evaluator\n\n";
this.orgEvaluators.forEach((repoEvaluators, orgEvaluator) => {
report += this.formatOrgEvaluator(orgEvaluator, repoEvaluators);
repoEvaluators.forEach((repoEvaluator) => {
report += this.formatRepoEvaluator(repoEvaluator);
});
});
const orgEvaluatorsJson = Array.from(this.orgEvaluators.entries()).map(([orgEvaluator, repoEvaluators]) => ({
orgEvaluator: JSON.stringify(orgEvaluator),
Expand Down Expand Up @@ -49819,13 +49841,19 @@ const loadPolicy = async (inputs) => {
let policy = {};
try {
Logger_1.logger.debug(`Loading policies from: ${inputs.policy_dir}`);
if (inputs.level === "organization") {
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);
}
else if (inputs.level === "repository_only") {
const repoPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "repository.yml"), "utf8");
policy.repo = js_yaml_1.default.load(repoPolicyFile);
}
else if (inputs.level === "repository") {
else if (inputs.level === "organization_and_repository") {
// Load organization policy
const orgPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "organization.yml"), "utf8");
policy.org = js_yaml_1.default.load(orgPolicyFile);
// Load repository policy
const repoPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "repository.yml"), "utf8");
policy.repo = js_yaml_1.default.load(repoPolicyFile);
}
Expand Down
41 changes: 25 additions & 16 deletions dist/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const run = async () => {
by dcodx.com - version 1.0
`);
// Adjusted part of the run function
try {
const startTime = process.hrtime();
const inputs = (0, Input_1.parseInputs)();
Expand All @@ -46,13 +47,33 @@ const run = async () => {
let report = new Report_1.Report();
report.addInput(inputs);
report.addPolicy(policies);
// depending on which input.level is provided, run the appropriate checks
if (inputs.level === "organization") {
Logger_1.logger.info("Running org level checks");
if (inputs.level === "organization_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");
const repository = {
name: inputs.repo,
owner: inputs.org,
};
const repoPolicyEvaluator = new RepoPolicyEvaluator_1.RepoPolicyEvaluator(repository, policies.repo);
await repoPolicyEvaluator.evaluatePolicy();
repoPolicyEvaluator.printCheckResults();
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.");
// Organization checks
const organizationPolicyEvaluator = new OrgPolicyEvaluator_1.OrgPolicyEvaluator(inputs.org, policies.org);
await organizationPolicyEvaluator.evaluatePolicy();
organizationPolicyEvaluator.printCheckResults();
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);
await Promise.all(repos.map(async (repo) => {
Expand All @@ -66,20 +87,8 @@ const run = async () => {
report.addRepoEvaluatorToOrg(organizationPolicyEvaluator, repoPolicyEvaluator);
}));
}
else if (inputs.level === "repository") {
const repository = {
name: inputs.repo,
owner: inputs.org,
};
Logger_1.logger.info("Running repo level checks");
const policyEvaluator = new RepoPolicyEvaluator_1.RepoPolicyEvaluator(repository, policies.repo);
await policyEvaluator.evaluatePolicy();
policyEvaluator.printCheckResults();
report.addOneRepoEvaluator(policyEvaluator);
}
else {
// TODO: Implement enterprise level checks
Logger_1.logger.info("Running enterprise level checks => Not implemented yet");
Logger_1.logger.info("Invalid level specified");
}
report.prepareReports();
report.writeReportToFile();
Expand Down
21 changes: 17 additions & 4 deletions dist/reporting/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,29 @@ class Report {
let jsonReport = {};
// Evaluation section
report += "## 📑 Detailed Evaluation Findings \n\n";
if (this.inputs.level === "repository") {
if (this.inputs.level === "repository_only") {
report += "### 📁 Repository Evaluator\n\n";
report += this.formatRepoEvaluator(this.repoEvaluator);
jsonReport.repoEvalator = this.repoEvaluator;
jsonReport.repoEvaluator = this.repoEvaluator; // Corrected typo from 'repoEvalator' to 'repoEvaluator'
}
else if (this.inputs.level === "organization") {
report += `### 🏢 Organization Evaluator\n\n`;
else if (this.inputs.level === "organization_only") {
report += "### 🏢 Organization Evaluator\n\n";
this.orgEvaluators.forEach((repoEvaluators, orgEvaluator) => {
report += this.formatOrgEvaluator(orgEvaluator, repoEvaluators);
});
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);
repoEvaluators.forEach((repoEvaluator) => {
report += this.formatRepoEvaluator(repoEvaluator);
});
});
const orgEvaluatorsJson = Array.from(this.orgEvaluators.entries()).map(([orgEvaluator, repoEvaluators]) => ({
orgEvaluator: JSON.stringify(orgEvaluator),
repoEvaluators: repoEvaluators.map((repoEvaluator) => JSON.stringify(repoEvaluator)),
Expand Down
10 changes: 8 additions & 2 deletions dist/utils/policies.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ const loadPolicy = async (inputs) => {
let policy = {};
try {
Logger_1.logger.debug(`Loading policies from: ${inputs.policy_dir}`);
if (inputs.level === "organization") {
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);
}
else if (inputs.level === "repository_only") {
const repoPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "repository.yml"), "utf8");
policy.repo = js_yaml_1.default.load(repoPolicyFile);
}
else if (inputs.level === "repository") {
else if (inputs.level === "organization_and_repository") {
// Load organization policy
const orgPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "organization.yml"), "utf8");
policy.org = js_yaml_1.default.load(orgPolicyFile);
// Load repository policy
const repoPolicyFile = fs_1.default.readFileSync(path_1.default.join(inputs.policy_dir, "repository.yml"), "utf8");
policy.repo = js_yaml_1.default.load(repoPolicyFile);
}
Expand Down
81 changes: 36 additions & 45 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,75 +16,66 @@ const run = async (): Promise<void> => {
`);

// Adjusted part of the run function
try {
const startTime = process.hrtime();
const inputs = parseInputs();
const policies: any = await loadPolicy(inputs);

const policies: any = await loadPolicy(inputs);
logger.debug("DEBUG MODE: " + inputs.debug);
let report = new Report();
report.addInput(inputs);
report.addPolicy(policies);
// depending on which input.level is provided, run the appropriate checks
if (inputs.level === "organization") {
logger.info("Running org level checks");

const organizationPolicyEvaluator = new OrgPolicyEvaluator(
inputs.org,
policies.org as OrgPolicy,
);


if (inputs.level === "organization_only") {
logger.info("Running organization level checks only");
const organizationPolicyEvaluator = new OrgPolicyEvaluator(inputs.org, policies.org as OrgPolicy);
await organizationPolicyEvaluator.evaluatePolicy();
organizationPolicyEvaluator.printCheckResults();
report.addOrgEvaluator(organizationPolicyEvaluator);

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,
);
}),
);
} else if (inputs.level === "repository") {
} else if (inputs.level === "repository_only") {
logger.info("Running repository level checks only");
const repository: Repository = {
name: inputs.repo,
owner: inputs.org,
};
logger.info("Running repo level checks");

const policyEvaluator = 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.");

await policyEvaluator.evaluatePolicy();
policyEvaluator.printCheckResults();
report.addOneRepoEvaluator(policyEvaluator);
// Organization checks
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);
}));
} else {
// TODO: Implement enterprise level checks
logger.info("Running enterprise level checks => Not implemented yet");
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) {
Expand Down
Loading

0 comments on commit daee7d4

Please sign in to comment.