RepoAuditor 0.2.80__tar.gz → 0.2.82__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. {repoauditor-0.2.80 → repoauditor-0.2.82}/DEVELOPMENT.md +8 -2
  2. {repoauditor-0.2.80 → repoauditor-0.2.82}/PKG-INFO +37 -2
  3. {repoauditor-0.2.80 → repoauditor-0.2.82}/README.md +36 -1
  4. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DoNotAllowBypassSettings.py +1 -1
  5. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRulesetRequirementImpl.py +25 -1
  6. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetQuery.py +120 -0
  7. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/AllowMainlineForcePushes.py +40 -0
  8. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/DismissStalePullRequestApprovals.py +59 -0
  9. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/EnsureStatusChecks.py +69 -0
  10. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireApprovalMostRecentPush.py +58 -0
  11. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireApprovals.py +68 -0
  12. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireCodeOwnerReview.py +62 -0
  13. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireCodeScanningResults.py +39 -0
  14. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireConversationResolution.py +59 -0
  15. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireLinearHistory.py +40 -0
  16. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequirePullRequests.py +19 -3
  17. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireSignedCommits.py +17 -3
  18. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireStatusChecksToPass.py +38 -0
  19. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireSuccessfulDeployments.py +42 -0
  20. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireUpToDateBranches.py +60 -0
  21. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RestrictCreations.py +38 -0
  22. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RestrictDeletions.py +38 -0
  23. repoauditor-0.2.82/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RestrictUpdates.py +38 -0
  24. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/__init__.py +1 -1
  25. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubEnterprise_EndToEndTest.py +182 -0
  26. repoauditor-0.2.82/tests/Plugins/GitHubModule/RulesetRequirements_UnitTest.py +688 -0
  27. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHub_EndToEndTest.py +132 -6
  28. repoauditor-0.2.80/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr → repoauditor-0.2.82/tests/Plugins/__snapshots__/GitHubEnterprise_EndToEndTest.ambr +761 -699
  29. repoauditor-0.2.82/tests/Plugins/__snapshots__/GitHub_EndToEndTest.ambr +3306 -0
  30. repoauditor-0.2.80/src/RepoAuditor/Plugins/GitHub/RulesetQuery.py +0 -78
  31. repoauditor-0.2.80/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/RequireStatusChecks.py +0 -25
  32. repoauditor-0.2.80/tests/Plugins/GitHubModule/RulesetRequirements_UnitTest.py +0 -190
  33. repoauditor-0.2.80/tests/Plugins/__snapshots__/GitHubEnterprise_EndToEndTest.ambr +0 -1688
  34. {repoauditor-0.2.80 → repoauditor-0.2.82}/.copier-answers.yml +0 -0
  35. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/CODEOWNERS +0 -0
  36. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  37. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  38. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  39. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  40. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/actions/release_impl/action.yml +0 -0
  41. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/pull_request_template.md +0 -0
  42. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/release_sources.yaml +0 -0
  43. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/workflows/CICD.yml +0 -0
  44. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/workflows/CICD_impl.yml +0 -0
  45. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/workflows/EndToEnd.yml +0 -0
  46. {repoauditor-0.2.80 → repoauditor-0.2.82}/.github/workflows/codeql.yml +0 -0
  47. {repoauditor-0.2.80 → repoauditor-0.2.82}/.gitignore +0 -0
  48. {repoauditor-0.2.80 → repoauditor-0.2.82}/.pre-commit-config.yaml +0 -0
  49. {repoauditor-0.2.80 → repoauditor-0.2.82}/.python-version +0 -0
  50. {repoauditor-0.2.80 → repoauditor-0.2.82}/CODE_OF_CONDUCT.md +0 -0
  51. {repoauditor-0.2.80 → repoauditor-0.2.82}/CONTRIBUTING.md +0 -0
  52. {repoauditor-0.2.80 → repoauditor-0.2.82}/GOVERNANCE.md +0 -0
  53. {repoauditor-0.2.80 → repoauditor-0.2.82}/LICENSE +0 -0
  54. {repoauditor-0.2.80 → repoauditor-0.2.82}/MAINTAINERS.md +0 -0
  55. {repoauditor-0.2.80 → repoauditor-0.2.82}/SECURITY.md +0 -0
  56. {repoauditor-0.2.80 → repoauditor-0.2.82}/default_config.yaml +0 -0
  57. {repoauditor-0.2.80 → repoauditor-0.2.82}/minisign_key.pub +0 -0
  58. {repoauditor-0.2.80 → repoauditor-0.2.82}/pyproject.toml +0 -0
  59. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/AutoGitSemVer.yaml +0 -0
  60. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/CommandLineProcessor.py +0 -0
  61. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Display.py +0 -0
  62. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/EntryPoint.py +0 -0
  63. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/ExecuteModules.py +0 -0
  64. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Impl/ParallelSequentialProcessor.py +0 -0
  65. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Impl/__init__.py +0 -0
  66. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Module.py +0 -0
  67. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugin.py +0 -0
  68. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/CommunityStandardsQuery.py +0 -0
  69. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Impl/ExistsRequirementImpl.py +0 -0
  70. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Impl/__init__.py +0 -0
  71. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Module.py +0 -0
  72. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/CodeOfConduct.py +0 -0
  73. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/CodeOwners.py +0 -0
  74. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/Contributing.py +0 -0
  75. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/IssueTemplates.py +0 -0
  76. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/LicenseFile.py +0 -0
  77. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/PullRequestTemplates.py +0 -0
  78. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/ReadMe.py +0 -0
  79. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/SecurityPolicy.py +0 -0
  80. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/Requirements/__init__.py +0 -0
  81. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandards/__init__.py +0 -0
  82. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/CommunityStandardsPlugin.py +0 -0
  83. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionQuery.py +0 -0
  84. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowDeletions.py +0 -0
  85. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/AllowMainlineForcePushes.py +0 -0
  86. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals.py +0 -0
  87. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/EnsureStatusChecks.py +0 -0
  88. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicEnableRequirementImpl.py +0 -0
  89. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/ClassicValueRequirementImpl.py +0 -0
  90. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/Impl/__init__.py +0 -0
  91. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush.py +0 -0
  92. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireApprovals.py +0 -0
  93. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireCodeOwnerReview.py +0 -0
  94. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireConversationResolution.py +0 -0
  95. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireLinearHistory.py +0 -0
  96. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequirePullRequests.py +0 -0
  97. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireSignedCommits.py +0 -0
  98. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireStatusChecksToPass.py +0 -0
  99. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/RequireUpToDateBranches.py +0 -0
  100. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/ClassicBranchProtectionRequirements/__init__.py +0 -0
  101. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/DefaultBranchQuery.py +0 -0
  102. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/DefaultBranchRequirements/Protected.py +0 -0
  103. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/DefaultBranchRequirements/__init__.py +0 -0
  104. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/Impl/Common.py +0 -0
  105. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/Impl/EnableRequirementImpl.py +0 -0
  106. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/Impl/ValueRequirementImpl.py +0 -0
  107. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/Impl/__init__.py +0 -0
  108. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/Module.py +0 -0
  109. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/RulesetRequirements/__init__.py +0 -0
  110. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardQuery.py +0 -0
  111. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/AutoMerge.py +0 -0
  112. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/DefaultBranch.py +0 -0
  113. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/DeleteHeadBranches.py +0 -0
  114. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/DependabotSecurityUpdates.py +0 -0
  115. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Description.py +0 -0
  116. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Impl/StandardEnableRequirementImpl.py +0 -0
  117. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Impl/StandardValueRequirementImpl.py +0 -0
  118. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Impl/__init__.py +0 -0
  119. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/License.py +0 -0
  120. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/MergeCommit.py +0 -0
  121. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/MergeCommitMessage.py +0 -0
  122. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/Private.py +0 -0
  123. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/RebaseMergeCommit.py +0 -0
  124. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SecretScanning.py +0 -0
  125. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SecretScanningPushProtection.py +0 -0
  126. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SquashCommitMerge.py +0 -0
  127. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SquashMergeCommitMessage.py +0 -0
  128. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SuggestUpdatingPullRequestBranches.py +0 -0
  129. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportDiscussions.py +0 -0
  130. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportIssues.py +0 -0
  131. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportProjects.py +0 -0
  132. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/SupportWikis.py +0 -0
  133. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/TemplateRepository.py +0 -0
  134. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/WebCommitSignoff.py +0 -0
  135. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/StandardRequirements/__init__.py +0 -0
  136. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHub/__init__.py +0 -0
  137. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHubBase/Module.py +0 -0
  138. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHubBase/__init__.py +0 -0
  139. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/GitHubPlugin.py +0 -0
  140. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Plugins/__init__.py +0 -0
  141. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Query.py +0 -0
  142. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/Requirement.py +0 -0
  143. {repoauditor-0.2.80 → repoauditor-0.2.82}/src/RepoAuditor/py.typed +0 -0
  144. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/CommandLineProcessor_UnitTest.py +0 -0
  145. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/EntryPoint_UnitTest.py +0 -0
  146. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/ExecuteModules_UnitTest.py +0 -0
  147. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Module_UnitTest.py +0 -0
  148. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugin_UnitTest.py +0 -0
  149. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/CommunityStandards/CommunityStandardsQuery_UnitTest.py +0 -0
  150. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/CommunityStandards/ExistsRequirementImpl_UnitTest.py +0 -0
  151. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/CommunityStandards/GitHubCommunityStandards_UnitTest.py +0 -0
  152. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/CommunityStandards_EndToEndTest.py +0 -0
  153. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicBranchProtectionQuery_UnitTest.py +0 -0
  154. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/DismissStalePullRequestApprovals_UnitTest.py +0 -0
  155. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/EnsureStatusChecks_UnitTest.py +0 -0
  156. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovalMostRecentPush_UnitTest.py +0 -0
  157. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireApprovals_UnitTest.py +0 -0
  158. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireCodeOwnerReview_UnitTest.py +0 -0
  159. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicBranchProtectionRequirements/RequireUpToDateBranches_UnitTest.py +0 -0
  160. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ClassicValueRequirementImpl_UnitTest.py +0 -0
  161. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/DefaultBranchQueryRequirements/Protected_UnitTest.py +0 -0
  162. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/DefaultBranchQuery_UnitTest.py +0 -0
  163. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/EnableRulesetRequirementImpl_UnitTest.py +0 -0
  164. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/GitHubModule_UnitTest.py +0 -0
  165. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/GitHubSession_UnitTest.py +0 -0
  166. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/RulsesetQuery_UnitTest.py +0 -0
  167. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/DependabotSecurityUpdates_UnitTest.py +0 -0
  168. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/Description_UnitTest.py +0 -0
  169. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/License_UnitTest.py +0 -0
  170. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/MergeCommitMessage_UnitTest.py +0 -0
  171. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/Private_UnitTest.py +0 -0
  172. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanningPushProtection_UnitTest.py +0 -0
  173. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/SecretScanning_UnitTest.py +0 -0
  174. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQueryRequirements/SquashMergeCommitMessage_UnitTest.py +0 -0
  175. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/StandardQuery_UnitTest.py +0 -0
  176. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/ValueRequrementImpl_UnitTest.py +0 -0
  177. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/GitHubModule/fixtures.py +0 -0
  178. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/__snapshots__/CommunityStandards_EndToEndTest.ambr +0 -0
  179. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/conftest.py +0 -0
  180. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Plugins/utilities.py +0 -0
  181. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Query_UnitTest.py +0 -0
  182. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/Requirement_UnitTest.py +0 -0
  183. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/__init__.py +0 -0
  184. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/__snapshots__/ExecuteModules_UnitTest.ambr +0 -0
  185. {repoauditor-0.2.80 → repoauditor-0.2.82}/tests/conftest.py +0 -0
  186. {repoauditor-0.2.80 → repoauditor-0.2.82}/uv.lock +0 -0
@@ -77,6 +77,7 @@ Please follow the steps below to complete the configuration.
77
77
  - Click `Add classic branch protection rule`.
78
78
  - Under `Branch name pattern`, type in `main`.
79
79
  - Check `Require a pull request before merging`.
80
+ - Check `Require a pull request before merging -> Require approvals`.
80
81
  - Check `Require a pull request before merging -> Dismiss stale pull request approvals when new commits are pushed`.
81
82
  - Check `Require a pull request before merging -> Require approval of the most recent reviewable push`.
82
83
  - Under `Protect matching branches`
@@ -100,8 +101,13 @@ Please follow the steps below to complete the configuration.
100
101
  - Enable `Restrict deletions`
101
102
  - Enable `Require signed commits`
102
103
  - Enable `Require a pull request before merging` with 1 required approval.
103
- - Enable `Require status checks to pass` with the `CI+CD Workflow / Validate (ubuntu-latest, 3.12)` or an equivalent check.
104
- - Enable `Block force pushes`.
104
+ - Enable `Dismiss stale pull request approvals when new commits are pushed`.
105
+ - Enable `Require approval of the most recent reviewable push`.
106
+ - Enable `Require conversation resolution before merging`.
107
+ - Enable `Require status checks to pass`.
108
+ - Enable `Require branches to be up to date before merging`.
109
+ - Set the `CI+CD Workflow / Validate (ubuntu-latest, 3.12)` or an equivalent check.
110
+ - Disable `Block force pushes`.
105
111
  - Be sure to hit `Save changes` at the end.
106
112
 
107
113
  ### Development Activities
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RepoAuditor
3
- Version: 0.2.80
3
+ Version: 0.2.82
4
4
  Summary: Add your description here
5
5
  Project-URL: Homepage, https://github.com/gt-sse-center/RepoAuditor
6
6
  Project-URL: Documentation, https://github.com/gt-sse-center/RepoAuditor
@@ -142,6 +142,41 @@ uvx RepoAuditor --include GitHub \
142
142
 
143
143
  `RepoAuditor` will generate a series of messages describing all the issues in the repository, along with the rationale behind them and the steps for resolution.
144
144
 
145
+ ### Custom Settings
146
+
147
+ `RepoAuditor` tries to provide default settings and checks which are considered best practices. However, your team or organization may have different ways of doing things.
148
+ You can override the default settings by specifying the appropriate flag.
149
+
150
+ We have 3 types of flags:
151
+
152
+ 1. Boolean flags for those settings which are checked to be on by default and you wish to check are off, with the form `Module-no-Requirement` (e.g. `--GitHub-no-MergeCommit`).
153
+ 2. Conversely, boolean flags for those settings which are checked to be off by default, and you wish to check are on, denoted by the form `Module-Requirement` (e.g. `--GitHub-AllowDeletions`).
154
+ 3. Values flags take a string value to determine what value to enforce, and have the form `Module-Requirement-value` (e.g. `--GitHub-License-value "MIT License"`).
155
+
156
+ Please run `uvx repoauditor --help` to get the list of all flags available.
157
+
158
+ #### Examples
159
+
160
+ For example, `RepoAuditor` by default checks that the setting `Allow rebase merging` is off. If you wish to check that this setting is turned on, you can run:
161
+
162
+ ```shell
163
+ uvx repoauditor --GitHub-RebaseMergeCommit
164
+ ```
165
+
166
+ Similarly, `RepoAuditor` checks if `Issues` are enabled. You can set `RepoAuditor` to check if `Issues` is disabled by specifying
167
+
168
+ ```shell
169
+ uvx repoauditor --GitHub-no-SupportIssues
170
+ ```
171
+
172
+ Finally, `RepoAuditor` by default enforces that the `MIT License` exists for the repository. If your organization requires another license (such as `GPL`), you can enforce that by specifying the license keyword such as:
173
+
174
+ ```shell
175
+ uvx repoauditor --GitHub-License-value "GNU General Public License v2.0"
176
+ ```
177
+
178
+ The types of licenses supported by GitHub can be found [here](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository#searching-github-by-license-type). Be sure to specify the full license name, e.g. `GNU General Public License v2.0`.
179
+
145
180
  ### Config File
146
181
 
147
182
  `RepoAuditor` accepts both a set of flags as well as a configuratin YAML file.
@@ -172,4 +207,4 @@ Additional information can be found at these locations.
172
207
 
173
208
  ## License
174
209
 
175
- RepoAuditor is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
210
+ RepoAuditor is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
@@ -115,6 +115,41 @@ uvx RepoAuditor --include GitHub \
115
115
 
116
116
  `RepoAuditor` will generate a series of messages describing all the issues in the repository, along with the rationale behind them and the steps for resolution.
117
117
 
118
+ ### Custom Settings
119
+
120
+ `RepoAuditor` tries to provide default settings and checks which are considered best practices. However, your team or organization may have different ways of doing things.
121
+ You can override the default settings by specifying the appropriate flag.
122
+
123
+ We have 3 types of flags:
124
+
125
+ 1. Boolean flags for those settings which are checked to be on by default and you wish to check are off, with the form `Module-no-Requirement` (e.g. `--GitHub-no-MergeCommit`).
126
+ 2. Conversely, boolean flags for those settings which are checked to be off by default, and you wish to check are on, denoted by the form `Module-Requirement` (e.g. `--GitHub-AllowDeletions`).
127
+ 3. Values flags take a string value to determine what value to enforce, and have the form `Module-Requirement-value` (e.g. `--GitHub-License-value "MIT License"`).
128
+
129
+ Please run `uvx repoauditor --help` to get the list of all flags available.
130
+
131
+ #### Examples
132
+
133
+ For example, `RepoAuditor` by default checks that the setting `Allow rebase merging` is off. If you wish to check that this setting is turned on, you can run:
134
+
135
+ ```shell
136
+ uvx repoauditor --GitHub-RebaseMergeCommit
137
+ ```
138
+
139
+ Similarly, `RepoAuditor` checks if `Issues` are enabled. You can set `RepoAuditor` to check if `Issues` is disabled by specifying
140
+
141
+ ```shell
142
+ uvx repoauditor --GitHub-no-SupportIssues
143
+ ```
144
+
145
+ Finally, `RepoAuditor` by default enforces that the `MIT License` exists for the repository. If your organization requires another license (such as `GPL`), you can enforce that by specifying the license keyword such as:
146
+
147
+ ```shell
148
+ uvx repoauditor --GitHub-License-value "GNU General Public License v2.0"
149
+ ```
150
+
151
+ The types of licenses supported by GitHub can be found [here](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository#searching-github-by-license-type). Be sure to specify the full license name, e.g. `GNU General Public License v2.0`.
152
+
118
153
  ### Config File
119
154
 
120
155
  `RepoAuditor` accepts both a set of flags as well as a configuratin YAML file.
@@ -145,4 +180,4 @@ Additional information can be found at these locations.
145
180
 
146
181
  ## License
147
182
 
148
- RepoAuditor is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
183
+ RepoAuditor is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
@@ -4,7 +4,7 @@
4
4
  # | Distributed under the MIT License.
5
5
  # |
6
6
  # -------------------------------------------------------------------------------
7
- """Contains the AllowBypassSettings object."""
7
+ """Contains the DoNotAllowBypassSettings object."""
8
8
 
9
9
  import textwrap
10
10
 
@@ -6,6 +6,7 @@
6
6
  # -------------------------------------------------------------------------------
7
7
  """Contains the EnableRequirementImpl object."""
8
8
 
9
+ import textwrap
9
10
  from collections.abc import Callable
10
11
  from typing import Any, Optional
11
12
 
@@ -28,14 +29,24 @@ class EnableRulesetRequirementImpl(EnableRequirementImpl):
28
29
  github_ruleset_type: str,
29
30
  github_ruleset_value: str,
30
31
  get_configuration_value_func: Callable[[dict[str, Any]], Optional[bool]],
31
- resolution: str,
32
32
  rationale: str,
33
+ resolution: Optional[str] = None,
33
34
  subject: Optional[str] = None,
34
35
  *,
35
36
  requires_explicit_include: bool = False,
36
37
  unset_set_terminology: tuple[str, str] = ("disabled", "enabled"),
37
38
  missing_value_is_warning: bool = True,
38
39
  ) -> None:
40
+ if resolution is None:
41
+ resolution = textwrap.dedent(
42
+ """\
43
+ 1) Visit '{session.github_url}/settings/rules'.
44
+ 2) Find or create a ruleset on the branch '{branch}'.
45
+ 3) Go to '{__ruleset_value}'.
46
+ 4) {__enabled_str} the rule.
47
+ """
48
+ )
49
+
39
50
  super().__init__(
40
51
  name=name,
41
52
  enabled_by_default=enabled_by_default,
@@ -52,6 +63,17 @@ class EnableRulesetRequirementImpl(EnableRequirementImpl):
52
63
 
53
64
  self.github_ruleset_type = github_ruleset_type
54
65
 
66
+ # ----------------------------------------------------------------------
67
+ def _GetValue(
68
+ self,
69
+ rule: dict[str, Any],
70
+ ) -> Optional[bool]:
71
+ rule_type = rule.get("type")
72
+ if rule_type is None:
73
+ return None
74
+
75
+ return rule_type == self.github_ruleset_type
76
+
55
77
  # ----------------------------------------------------------------------
56
78
  @override
57
79
  def _EvaluateImpl(
@@ -70,6 +92,8 @@ class EnableRulesetRequirementImpl(EnableRequirementImpl):
70
92
 
71
93
  query_data["__expected_value"] = expected_rule_enabled
72
94
  query_data["__enabled_str"] = "Enable" if expected_rule_enabled else "Disable"
95
+ # ruleset_value is stored as settings_value
96
+ query_data["__ruleset_value"] = self.github_settings_value
73
97
 
74
98
  # Get the rules for the specified branch
75
99
  rules = query_data.get("rules", [])
@@ -0,0 +1,120 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the RulesetQuery object."""
8
+
9
+ from typing import Any, Optional
10
+
11
+ from dbrownell_Common.Types import override
12
+
13
+ from RepoAuditor.Impl.ParallelSequentialProcessor import ExecutionStyle
14
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.AllowMainlineForcePushes import (
15
+ AllowMainlineForcePushesRule,
16
+ )
17
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.DismissStalePullRequestApprovals import (
18
+ DismissStalePullRequestApprovalsRule,
19
+ )
20
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.EnsureStatusChecks import EnsureStatusChecksRule
21
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireApprovalMostRecentPush import (
22
+ RequireApprovalMostRecentPushRule,
23
+ )
24
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireApprovals import RequireApprovalsRule
25
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireCodeOwnerReview import RequireCodeOwnerReviewRule
26
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireCodeScanningResults import (
27
+ RequireCodeScanningResultsRule,
28
+ )
29
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireConversationResolution import (
30
+ RequireConversationResolutionRule,
31
+ )
32
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireLinearHistory import RequireLinearHistoryRule
33
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequirePullRequests import RequirePullRequests
34
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireSignedCommits import RequireSignedCommits
35
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireStatusChecksToPass import (
36
+ RequireStatusChecksToPassRule,
37
+ )
38
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireSuccessfulDeployments import (
39
+ RequireSuccessfulDeploymentsRule,
40
+ )
41
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RequireUpToDateBranches import RequireUpToDateBranchesRule
42
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RestrictCreations import RestrictCreationsRule
43
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RestrictDeletions import RestrictDeletionsRule
44
+ from RepoAuditor.Plugins.GitHub.RulesetRequirements.RestrictUpdates import RestrictUpdatesRule
45
+ from RepoAuditor.Query import Query
46
+
47
+
48
+ class RulesetQuery(Query):
49
+ """Query to validate GitHub repository rulesets."""
50
+
51
+ def __init__(self) -> None:
52
+ super().__init__(
53
+ "RulesetQuery",
54
+ ExecutionStyle.Parallel,
55
+ [
56
+ RestrictCreationsRule(),
57
+ RestrictUpdatesRule(),
58
+ RestrictDeletionsRule(),
59
+ RequireLinearHistoryRule(),
60
+ RequireSuccessfulDeploymentsRule(),
61
+ RequireSignedCommits(),
62
+ RequirePullRequests(),
63
+ RequireApprovalsRule(),
64
+ DismissStalePullRequestApprovalsRule(),
65
+ RequireCodeOwnerReviewRule(),
66
+ RequireApprovalMostRecentPushRule(),
67
+ RequireConversationResolutionRule(),
68
+ RequireStatusChecksToPassRule(),
69
+ RequireUpToDateBranchesRule(),
70
+ EnsureStatusChecksRule(),
71
+ AllowMainlineForcePushesRule(),
72
+ RequireCodeScanningResultsRule(),
73
+ ],
74
+ )
75
+
76
+ @override
77
+ def GetData(
78
+ self,
79
+ module_data: dict[str, Any],
80
+ ) -> Optional[dict[str, Any]]:
81
+ """Retrieve data required for validating GitHub rulesets.
82
+
83
+ Args:
84
+ module_data (dict): Dictionary containing initial data from the module.
85
+
86
+ Returns:
87
+ Optional[dict]: A dictionary containing ruleset-related
88
+ data, or None if an error occurs.
89
+
90
+ """
91
+ branch = module_data.get("branch")
92
+ if branch is None:
93
+ # Get the default branch name
94
+ response = module_data["session"].get("")
95
+
96
+ response.raise_for_status()
97
+ response = response.json()
98
+
99
+ branch = response["default_branch"]
100
+
101
+ # Record the branch name
102
+ module_data["branch"] = branch
103
+
104
+ # Fetch ruleset data for a specific branch.
105
+ # This only returns active rules on the branch
106
+ rules_response = module_data["session"].get(f"rules/branches/{branch}")
107
+
108
+ rules_response.raise_for_status()
109
+
110
+ # Add ruleset data to module_data
111
+ module_data["rules"] = rules_response.json()
112
+
113
+ # Also get the associated ruleset for each rule
114
+ for rule in module_data["rules"]:
115
+ ruleset_response = module_data["session"].get(f"rulesets/{rule['ruleset_id']}")
116
+ ruleset_response.raise_for_status()
117
+ ruleset = ruleset_response.json()
118
+ rule["ruleset"] = ruleset
119
+
120
+ return module_data
@@ -0,0 +1,40 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the AllowMainlineForcePushesRule requirement."""
8
+
9
+ import textwrap
10
+
11
+ from RepoAuditor.Plugins.GitHub.Impl.EnableRulesetRequirementImpl import EnableRulesetRequirementImpl
12
+
13
+
14
+ class AllowMainlineForcePushesRule(EnableRulesetRequirementImpl):
15
+ """Requirement for rule to allow force pushes to the matching branch."""
16
+
17
+ def __init__(self) -> None:
18
+ super().__init__(
19
+ name="AllowMainlineForcePushesRule",
20
+ enabled_by_default=False,
21
+ dynamic_arg_name="yes",
22
+ github_ruleset_type="non_fast_forward",
23
+ github_ruleset_value="Block force pushes",
24
+ get_configuration_value_func=self._GetValue,
25
+ rationale=textwrap.dedent(
26
+ """\
27
+ The default behavior is to not allow force pushes to the mainline branch.
28
+
29
+ Reasons for this Default
30
+ ------------------------
31
+ - Force pushes rewrite history, which breaks git lineage for all other clones of the repository.
32
+ Merges are possible when this happens, but they are difficult to perform and data loss is
33
+ possible.
34
+
35
+ Reasons to Override this Default
36
+ --------------------------------
37
+ <unknown>
38
+ """,
39
+ ),
40
+ )
@@ -0,0 +1,59 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the DismissStalePullRequestApprovalsRule object."""
8
+
9
+ import textwrap
10
+ from typing import Any, Optional
11
+
12
+ from dbrownell_Common.Types import override # type: ignore[import-untyped]
13
+
14
+ from RepoAuditor.Plugins.GitHub.Impl.EnableRulesetRequirementImpl import EnableRulesetRequirementImpl
15
+
16
+
17
+ # ----------------------------------------------------------------------
18
+ class DismissStalePullRequestApprovalsRule(EnableRulesetRequirementImpl):
19
+ """Rule to dismiss stale pull request approvals when new commits are pushed."""
20
+
21
+ # ----------------------------------------------------------------------
22
+ def __init__(self) -> None:
23
+ super().__init__(
24
+ name="DismissStalePullRequestApprovalsRule",
25
+ enabled_by_default=True,
26
+ dynamic_arg_name="no",
27
+ github_ruleset_type="dismiss_stale_reviews_on_push",
28
+ github_ruleset_value="Require a pull request before merging -> Dismiss stale pull request approvals when new commits are pushed",
29
+ get_configuration_value_func=self._GetValue,
30
+ rationale=textwrap.dedent(
31
+ """\
32
+ The default behavior is to dismiss stale pull request approvals when new commits are pushed.
33
+
34
+ Reasons for this Default
35
+ ------------------------
36
+ - Approvals apply to the changes as they existed when the approval was granted. The approval
37
+ may no longer be valid when new changes are pushed.
38
+
39
+ Reasons to Override this Default
40
+ --------------------------------
41
+ You trust the contributor to only make minor changes after approval.
42
+ """
43
+ ),
44
+ )
45
+
46
+ # ----------------------------------------------------------------------
47
+ @override
48
+ def _GetValue(
49
+ self,
50
+ rule: dict[str, Any],
51
+ ) -> Optional[bool]:
52
+ rule_type = rule.get("type")
53
+ if rule_type is None:
54
+ return None
55
+
56
+ if rule_type == "pull_request":
57
+ return rule["parameters"].get(self.github_ruleset_type, False)
58
+
59
+ return False
@@ -0,0 +1,69 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the EnsureStatusChecksRule object."""
8
+
9
+ import textwrap
10
+ from typing import Any, Optional
11
+
12
+ from dbrownell_Common.Types import override # type: ignore[import-untyped]
13
+
14
+ from RepoAuditor.Plugins.GitHub.Impl.EnableRulesetRequirementImpl import EnableRulesetRequirementImpl
15
+
16
+
17
+ # ----------------------------------------------------------------------
18
+ class EnsureStatusChecksRule(EnableRulesetRequirementImpl):
19
+ """Rule to verify status checks have been assigned as a rule for a branch."""
20
+
21
+ # ----------------------------------------------------------------------
22
+ def __init__(self) -> None:
23
+ super().__init__(
24
+ name="EnsureStatusChecksRule",
25
+ enabled_by_default=True,
26
+ dynamic_arg_name="no",
27
+ github_ruleset_type="required_status_checks",
28
+ github_ruleset_value="Require status checks to pass -> Status checks that are required",
29
+ get_configuration_value_func=self._GetValue,
30
+ resolution=textwrap.dedent(
31
+ """\
32
+ 1) Visit '{session.github_url}/settings/rules'.
33
+ 2) Find or create a ruleset on the branch '{branch}'.
34
+ 3) Go to '{__ruleset_value}'.
35
+ 4) Click on '+ Add checks'.
36
+ 5) Type the name of the check to enforce.
37
+ 6) Select status checks that must pass before merging.
38
+ """,
39
+ ),
40
+ rationale=textwrap.dedent(
41
+ """\
42
+ The default behavior is to require the specification of at least one status check that must pass before merging.
43
+
44
+ Reasons for this Default
45
+ ------------------------
46
+ - A Continuous Integration process must be gated by some activity, action, or work flow.
47
+
48
+ Reasons to Override this Default
49
+ --------------------------------
50
+ - Code reviews are sufficient to ensure the quality of pull requests before they are merged into the branch
51
+ (this is not recommended).
52
+ """
53
+ ),
54
+ )
55
+
56
+ # ----------------------------------------------------------------------
57
+ @override
58
+ def _GetValue(
59
+ self,
60
+ rule: dict[str, Any],
61
+ ) -> Optional[bool]:
62
+ rule_type = rule.get("type")
63
+
64
+ # If rule_type doesn't exist,
65
+ # it means the rule is not applicable
66
+ if rule_type and rule_type == self.github_ruleset_type:
67
+ return len(rule["parameters"][self.github_ruleset_type]) > 0
68
+
69
+ return False
@@ -0,0 +1,58 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the RequireApprovalMostRecentPushRule object."""
8
+
9
+ import textwrap
10
+ from typing import Any, Optional
11
+
12
+ from dbrownell_Common.Types import override # type: ignore[import-untyped]
13
+
14
+ from RepoAuditor.Plugins.GitHub.Impl.EnableRulesetRequirementImpl import EnableRulesetRequirementImpl
15
+
16
+
17
+ # ----------------------------------------------------------------------
18
+ class RequireApprovalMostRecentPushRule(EnableRulesetRequirementImpl):
19
+ """Rule to require approval on the most recent reviewable push in a pull request."""
20
+
21
+ # ----------------------------------------------------------------------
22
+ def __init__(self) -> None:
23
+ super().__init__(
24
+ name="RequireApprovalMostRecentPushRule",
25
+ enabled_by_default=True,
26
+ dynamic_arg_name="no",
27
+ github_ruleset_type="require_last_push_approval",
28
+ github_ruleset_value="Require a pull request before merging -> Require approval of the most recent reviewable push",
29
+ get_configuration_value_func=self._GetValue,
30
+ rationale=textwrap.dedent(
31
+ """\
32
+ The default behavior is to require approval of the most recent reviewable push by someone other than the author of the pull request.
33
+
34
+ Reasons for this Default
35
+ ------------------------
36
+ - Self-approval of a pull request eliminates the value provided by a second pair of eyes during a code review.
37
+
38
+ Reasons to Override this Default
39
+ --------------------------------
40
+ - You are the only person working on the repository.
41
+ """,
42
+ ),
43
+ )
44
+
45
+ # ----------------------------------------------------------------------
46
+ @override
47
+ def _GetValue(
48
+ self,
49
+ rule: dict[str, Any],
50
+ ) -> Optional[bool]:
51
+ rule_type = rule.get("type")
52
+ if rule_type is None:
53
+ return None
54
+
55
+ if rule_type == "pull_request":
56
+ return rule["parameters"].get(self.github_ruleset_type, False)
57
+
58
+ return False
@@ -0,0 +1,68 @@
1
+ # -------------------------------------------------------------------------------
2
+ # |
3
+ # | Copyright (c) 2024 Scientific Software Engineering Center at Georgia Tech
4
+ # | Distributed under the MIT License.
5
+ # |
6
+ # -------------------------------------------------------------------------------
7
+ """Contains the RequireApprovalsRule object."""
8
+
9
+ import textwrap
10
+ from typing import Any, Optional
11
+
12
+ from dbrownell_Common.Types import override # type: ignore[import-untyped]
13
+
14
+ from RepoAuditor.Plugins.GitHub.Impl.EnableRulesetRequirementImpl import EnableRulesetRequirementImpl
15
+
16
+
17
+ # ----------------------------------------------------------------------
18
+ class RequireApprovalsRule(EnableRulesetRequirementImpl):
19
+ """Rule to require at least 1 approval on a pull request."""
20
+
21
+ # ----------------------------------------------------------------------
22
+ def __init__(self) -> None:
23
+ super().__init__(
24
+ name="RequireApprovalsRule",
25
+ enabled_by_default=True,
26
+ dynamic_arg_name="no",
27
+ github_ruleset_type="required_approving_review_count",
28
+ github_ruleset_value="Require a pull request before merging -> Required approvals",
29
+ get_configuration_value_func=self._GetValue,
30
+ resolution=textwrap.dedent(
31
+ """\
32
+ 1) Visit '{session.github_url}/settings/rules'.
33
+ 2) Find or create a ruleset on the branch '{branch}'.
34
+ 3) Go to '{__ruleset_value}'.
35
+ 4) Set the number of required approvals to at least 1.
36
+ """
37
+ ),
38
+ rationale=textwrap.dedent(
39
+ """\
40
+ The default behavior is to require at least one approval.
41
+
42
+ Reasons for this Default
43
+ ------------------------
44
+ - Code Reviews are a generally accepted best practice for software development.
45
+
46
+ Reasons to Override this Default
47
+ --------------------------------
48
+ - You are the only person working on the repository (set the value to 0).
49
+ - You want to require more than one approval (set the value to the number of approvals required).
50
+ - You are not comfortable with the amount of time code reviews introduce in the development process (set the value to 0).
51
+ """,
52
+ ),
53
+ )
54
+
55
+ # ----------------------------------------------------------------------
56
+ @override
57
+ def _GetValue(
58
+ self,
59
+ rule: dict[str, Any],
60
+ ) -> Optional[bool]:
61
+ rule_type = rule.get("type")
62
+ if rule_type is None:
63
+ return None
64
+
65
+ if rule_type == "pull_request":
66
+ return rule["parameters"].get(self.github_ruleset_type, 0) > 0
67
+
68
+ return False