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 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
@@ -0,0 +1,3 @@
1
+ {
2
+ "profanitySureness": 1
3
+ }
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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WayOfWorking
4
+ module Audit
5
+ module Github
6
+ VERSION = '1.0.1'
7
+ end
8
+ end
9
+ 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: []