way_of_working-audit-github 1.0.1

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.
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: []