way_of_working-audit-github 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.alexrc +3 -0
- data/.mega-linter.yml +145 -0
- data/.rubocop +1 -0
- data/CHANGELOG.md +24 -0
- data/LICENSE.txt +21 -0
- data/README.md +57 -0
- data/Rakefile +16 -0
- data/code_safety.yml +122 -0
- data/lib/way_of_working/audit/github/auditor.rb +43 -0
- data/lib/way_of_working/audit/github/generators/exec.rb +125 -0
- data/lib/way_of_working/audit/github/plugin.rb +1 -0
- data/lib/way_of_working/audit/github/rules/base.rb +89 -0
- data/lib/way_of_working/audit/github/rules/registry.rb +36 -0
- data/lib/way_of_working/audit/github/rules/unknown.rb +19 -0
- data/lib/way_of_working/audit/github/version.rb +9 -0
- data/lib/way_of_working/audit/github.rb +40 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 88c26bf5fa25e6781969f4b99218e1f2d4935b114b2b054729b5a16de68063e9
|
4
|
+
data.tar.gz: d7383261a3b640c720f950a2493836a91ba05478206db6c85fc07960a0d41800
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7bc8e9a733c7a5814bbb9aeded92150e2cb613128d97a27c93de5a9f53a6501d723b3a5528268b5f681e92654abf7c3b3576a7b75c154b2fcde7fa1996b2fdde
|
7
|
+
data.tar.gz: ae783fae452ac723536c0a418a9c55bd1d894d166ec0680a3b7e242313ee52a0d85cc8ed8e6192321b67b7ef04640faad795129efbeb73afe45c30b385d22d8d
|
data/.alexrc
ADDED
data/.mega-linter.yml
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
---
|
2
|
+
# Configuration file for MegaLinter
|
3
|
+
# See all available variables at https://megalinter.io/configuration/
|
4
|
+
# and in linters documentation
|
5
|
+
|
6
|
+
APPLY_FIXES: none # all, none, or list of linter keys
|
7
|
+
ENABLE_LINTERS: # All other linters will be disabled by default
|
8
|
+
### Languages
|
9
|
+
- BASH_EXEC # in Super-Linter
|
10
|
+
- BASH_SHELLCHECK # in Super-Linter
|
11
|
+
- BASH_SHFMT # in Super-Linter
|
12
|
+
- C_CLANG_FORMAT
|
13
|
+
- C_CPPLINT
|
14
|
+
# - CLOJURE_CLJ_KONDO # in Super-Linter
|
15
|
+
# - CLOJURE_CLJSTYLE
|
16
|
+
- COFFEE_COFFEELINT # in Super-Linter
|
17
|
+
- CPP_CLANG_FORMAT
|
18
|
+
- CPP_CPPLINT # in Super-Linter
|
19
|
+
- CSHARP_CSHARPIER
|
20
|
+
- CSHARP_DOTNET_FORMAT # in Super-Linter
|
21
|
+
- CSHARP_ROSLYNATOR
|
22
|
+
- DART_DARTANALYZER # in Super-Linter
|
23
|
+
- GO_GOLANGCI_LINT # in Super-Linter
|
24
|
+
- GO_REVIVE
|
25
|
+
# - GROOVY_NPM_GROOVY_LINT # in Super-Linter
|
26
|
+
- JAVA_CHECKSTYLE # in Super-Linter
|
27
|
+
- JAVA_PMD
|
28
|
+
- JAVASCRIPT_ES # in Super-Linter
|
29
|
+
# - JAVASCRIPT_PRETTIER
|
30
|
+
- JAVASCRIPT_STANDARD # in Super-Linter
|
31
|
+
- JSX_ESLINT
|
32
|
+
- KOTLIN_DETEKT
|
33
|
+
- KOTLIN_KTLINT # in Super-Linter
|
34
|
+
# - LUA_LUACHECK # in Super-Linter
|
35
|
+
# - LUA_SELENE
|
36
|
+
# - LUA_STYLUA
|
37
|
+
- MAKEFILE_CHECKMAKE
|
38
|
+
# - PERL_PERLCRITIC # in Super-Linter
|
39
|
+
# - PHP_BUILTIN
|
40
|
+
# - PHP_PHPCS # in Super-Linter
|
41
|
+
# - PHP_PHPCSFIXER
|
42
|
+
# - PHP_PHPLINT # in Super-Linter
|
43
|
+
# - PHP_PHPSTAN # in Super-Linter
|
44
|
+
# - PHP_PSALM # in Super-Linter
|
45
|
+
# - POWERSHELL_POWERSHELL
|
46
|
+
# - POWERSHELL_POWERSHELL_FORMATTER
|
47
|
+
- PYTHON_BANDIT
|
48
|
+
- PYTHON_BLACK # in Super-Linter
|
49
|
+
- PYTHON_FLAKE8 # in Super-Linter
|
50
|
+
- PYTHON_ISORT # in Super-Linter
|
51
|
+
- PYTHON_MYPY
|
52
|
+
- PYTHON_PYLINT # in Super-Linter
|
53
|
+
- PYTHON_PYRIGHT
|
54
|
+
- PYTHON_RUFF
|
55
|
+
- R_LINTR # in Super-Linter
|
56
|
+
# - RAKU_RAKU # in Super-Linter
|
57
|
+
# - RUBY_RUBOCOP # in Super-Linter
|
58
|
+
- RUST_CLIPPY # in Super-Linter
|
59
|
+
# - SALESFORCE_LIGHTNING_FLOW_SCANNER
|
60
|
+
# - SALESFORCE_SFDX_SCANNER_APEX
|
61
|
+
# - SALESFORCE_SFDX_SCANNER_AURA
|
62
|
+
# - SALESFORCE_SFDX_SCANNER_LWC
|
63
|
+
- SCALA_SCALAFIX
|
64
|
+
- SQL_SQLFLUFF # in Super-Linter
|
65
|
+
- SQL_TSQLLINT
|
66
|
+
- SWIFT_SWIFTLINT
|
67
|
+
- TSX_ESLINT
|
68
|
+
- TYPESCRIPT_ES # in Super-Linter
|
69
|
+
# - TYPESCRIPT_PRETTIER
|
70
|
+
- TYPESCRIPT_STANDARD # in Super-Linter
|
71
|
+
# - VBDOTNET_DOTNET_FORMAT
|
72
|
+
|
73
|
+
### Formats
|
74
|
+
- CSS_STYLELINT # in Super-Linter
|
75
|
+
- ENV_DOTENV_LINTER # in Super-Linter
|
76
|
+
# - GRAPHQL_GRAPHQL_SCHEMA_LINTER
|
77
|
+
# - HTML_DJLINT # Refuses to see config file
|
78
|
+
- HTML_HTMLHINT # in Super-Linter
|
79
|
+
- JSON_ESLINT_PLUGIN_JSONC # in Super-Linter
|
80
|
+
- JSON_JSONLINT
|
81
|
+
- JSON_NPM_PACKAGE_JSON_LINT
|
82
|
+
# - JSON_PRETTIER
|
83
|
+
- JSON_V8R
|
84
|
+
# - LATEX_CHKTEX # in Super-Linter
|
85
|
+
- MARKDOWN_MARKDOWNLINT # in Super-Linter
|
86
|
+
- MARKDOWN_MARKDOWN_LINK_CHECK
|
87
|
+
- MARKDOWN_MARKDOWN_TABLE_FORMATTER
|
88
|
+
- MARKDOWN_REMARK_LINT
|
89
|
+
# - PROTOBUF_PROTOLINT # in Super-Linter
|
90
|
+
# - RST_RSTCHECK
|
91
|
+
# - RST_RSTFMT
|
92
|
+
# - RST_RST_LINT
|
93
|
+
- XML_XMLLINT # in Super-Linter
|
94
|
+
# - YAML_PRETTIER
|
95
|
+
- YAML_V8R
|
96
|
+
- YAML_YAMLLINT # in Super-Linter
|
97
|
+
|
98
|
+
### Tooling
|
99
|
+
- ACTION_ACTIONLINT # in Super-Linter
|
100
|
+
- ANSIBLE_ANSIBLE_LINT # in Super-Linter
|
101
|
+
- API_SPECTRAL
|
102
|
+
- ARM_ARM_TTK # in Super-Linter
|
103
|
+
# - BICEP_BICEP_LINTER
|
104
|
+
- CLOUDFORMATION_CFN_LINT # in Super-Linter
|
105
|
+
- DOCKERFILE_HADOLINT # in Super-Linter
|
106
|
+
- EDITORCONFIG_EDITORCONFIG_CHECKER # in Super-Linter
|
107
|
+
# - GHERKIN_GHERKIN_LINT # in Super-Linter
|
108
|
+
- KUBERNETES_HELM
|
109
|
+
- KUBERNETES_KUBECONFORM
|
110
|
+
- KUBERNETES_KUBESCAPE
|
111
|
+
- PUPPET_PUPPET_LINT
|
112
|
+
# - SNAKEMAKE_LINT # in Super-Linter
|
113
|
+
# - SNAKEMAKE_SNAKEFMT # in Super-Linter
|
114
|
+
# - TEKTON_TEKTON_LINT # in Super-Linter
|
115
|
+
- TERRAFORM_TERRAFORM_FMT # in Super-Linter
|
116
|
+
- TERRAFORM_TERRAGRUNT # in Super-Linter
|
117
|
+
- TERRAFORM_TERRASCAN # in Super-Linter
|
118
|
+
- TERRAFORM_TFLINT # in Super-Linter
|
119
|
+
|
120
|
+
### Code quality checkers
|
121
|
+
- COPYPASTE_JSCPD # in Super-Linter
|
122
|
+
- REPOSITORY_CHECKOV
|
123
|
+
- REPOSITORY_DEVSKIM
|
124
|
+
- REPOSITORY_DUSTILOCK
|
125
|
+
- REPOSITORY_GIT_DIFF
|
126
|
+
- REPOSITORY_GITLEAKS # in Super-Linter
|
127
|
+
- REPOSITORY_GRYPE
|
128
|
+
- REPOSITORY_KICS
|
129
|
+
- REPOSITORY_LS_LINT
|
130
|
+
- REPOSITORY_SECRETLINT
|
131
|
+
- REPOSITORY_SEMGREP
|
132
|
+
- REPOSITORY_SYFT
|
133
|
+
- REPOSITORY_TRIVY
|
134
|
+
- REPOSITORY_TRIVY_SBOM
|
135
|
+
- REPOSITORY_TRUFFLEHOG
|
136
|
+
# - SPELL_CSPELL
|
137
|
+
- SPELL_LYCHEE
|
138
|
+
- SPELL_PROSELINT
|
139
|
+
- SPELL_VALE
|
140
|
+
|
141
|
+
SHOW_ELAPSED_TIME: false
|
142
|
+
FILEIO_REPORTER: false
|
143
|
+
FAIL_IF_MISSING_LINTER_IN_FLAVOR: true
|
144
|
+
# DISABLE_ERRORS: true # Uncomment if you want MegaLinter to detect
|
145
|
+
# errors but not block CI to pass
|
data/.rubocop
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--config .github/linters/rubocop_defaults.yml
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
## [1.0.1] - 2025-01-24
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
- Linted a return from a code block
|
15
|
+
|
16
|
+
## [1.0.0] - 2025-01-24
|
17
|
+
|
18
|
+
### Added
|
19
|
+
|
20
|
+
- Initial implementation of the auditor, registry and exec command generator
|
21
|
+
|
22
|
+
[unreleased]: https://github.com/HealthDataInsight/way_of_working-audit-github/compare/v1.0.1...HEAD
|
23
|
+
[1.0.1]: https://github.com/HealthDataInsight/way_of_working-audit-github/compare/v1.0.0...v1.0.1
|
24
|
+
[1.0.0]: https://github.com/HealthDataInsight/way_of_working-audit-github/releases/tag/v1.0.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Health Data Insight CIC
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# WayOfWorking::Audit::Github
|
2
|
+
|
3
|
+
<!-- Way of Working: Main Badge Holder Start -->
|
4
|
+
![Way of Working Badge](https://img.shields.io/badge/Way_of_Working-v2.0.1-%238169e3?labelColor=black)
|
5
|
+
<!-- Way of Working: Additional Badge Holder Start -->
|
6
|
+
<!-- Way of Working: Badge Holder End -->
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
A [Way of Working](https://github.com/HealthDataInsight/way_of_working) plugin that provides a registry and auditing tool for GitHub repositories. Rules can check for both missing/incorrect files and mis-configuration of the repository itself. Many existing plugins have defined their own rules to check that they have been adopted properly.
|
11
|
+
|
12
|
+
Work is ongoing on a plugin for CIS GitHub Benchmark compliance testing.
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Install the gem and add to the application's Gemfile by executing:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
20
|
+
```
|
21
|
+
|
22
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
26
|
+
```
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
Define the following environment variables:
|
31
|
+
|
32
|
+
- `GITHUB_ORGANISATION`: the name of your organisation being scanned (as used in the GitHub URL)
|
33
|
+
- `GITHUB_TOKEN`: a PAT token with sufficient permission to access repositories and their configuration.
|
34
|
+
|
35
|
+
Then to run the GitHub audit for your project, use:
|
36
|
+
|
37
|
+
```bash
|
38
|
+
way_of_working exec audit_github
|
39
|
+
```
|
40
|
+
|
41
|
+
## Development
|
42
|
+
|
43
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
44
|
+
|
45
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/HealthDataInsight/way_of_working-audit-github>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/HealthDataInsight/way_of_working-audit-github/blob/main/CODE_OF_CONDUCT.md).
|
50
|
+
|
51
|
+
## License
|
52
|
+
|
53
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
54
|
+
|
55
|
+
## Code of Conduct
|
56
|
+
|
57
|
+
Everyone interacting in the way_of_working-audit-github project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/HealthDataInsight/way_of_working-audit-github/blob/main/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'way_of_working/tasks'
|
6
|
+
|
7
|
+
Rake::TestTask.new(:test) do |t|
|
8
|
+
t.libs << 'lib'
|
9
|
+
t.libs << 'test'
|
10
|
+
t.test_files = FileList['test/**/*_test.rb']
|
11
|
+
t.verbose = false
|
12
|
+
t.warning = false
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Run tests'
|
16
|
+
task default: :test
|
data/code_safety.yml
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
---
|
2
|
+
file safety:
|
3
|
+
".alexrc":
|
4
|
+
comments:
|
5
|
+
reviewed_by: shilpigoeldev
|
6
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
7
|
+
".github/linters/.markdown-link-check.json":
|
8
|
+
comments:
|
9
|
+
reviewed_by: shilpigoeldev
|
10
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
11
|
+
".github/linters/rubocop_defaults.yml":
|
12
|
+
comments:
|
13
|
+
reviewed_by: shilpigoeldev
|
14
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
15
|
+
".github/workflows/inclusive-language.yml":
|
16
|
+
comments:
|
17
|
+
reviewed_by: shilpigoeldev
|
18
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
19
|
+
".github/workflows/main.yml":
|
20
|
+
comments:
|
21
|
+
reviewed_by: shilpigoeldev
|
22
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
23
|
+
".github/workflows/mega-linter.yml":
|
24
|
+
comments:
|
25
|
+
reviewed_by: shilpigoeldev
|
26
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
27
|
+
".gitignore":
|
28
|
+
comments:
|
29
|
+
reviewed_by: shilpigoeldev
|
30
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
31
|
+
".mega-linter.yml":
|
32
|
+
comments:
|
33
|
+
reviewed_by: shilpigoeldev
|
34
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
35
|
+
".rubocop":
|
36
|
+
comments:
|
37
|
+
reviewed_by: shilpigoeldev
|
38
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
39
|
+
CHANGELOG.md:
|
40
|
+
comments:
|
41
|
+
reviewed_by: shilpigoeldev
|
42
|
+
safe_revision: ed3796d3dcd6d7314ee994c852e3e966df9c0d32
|
43
|
+
Gemfile:
|
44
|
+
comments:
|
45
|
+
reviewed_by: shilpigoeldev
|
46
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
47
|
+
Gemfile.lock:
|
48
|
+
comments:
|
49
|
+
reviewed_by: shilpigoeldev
|
50
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
51
|
+
LICENSE.txt:
|
52
|
+
comments:
|
53
|
+
reviewed_by: shilpigoeldev
|
54
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
55
|
+
README.md:
|
56
|
+
comments:
|
57
|
+
reviewed_by: shilpigoeldev
|
58
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
59
|
+
Rakefile:
|
60
|
+
comments:
|
61
|
+
reviewed_by: shilpigoeldev
|
62
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
63
|
+
bin/console:
|
64
|
+
comments:
|
65
|
+
reviewed_by: shilpigoeldev
|
66
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
67
|
+
bin/setup:
|
68
|
+
comments:
|
69
|
+
reviewed_by: shilpigoeldev
|
70
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
71
|
+
lib/way_of_working/audit/github.rb:
|
72
|
+
comments:
|
73
|
+
reviewed_by: shilpigoeldev
|
74
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
75
|
+
lib/way_of_working/audit/github/auditor.rb:
|
76
|
+
comments:
|
77
|
+
reviewed_by: shilpigoeldev
|
78
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
79
|
+
lib/way_of_working/audit/github/generators/exec.rb:
|
80
|
+
comments:
|
81
|
+
reviewed_by: shilpigoeldev
|
82
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
83
|
+
lib/way_of_working/audit/github/plugin.rb:
|
84
|
+
comments:
|
85
|
+
reviewed_by: shilpigoeldev
|
86
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
87
|
+
lib/way_of_working/audit/github/rules/base.rb:
|
88
|
+
comments:
|
89
|
+
reviewed_by: shilpigoeldev
|
90
|
+
safe_revision: ed3796d3dcd6d7314ee994c852e3e966df9c0d32
|
91
|
+
lib/way_of_working/audit/github/rules/registry.rb:
|
92
|
+
comments:
|
93
|
+
reviewed_by: shilpigoeldev
|
94
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
95
|
+
lib/way_of_working/audit/github/rules/unknown.rb:
|
96
|
+
comments:
|
97
|
+
reviewed_by: shilpigoeldev
|
98
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
99
|
+
lib/way_of_working/audit/github/version.rb:
|
100
|
+
comments:
|
101
|
+
reviewed_by: shilpigoeldev
|
102
|
+
safe_revision: ed3796d3dcd6d7314ee994c852e3e966df9c0d32
|
103
|
+
test/test_helper.rb:
|
104
|
+
comments:
|
105
|
+
reviewed_by: shilpigoeldev
|
106
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
107
|
+
test/way_of_working/audit/github/rule_test.rb:
|
108
|
+
comments:
|
109
|
+
reviewed_by: shilpigoeldev
|
110
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
111
|
+
test/way_of_working/audit/github/zeitwerk_loader_test.rb:
|
112
|
+
comments:
|
113
|
+
reviewed_by: shilpigoeldev
|
114
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
115
|
+
test/way_of_working/audit/github_test.rb:
|
116
|
+
comments:
|
117
|
+
reviewed_by: shilpigoeldev
|
118
|
+
safe_revision: 84e86c45c31ac0e37a13cf39d2bbbff01391f39d
|
119
|
+
way_of_working-audit-github.gemspec:
|
120
|
+
comments:
|
121
|
+
reviewed_by: shilpigoeldev
|
122
|
+
safe_revision: 4f2b65e6f3eda6c9213348886916aa391cd2e295
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
require_relative 'rules/registry'
|
3
|
+
|
4
|
+
module WayOfWorking
|
5
|
+
module Audit
|
6
|
+
module Github
|
7
|
+
# This auditor runs all the rules against any given GitHub repository
|
8
|
+
class Auditor
|
9
|
+
def initialize(access_token, organisation_name)
|
10
|
+
@access_token = access_token
|
11
|
+
@organisation_name = organisation_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def audit(repository)
|
15
|
+
# Get all the rules once, rather than repeatedly in individual rules
|
16
|
+
rulesets = @client.get("repos/#{repository.full_name}/rulesets").map do |rule|
|
17
|
+
@client.get("repos/#{repository.full_name}/rulesets/#{rule[:id]}")
|
18
|
+
end
|
19
|
+
|
20
|
+
Array(Rules::Registry.rules).each do |rule_name, klass|
|
21
|
+
rule = klass.new(client, rule_name, repository, rulesets)
|
22
|
+
|
23
|
+
yield rule
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def repositories
|
28
|
+
@repositories ||= client.org_repos(@organisation_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def client
|
34
|
+
@client ||= begin
|
35
|
+
client = Octokit::Client.new(access_token: @access_token) # , per_page: 1_000
|
36
|
+
client.auto_paginate = true
|
37
|
+
client
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'git'
|
4
|
+
require 'rainbow'
|
5
|
+
require 'thor'
|
6
|
+
require 'way_of_working/audit/github/auditor'
|
7
|
+
# require 'way_of_working/github_audit/rules/all'
|
8
|
+
|
9
|
+
module WayOfWorking
|
10
|
+
module Audit
|
11
|
+
module Github
|
12
|
+
module Generators
|
13
|
+
# This generator runs the github audit
|
14
|
+
class Exec < Thor::Group
|
15
|
+
# argument :all_repos, type: :string, required: false, desc: 'Optional repo to test'
|
16
|
+
|
17
|
+
desc 'This runs the github audit on this project'
|
18
|
+
|
19
|
+
def check_for_github_token_environment_variables
|
20
|
+
@github_token = ENV.fetch('GITHUB_TOKEN', nil)
|
21
|
+
return unless @github_token.nil?
|
22
|
+
|
23
|
+
abort(Rainbow("\nMissing GITHUB_TOKEN environment variable").red)
|
24
|
+
end
|
25
|
+
|
26
|
+
def check_for_github_organisation_environment_variables
|
27
|
+
@github_organisation = ENV.fetch('GITHUB_ORGANISATION', nil)
|
28
|
+
return unless @github_organisation.nil?
|
29
|
+
|
30
|
+
abort(Rainbow("\nMissing GITHUB_ORGANISATION environment variable").red)
|
31
|
+
end
|
32
|
+
|
33
|
+
def start_timer
|
34
|
+
@start_time = Time.now
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_github_organisation_remotes
|
38
|
+
abort(Rainbow("\nGitHub is not an upstream repository.").red) if github_organisation_remotes.empty?
|
39
|
+
|
40
|
+
# say(Rainbow("Limiting audit to #{path}\n").yellow) if path
|
41
|
+
say "\nRunning..."
|
42
|
+
end
|
43
|
+
|
44
|
+
def prep_audit
|
45
|
+
@auditor = ::WayOfWorking::Audit::Github::Auditor.new(@github_token, @github_organisation)
|
46
|
+
|
47
|
+
# Loop though all the repos
|
48
|
+
@repositories = @auditor.repositories # .to_a[20..]
|
49
|
+
@repositories = @repositories.select do |repo|
|
50
|
+
github_organisation_remotes.include?(repo.name)
|
51
|
+
end
|
52
|
+
rescue Octokit::Unauthorized
|
53
|
+
abort(Rainbow("\nGITHUB_TOKEN has expired or does not have sufficient permission").red)
|
54
|
+
end
|
55
|
+
|
56
|
+
def run_audit
|
57
|
+
@audit_ok = true
|
58
|
+
unarchived_repos.each do |repo|
|
59
|
+
@auditor.audit(repo) do |rule|
|
60
|
+
case rule.status
|
61
|
+
when :not_applicable
|
62
|
+
# Do nothing
|
63
|
+
when :passed
|
64
|
+
say "✅ #{rule.tags.inspect} Passed #{rule.name}"
|
65
|
+
when :failed
|
66
|
+
say "❌ #{rule.tags.inspect} Failed #{rule.name}: #{rule.errors.to_sentence}"
|
67
|
+
@audit_ok = false
|
68
|
+
else
|
69
|
+
abort(Rainbow("Unknown response #{rule.status.inspect}").red)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def run_last
|
76
|
+
say(Rainbow("\nTotal time taken: #{(Time.now - @start_time).to_i} seconds").yellow)
|
77
|
+
|
78
|
+
if @audit_ok
|
79
|
+
say(Rainbow("\nGitHub audit succeeded!").green)
|
80
|
+
else
|
81
|
+
abort(Rainbow("\nGitHub audit failed!").red)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def unarchived_repos(&block)
|
88
|
+
return to_enum(__method__) unless block_given?
|
89
|
+
|
90
|
+
@repositories.each do |repo|
|
91
|
+
if repo.archived?
|
92
|
+
say(Rainbow("\nSkipping archived repo: #{repo.name}").yellow)
|
93
|
+
|
94
|
+
next
|
95
|
+
end
|
96
|
+
|
97
|
+
say("#{repo.name} [#{repo.private? ? 'Private' : 'Public'}] #{repo.description} " \
|
98
|
+
"#{repo.language} #{repo.topics.join(',')}")
|
99
|
+
|
100
|
+
block.call(repo)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# This method returns the repo names for all upstream repositories
|
105
|
+
# hosted on GitHub, for the given organisation
|
106
|
+
def github_organisation_remotes
|
107
|
+
@github_organisation_remotes ||= begin
|
108
|
+
all_remote_urls = ::Git.open('.').remotes.map(&:url)
|
109
|
+
|
110
|
+
organisation_remote_urls = all_remote_urls.select do |url|
|
111
|
+
url.start_with?("https://github.com/#{@github_organisation}")
|
112
|
+
end
|
113
|
+
|
114
|
+
organisation_remote_urls.map do |url|
|
115
|
+
matchdata = url.match(%r{\Ahttps://github.com/([^/]+)/([^/]+)\.git})
|
116
|
+
|
117
|
+
matchdata[2]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'way_of_working/audit/github'
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
require 'base64'
|
6
|
+
require 'octokit'
|
7
|
+
require_relative 'registry'
|
8
|
+
|
9
|
+
module WayOfWorking
|
10
|
+
module Audit
|
11
|
+
module Github
|
12
|
+
module Rules
|
13
|
+
# This is the base class for GitHub audit rules
|
14
|
+
class Base
|
15
|
+
attr_accessor :errors, :name, :rulesets, :warnings
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# Stores and return the source root for this class
|
19
|
+
def source_root(path = nil)
|
20
|
+
@source_root = path if path
|
21
|
+
@source_root ||= nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(client, name, repo, rulesets)
|
26
|
+
@client = client
|
27
|
+
@name = name
|
28
|
+
@repo = repo
|
29
|
+
@repo_name = repo.full_name
|
30
|
+
@rulesets = rulesets
|
31
|
+
@errors = []
|
32
|
+
@warnings = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def status
|
36
|
+
@status ||= begin
|
37
|
+
result = validate
|
38
|
+
|
39
|
+
if result == :not_applicable
|
40
|
+
result
|
41
|
+
else
|
42
|
+
@errors.empty? ? :passed : :failed
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate
|
48
|
+
$stdout.puts 'Rule#valid? has been deprecated, use "validate"'
|
49
|
+
valid?
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.tags
|
53
|
+
[:way_of_working]
|
54
|
+
end
|
55
|
+
|
56
|
+
def tags
|
57
|
+
self.class.tags
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def repo_file_contents(path)
|
63
|
+
response = @client.contents(@repo_name, path: path)
|
64
|
+
Base64.decode64(response.content).force_encoding('UTF-8')
|
65
|
+
rescue Octokit::NotFound
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method returns the content of the README file
|
70
|
+
def readme_content
|
71
|
+
@readme_content ||=
|
72
|
+
begin
|
73
|
+
response = @client.readme(@repo_name)
|
74
|
+
|
75
|
+
Base64.decode64(response.content).force_encoding('UTF-8')
|
76
|
+
rescue Octokit::NotFound
|
77
|
+
''
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# This convenience method returns the branch rules for this repo
|
82
|
+
def branch_rules(branch)
|
83
|
+
@client.get("repos/#{@repo.full_name}/rules/branches/#{branch}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'unknown'
|
4
|
+
|
5
|
+
module WayOfWorking
|
6
|
+
module Audit
|
7
|
+
module Github
|
8
|
+
module Rules
|
9
|
+
# This provides the GitHub audit rule factory
|
10
|
+
module Registry
|
11
|
+
class << self
|
12
|
+
attr_accessor :rules
|
13
|
+
|
14
|
+
def register(klass, rule_name)
|
15
|
+
@rules ||= {}
|
16
|
+
|
17
|
+
@rules[rule_name] = klass
|
18
|
+
end
|
19
|
+
|
20
|
+
def unregister(*rule_names)
|
21
|
+
rule_names.each do |rule_name|
|
22
|
+
@rules.delete(rule_name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def rule(rule_name, client, repo)
|
27
|
+
klass = Registry.rules.fetch(rule_name, Unknown)
|
28
|
+
|
29
|
+
klass.new(client, repo)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module WayOfWorking
|
6
|
+
module Audit
|
7
|
+
module Github
|
8
|
+
module Rules
|
9
|
+
# This is a stub handler for rules that aren't in the registry.
|
10
|
+
class Unknown < Base
|
11
|
+
def initialize(client, repo_name)
|
12
|
+
super
|
13
|
+
raise 'Error: Unknown client'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'way_of_working'
|
4
|
+
require 'zeitwerk'
|
5
|
+
|
6
|
+
loader = Zeitwerk::Loader.for_gem_extension(WayOfWorking::Audit)
|
7
|
+
loader.ignore("#{__dir__}/github/plugin.rb")
|
8
|
+
loader.setup
|
9
|
+
|
10
|
+
module WayOfWorking
|
11
|
+
module Audit
|
12
|
+
module Github
|
13
|
+
class Error < StandardError; end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module SubCommands
|
18
|
+
# This reopens the "way_of_working exec" sub command
|
19
|
+
class Exec
|
20
|
+
register(Audit::Github::Generators::Exec, 'audit_github', 'audit_github',
|
21
|
+
<<~LONGDESC)
|
22
|
+
Description:
|
23
|
+
This runs the GitHub audit
|
24
|
+
|
25
|
+
Example:
|
26
|
+
way_of_working exec audit_github
|
27
|
+
LONGDESC
|
28
|
+
end
|
29
|
+
|
30
|
+
# # This reopens the "way_of_working init" sub command
|
31
|
+
# class Init
|
32
|
+
# register(Audit::Github::Generators::Init, 'audit', 'audit',
|
33
|
+
# end
|
34
|
+
|
35
|
+
# # This reopens the "way_of_working new" sub command
|
36
|
+
# class New
|
37
|
+
# register(Audit::Github::Generators::New, 'audit', 'audit [NAME]',
|
38
|
+
# end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: way_of_working-audit-github
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tim Gentry
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-01-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday-multipart
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday-retry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: octokit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '9.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '9.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: way_of_working
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: zeitwerk
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.6.18
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.6.18
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- 52189+timgentry@users.noreply.github.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".alexrc"
|
91
|
+
- ".mega-linter.yml"
|
92
|
+
- ".rubocop"
|
93
|
+
- CHANGELOG.md
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- code_safety.yml
|
98
|
+
- lib/way_of_working/audit/github.rb
|
99
|
+
- lib/way_of_working/audit/github/auditor.rb
|
100
|
+
- lib/way_of_working/audit/github/generators/exec.rb
|
101
|
+
- lib/way_of_working/audit/github/plugin.rb
|
102
|
+
- lib/way_of_working/audit/github/rules/base.rb
|
103
|
+
- lib/way_of_working/audit/github/rules/registry.rb
|
104
|
+
- lib/way_of_working/audit/github/rules/unknown.rb
|
105
|
+
- lib/way_of_working/audit/github/version.rb
|
106
|
+
homepage: https://github.com/HealthDataInsight/way_of_working-audit-github
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata:
|
110
|
+
allowed_push_host: https://rubygems.org
|
111
|
+
rubygems_mfa_required: 'true'
|
112
|
+
homepage_uri: https://github.com/HealthDataInsight/way_of_working-audit-github
|
113
|
+
source_code_uri: https://github.com/HealthDataInsight/way_of_working-audit-github
|
114
|
+
changelog_uri: https://github.com/HealthDataInsight/way_of_working-audit-github/blob/main/CHANGELOG.md
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 3.1.0
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubygems_version: 3.5.22
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Way of Working plugin for GitHub auditing
|
134
|
+
test_files: []
|