diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml index 63a91da..ce9fd3f 100644 --- a/.github/workflows/acceptance.yml +++ b/.github/workflows/acceptance.yml @@ -17,7 +17,7 @@ jobs: has_change: ${{ steps.diff.outputs.has_change}} steps: - - uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2 + - uses: actions/checkout@v3 - id: fetch-base if: github.event_name == 'pull_request' @@ -66,9 +66,9 @@ jobs: run: | echo "✅ Bypassing acceptance tests - they are not required for this change" - - name: Check out code + - name: checkout if: ${{ needs.changes.outputs.has_change == 'true' }} - uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2 + uses: actions/checkout@v3 # Use Docker layer caching for 'docker build' and 'docker-compose build' commands. # https://github.com/satackey/action-docker-layer-caching/releases/tag/v0.0.11 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..1f69d66 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: build + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_call: + +permissions: + contents: read + +jobs: + build: + name: build + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # pin@v1.152.0 + with: + bundler-cache: true + + - name: bootstrap + run: script/bootstrap + + - name: build + run: | + GEM_NAME=$(ls | grep gemspec | cut -d. -f1) + echo "Attempting to build gem $GEM_NAME..." + gem build $GEM_NAME + if [ $? -eq 0 ]; then + echo "Gem built successfully!" + else + echo "Gem build failed!" + exit 1 + fi diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index eec268e..e629800 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,4 +1,4 @@ -name: "CodeQL" +name: CodeQL on: push: @@ -24,8 +24,8 @@ jobs: language: [ 'ruby' ] steps: - - name: Checkout repository - uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2 + - name: checkout + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/gem.yml b/.github/workflows/gem.yml deleted file mode 100644 index bc74e81..0000000 --- a/.github/workflows/gem.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Publish and Release Gem -on: - push: - branches: [ $default-branch ] - paths: [ "VERSION" ] - workflow_dispatch: - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - - - name: Setup Ruby - uses: ruby/setup-ruby@8a45918450651f5e4784b6031db26f4b9f76b251 - with: - bundler-cache: true - - - name: Run Tests - run: script/test - - - name: Build Gem - run: | - echo "GEM_VERSION=$(gem build entitlements-github-plugin.gemspec 2>&1 | grep Version | cut -d':' -f 2 | tr -d " \t\n\r")" >> $GITHUB_ENV - - - name: Publish to GitHub Packages - run: | - GEM_HOST_API_KEY=${{ secrets.GITHUB_TOKEN }} gem push --KEY github --host https://rubygems.pkg.github.com/github entitlements-github-plugin-${{ env.GEM_VERSION }}.gem diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3ed1ba5..37f21e9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,12 +14,11 @@ jobs: contents: read steps: - - name: Check out code - uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2 + - name: checkout + uses: actions/checkout@v3 - - uses: ruby/setup-ruby@8029ebd6e5bd8f4e0d6f7623ea76a01ec5b1010d # pin@v1.110.0 + - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # pin@v1.152.0 with: - ruby-version: 3.1.2 bundler-cache: true - name: rubocop diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5c3d25b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,53 @@ +name: release + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - lib/version.rb + +permissions: + contents: write + packages: write + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # pin@v1.152.0 + with: + bundler-cache: true + + - name: bootstrap + run: script/bootstrap + + - name: lint + run: bundle exec rubocop -c .rubocop.yml lib/ spec/ + + - name: test + run: script/test + + - name: set GEM_NAME from gemspec + run: echo "GEM_NAME=$(ls | grep gemspec | cut -d. -f1)" >> $GITHUB_ENV + + # builds the gem and saves the version to GITHUB_ENV + - name: build + run: echo "GEM_VERSION=$(gem build ${{ env.GEM_NAME }}.gemspec 2>&1 | grep Version | cut -d':' -f 2 | tr -d " \t\n\r")" >> $GITHUB_ENV + + - name: publish to GitHub packages + run: | + export OWNER=$( echo ${{ github.repository }} | cut -d "/" -f 1 ) + GEM_HOST_API_KEY=${{ secrets.GITHUB_TOKEN }} gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} ${{ env.GEM_NAME }}-${{ env.GEM_VERSION }}.gem + + - name: release + uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # pin@v1.12.0 + with: + artifacts: "${{ env.GEM_NAME }}-${{ env.GEM_VERSION }}.gem" + tag: "v${{ env.GEM_VERSION }}" + generateReleaseNotes: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index edc9e15..7833f83 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,12 +14,11 @@ jobs: contents: read steps: - - name: Check out code - uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2 + - name: checkout + uses: actions/checkout@v3 - - uses: ruby/setup-ruby@8029ebd6e5bd8f4e0d6f7623ea76a01ec5b1010d # pin@v1.110.0 + - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # pin@v1.152.0 with: - ruby-version: 3.1.2 bundler-cache: true - name: rspec tests diff --git a/.rubocop.yml b/.rubocop.yml index f2a38d8..5ae9443 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,8 +3,9 @@ inherit_gem: - config/default.yml AllCops: + SuggestExtensions: false DisplayCopNames: true - TargetRubyVersion: 2.7.5 + TargetRubyVersion: 3.1 Exclude: - 'bin/*' - 'spec/acceptance/fixtures/**/*' diff --git a/Gemfile.lock b/Gemfile.lock index 2a69b58..4bc69ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - entitlements-github-plugin (0.2.0) + entitlements-github-plugin (0.3.0) contracts (= 0.17.0) faraday (~> 2.0) faraday-retry (~> 2.0) diff --git a/README.md b/README.md index de364c0..4122006 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # entitlements-github-plugin -[![acceptance](https://github.com/github/entitlements-github-plugin/actions/workflows/acceptance.yml/badge.svg)](https://github.com/github/entitlements-github-plugin/actions/workflows/acceptance.yml) [![test](https://github.com/github/entitlements-github-plugin/actions/workflows/test.yml/badge.svg)](https://github.com/github/entitlements-github-plugin/actions/workflows/test.yml) [![lint](https://github.com/github/entitlements-github-plugin/actions/workflows/lint.yml/badge.svg)](https://github.com/github/entitlements-github-plugin/actions/workflows/lint.yml) [![coverage](https://img.shields.io/badge/coverage-100%25-success)](https://img.shields.io/badge/coverage-100%25-success) [![style](https://img.shields.io/badge/code%20style-rubocop--github-blue)](https://github.com/github/rubocop-github) +[![acceptance](https://github.com/github/entitlements-github-plugin/actions/workflows/acceptance.yml/badge.svg)](https://github.com/github/entitlements-github-plugin/actions/workflows/acceptance.yml) [![test](https://github.com/github/entitlements-github-plugin/actions/workflows/test.yml/badge.svg)](https://github.com/github/entitlements-github-plugin/actions/workflows/test.yml) [![lint](https://github.com/github/entitlements-github-plugin/actions/workflows/lint.yml/badge.svg)](https://github.com/github/entitlements-github-plugin/actions/workflows/lint.yml) [![release](https://github.com/github/entitlements-github-plugin/actions/workflows/release.yml/badge.svg)](https://github.com/github/entitlements-github-plugin/actions/workflows/release.yml) [![coverage](https://img.shields.io/badge/coverage-100%25-success)](https://img.shields.io/badge/coverage-100%25-success) [![style](https://img.shields.io/badge/code%20style-rubocop--github-blue)](https://github.com/github/rubocop-github) `entitlements-github-plugin` is an [entitlements-app](https://github.com/github/entitlements-app) plugin allowing entitlements configs to be used to manage membership of GitHub.com Organizations and Teams. @@ -82,3 +82,13 @@ For example, if there were a file `github.com/github/teams/new-team.txt` with a Entitlements configs can contain metadata which the plugin will use to make further configuration decisions. `metadata_parent_team_name` - when defined in an entitlements config, the defined team will be made the parent team of this GitHub.com Team. + +## Release 🚀 + +To release a new version of this Gem, do the following: + +1. Update the version number in the [`lib/version.rb`](lib/version.rb) file +2. Run `bundle install` to update the `Gemfile.lock` file with the new version +3. Commit your changes, push them to GitHub, and open a PR + +Once your PR is approved and the changes are merged, a new release will be created automatically by the [`release.yml`](.github/workflows/release.yml) workflow. The latest version of the Gem will be published to the GitHub Package Registry. diff --git a/VERSION b/VERSION deleted file mode 100644 index 0ea3a94..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.2.0 diff --git a/entitlements-github-plugin.gemspec b/entitlements-github-plugin.gemspec index d077b54..e62d35c 100644 --- a/entitlements-github-plugin.gemspec +++ b/entitlements-github-plugin.gemspec @@ -1,14 +1,16 @@ # frozen_string_literal: true +require_relative "lib/version" + Gem::Specification.new do |s| s.name = "entitlements-github-plugin" - s.version = File.read("VERSION").chomp + s.version = Entitlements::Version::VERSION s.summary = "GitHub dotcom provider for entitlements-app" - s.description = "" + s.description = "Entitlements plugin to manage GitHub Orgs and Team memberships and access" s.authors = ["GitHub, Inc. Security Ops"] s.email = "security@github.com" s.license = "MIT" - s.files = Dir.glob("lib/**/*") + %w[VERSION] + s.files = Dir.glob("lib/**/*") s.homepage = "https://github.com/github/entitlements-github-plugin" s.executables = %w[] diff --git a/lib/entitlements/backend/github_org/controller.rb b/lib/entitlements/backend/github_org/controller.rb index 10b8e4e..f4c5be0 100644 --- a/lib/entitlements/backend/github_org/controller.rb +++ b/lib/entitlements/backend/github_org/controller.rb @@ -83,7 +83,7 @@ def calculate validate_no_dupes! # calls read() for each group if changes.any? - print_differences(key: group_name, added: [], removed: [], changed: changes, ignored_users: ignored_users) + print_differences(key: group_name, added: [], removed: [], changed: changes, ignored_users:) @actions.concat(changes) else logger.debug "UNCHANGED: No GitHub organization changes for #{group_name}" @@ -398,11 +398,11 @@ def categorized_changes if removed.key?(member.downcase) # Already removed from a previous role. Therefore this is a move to a different role. removed.delete(member.downcase) - moved[member.downcase] = { member: member, role: role } + moved[member.downcase] = { member:, role: } else # Not removed from a previous role. Suspect this is an addition to the org (if we later spot a removal # from a role, then the code below will update that to be a move instead). - added[member.downcase] = { member: member, role: role } + added[member.downcase] = { member:, role: } end end @@ -414,12 +414,12 @@ def categorized_changes else # Not added to a previous role. Suspect this is a removal from the org (if we later spot an addition # to another role, then the code above will update that to be a move instead). - removed[member.downcase] = { member: member, role: role } + removed[member.downcase] = { member:, role: } end end end - { added: added, removed: removed, moved: moved } + { added:, removed:, moved: } end # Admins or members who are both `invited` and `pending` do not need to be re-invited. We're waiting for them diff --git a/lib/entitlements/backend/github_org/service.rb b/lib/entitlements/backend/github_org/service.rb index 6efcbd8..2c57482 100644 --- a/lib/entitlements/backend/github_org/service.rb +++ b/lib/entitlements/backend/github_org/service.rb @@ -44,7 +44,7 @@ def sync(implementation, role) Contract String, String => C::Bool def add_user_to_organization(user, role) Entitlements.logger.debug "#{identifier} add_user_to_organization(user=#{user}, org=#{org}, role=#{role})" - new_membership = octokit.update_organization_membership(org, user: user, role: role) + new_membership = octokit.update_organization_membership(org, user:, role:) # Happy path if new_membership[:role] == role @@ -70,7 +70,7 @@ def add_user_to_organization(user, role) Contract String => C::Bool def remove_user_from_organization(user) Entitlements.logger.debug "#{identifier} remove_user_from_organization(user=#{user}, org=#{org})" - result = octokit.remove_organization_membership(org, user: user) + result = octokit.remove_organization_membership(org, user:) # If we removed the user, remove them from the cache of members, so that any GitHub team # operations in this organization will ignore this user. diff --git a/lib/entitlements/backend/github_team/controller.rb b/lib/entitlements/backend/github_team/controller.rb index 04ddd7d..d5df8ec 100644 --- a/lib/entitlements/backend/github_team/controller.rb +++ b/lib/entitlements/backend/github_team/controller.rb @@ -61,12 +61,12 @@ def calculate end if diff[:metadata] && diff[:metadata][:create_team] - added << Entitlements::Models::Action.new(team_slug, provider.read(group), group, group_name, ignored_users: ignored_users) + added << Entitlements::Models::Action.new(team_slug, provider.read(group), group, group_name, ignored_users:) else - changed << Entitlements::Models::Action.new(team_slug, provider.read(group), group, group_name, ignored_users: ignored_users) + changed << Entitlements::Models::Action.new(team_slug, provider.read(group), group, group_name, ignored_users:) end end - print_differences(key: group_name, added: added, removed: [], changed: changed) + print_differences(key: group_name, added:, removed: [], changed:) @actions = added + changed end diff --git a/lib/entitlements/backend/github_team/models/team.rb b/lib/entitlements/backend/github_team/models/team.rb index 6f37441..0be33bf 100644 --- a/lib/entitlements/backend/github_team/models/team.rb +++ b/lib/entitlements/backend/github_team/models/team.rb @@ -27,7 +27,7 @@ def initialize(team_id:, team_name:, members:, ou:, metadata:) @team_id = team_id @team_name = team_name.downcase @team_dn = ["cn=#{team_name.downcase}", ou].join(",") - super(dn: @team_dn, members: Set.new(members.map { |m| m.downcase }), metadata: metadata) + super(dn: @team_dn, members: Set.new(members.map { |m| m.downcase }), metadata:) end end end diff --git a/lib/entitlements/backend/github_team/provider.rb b/lib/entitlements/backend/github_team/provider.rb index 11b6e30..2fe1813 100644 --- a/lib/entitlements/backend/github_team/provider.rb +++ b/lib/entitlements/backend/github_team/provider.rb @@ -127,7 +127,7 @@ def commit(entitlement_group) # Create the new team and invalidate the cache if github_team.nil? team_name = entitlement_group.cn.downcase - github.create_team(entitlement_group: entitlement_group) + github.create_team(entitlement_group:) github.invalidate_predictive_cache(entitlement_group) @github_team_cache.delete(team_name) github_team = github.read_team(entitlement_group) @@ -168,7 +168,7 @@ def create_github_team_group(entitlement_group) team_name: entitlement_group.cn.downcase, members: Set.new, ou: github.ou, - metadata: metadata + metadata: ) end diff --git a/lib/entitlements/backend/github_team/service.rb b/lib/entitlements/backend/github_team/service.rb index a174150..e65b581 100644 --- a/lib/entitlements/backend/github_team/service.rb +++ b/lib/entitlements/backend/github_team/service.rb @@ -78,7 +78,7 @@ def read_team(entitlement_group) team_id: -1, team_name: team_identifier, members: cached_members, - ou: ou, + ou:, metadata: team_metadata ) @@ -108,7 +108,7 @@ def read_team(entitlement_group) team_id: teamdata[:team_id], team_name: team_identifier, members: Set.new(teamdata[:members]), - ou: ou, + ou:, metadata: team_metadata ) rescue TeamNotFound @@ -380,7 +380,7 @@ def graphql_team_data(team_slug) break end - { members: result, team_id: team_id, parent_team_name: parent_team_name } + { members: result, team_id:, parent_team_name: } end # Ensure that the given team ID actually matches up to the team slug on GitHub. This is in place @@ -425,7 +425,7 @@ def add_user_to_team(user:, team:, role: "member") end Entitlements.logger.debug "#{identifier} add_user_to_team(user=#{user}, org=#{org}, team_id=#{team.team_id}, role=#{role})" validate_team_id_and_slug!(team.team_id, team.team_name) - result = octokit.add_team_membership(team.team_id, user, role: role) + result = octokit.add_team_membership(team.team_id, user, role:) result[:state] == "active" || result[:state] == "pending" end diff --git a/lib/entitlements/service/github.rb b/lib/entitlements/service/github.rb index 7c33d70..3a440a6 100644 --- a/lib/entitlements/service/github.rb +++ b/lib/entitlements/service/github.rb @@ -82,7 +82,7 @@ def org_members member_count = result.count { |_, role| role == "member" } Entitlements.logger.debug "Currently #{org} has #{admin_count} admin(s) and #{member_count} member(s)" - { cache: cache, value: result } + { cache:, value: result } end Entitlements.cache[:github_org_members][org_signature][:value] @@ -354,9 +354,9 @@ def graphql_http_post_real(query) data = JSON.parse(response.body) if data.key?("errors") Entitlements.logger.error "Errors reported: #{data['errors'].inspect}" - return { code: 500, data: data } + return { code: 500, data: } end - { code: response.code.to_i, data: data } + { code: response.code.to_i, data: } rescue JSON::ParserError => e Entitlements.logger.error "#{e.class} #{e.message}: #{response.body.inspect}" { code: 500, data: { "body" => response.body } } diff --git a/lib/version.rb b/lib/version.rb new file mode 100644 index 0000000..423f893 --- /dev/null +++ b/lib/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Entitlements + module Version + VERSION = "0.3.0" + end +end diff --git a/script/release b/script/release deleted file mode 100755 index cdbc892..0000000 --- a/script/release +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# Tag and push a release. - -set -e -set -x - -# Make sure we're in the project root. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" -cd ${DIR} - -# Build a new gem archive. - -rm -rf entitlements-github-plugin-*.gem -gem build -q entitlements-github-plugin.gemspec - -# Make sure we're on the main branch. - -(git branch --no-color | grep -q '* main') || { - echo "Only release from the main branch." - exit 1 -} - -# Figure out what version we're releasing. - -tag=v`ls entitlements-github-plugin-*.gem | sed 's/^entitlements-github-plugin-\(.*\)\.gem$/\1/'` - -# Make sure we haven't released this version before. - -git fetch -t origin - -(git tag -l | grep -q "$tag") && { - echo "Whoops, there's already a '${tag}' tag." - exit 1 -} - -# Tag it and bag it. - -gem push entitlements-github-plugin-*.gem && git tag "$tag" && - git push origin main && git push origin "$tag" diff --git a/spec/acceptance/Dockerfile.entitlements-github-plugin b/spec/acceptance/Dockerfile.entitlements-github-plugin index 00d146a..a1ff0b8 100644 --- a/spec/acceptance/Dockerfile.entitlements-github-plugin +++ b/spec/acceptance/Dockerfile.entitlements-github-plugin @@ -22,7 +22,8 @@ RUN gem install bundler # Bootstrap files and caching for speed COPY "vendor/cache/" "/data/entitlements/vendor/cache/" COPY "script/" "/data/entitlements/script/" -COPY [".rubocop.yml", ".ruby-version", "entitlements-github-plugin.gemspec", "Gemfile", "Gemfile.lock", "VERSION", "/data/entitlements/"] +COPY [".rubocop.yml", ".ruby-version", "entitlements-github-plugin.gemspec", "Gemfile", "Gemfile.lock", "/data/entitlements/"] +COPY "lib/version.rb" "/data/entitlements/lib/version.rb" RUN ./script/bootstrap # Source Files diff --git a/spec/acceptance/docker-compose.yml b/spec/acceptance/docker-compose.yml index 170b09b..c778e7e 100644 --- a/spec/acceptance/docker-compose.yml +++ b/spec/acceptance/docker-compose.yml @@ -28,6 +28,7 @@ services: volumes: - "${DIR}/spec/acceptance:/acceptance:ro" - "${DIR}/spec/acceptance/git-server/keys:/git-server/keys:ro" + ldap-server: entrypoint: /acceptance/ldap-server/run-server.sh image: osixia/openldap:1.2.2 @@ -39,6 +40,7 @@ services: - "127.0.0.1:636:636" volumes: - "${DIR}/spec/acceptance:/acceptance:ro" + github-server: build: context: "${DIR}/spec/acceptance/github-server" @@ -49,7 +51,6 @@ services: - github.fake ports: - "127.0.0.1:443:443" + - "127.0.0.1:80:80" volumes: - "${DIR}/spec/acceptance:/acceptance:ro" - ports: - - "127.0.0.1:80:80" diff --git a/spec/acceptance/tests/spec_helper.rb b/spec/acceptance/tests/spec_helper.rb index 3c665ba..26fd947 100644 --- a/spec/acceptance/tests/spec_helper.rb +++ b/spec/acceptance/tests/spec_helper.rb @@ -64,7 +64,7 @@ def run(fixture_dir, args = []) command_parts = [binary, "--config-file", configfile] + args command = command_parts.map { |i| Shellwords.escape(i) }.join(" ") stdout, stderr, exitstatus = Open3.capture3(command) - OpenStruct.new({ stdout: stdout, stderr: stderr, exitstatus: exitstatus.exitstatus, success?: exitstatus.exitstatus == 0 }) + OpenStruct.new({ stdout:, stderr:, exitstatus: exitstatus.exitstatus, success?: exitstatus.exitstatus == 0 }) end def log(priority, pattern) diff --git a/spec/unit/entitlements/backend/github_org/controller_spec.rb b/spec/unit/entitlements/backend/github_org/controller_spec.rb index 149dc21..0cbb69e 100644 --- a/spec/unit/entitlements/backend/github_org/controller_spec.rb +++ b/spec/unit/entitlements/backend/github_org/controller_spec.rb @@ -588,7 +588,7 @@ let(:answer2) { { "monalisa" => "ADMIN", "ragamuffin" => "ADMIN", "blackmanx" => "MEMBER", "toyger" => "MEMBER" } } it "invalidates the cache and consults the API" do - cache[:predictive_state] = { by_dn: { org1_admin_dn => { members: admins, metadata: nil }, org1_member_dn => { members: members, metadata: nil } }, invalid: Set.new } + cache[:predictive_state] = { by_dn: { org1_admin_dn => { members: admins, metadata: nil }, org1_member_dn => { members:, metadata: nil } }, invalid: Set.new } allow(Entitlements::Data::Groups::Calculated).to receive(:read_all) .with("foo-githuborg", { diff --git a/spec/unit/entitlements/backend/github_team/provider_spec.rb b/spec/unit/entitlements/backend/github_team/provider_spec.rb index 83576c4..e887163 100644 --- a/spec/unit/entitlements/backend/github_team/provider_spec.rb +++ b/spec/unit/entitlements/backend/github_team/provider_spec.rb @@ -19,8 +19,8 @@ let(:russian_blue) { Entitlements::Models::Person.new(uid: "russian_blue") } let(:members) { Set.new(%w[SnowShoe russian_blue]) } let(:dn) { "cn=cats,ou=Github,dc=github,dc=fake" } - let(:group) { Entitlements::Models::Group.new(dn: dn, description: ":smile_cat:", members: Set.new([snowshoe, russian_blue]), metadata: {"application_owner" => "russian_blue"}) } - let(:team) { Entitlements::Backend::GitHubTeam::Models::Team.new(team_id: 1001, team_name: "cats", members: members, ou: "ou=kittensinc,ou=GitHub,dc=github,dc=fake", metadata: {"application_owner" => "russian_blue"}) } + let(:group) { Entitlements::Models::Group.new(dn:, description: ":smile_cat:", members: Set.new([snowshoe, russian_blue]), metadata: {"application_owner" => "russian_blue"}) } + let(:team) { Entitlements::Backend::GitHubTeam::Models::Team.new(team_id: 1001, team_name: "cats", members:, ou: "ou=kittensinc,ou=GitHub,dc=github,dc=fake", metadata: {"application_owner" => "russian_blue"}) } let(:member_strings_set) { Set.new(members.map(&:downcase)) } let(:subject) { described_class.new(config: provider_config) } @@ -189,9 +189,9 @@ end describe "#change_ignored?" do - let(:group1) { Entitlements::Models::Group.new(dn: dn, description: ":smile_cat:", members: Set.new([snowshoe])) } - let(:group2) { Entitlements::Models::Group.new(dn: dn, description: ":smile_cat:", members: Set.new([russian_blue])) } - let(:action) { Entitlements::Models::Action.new(dn, group1, group2, "foo", ignored_users: ignored_users) } + let(:group1) { Entitlements::Models::Group.new(dn:, description: ":smile_cat:", members: Set.new([snowshoe])) } + let(:group2) { Entitlements::Models::Group.new(dn:, description: ":smile_cat:", members: Set.new([russian_blue])) } + let(:action) { Entitlements::Models::Action.new(dn, group1, group2, "foo", ignored_users:) } context "all adds/removes ignored" do let(:ignored_users) { Set.new([snowshoe, russian_blue].map(&:uid)) } @@ -260,7 +260,7 @@ allow(subject).to receive(:github).and_return(github) expect(github).to receive(:read_team).with(entitlement_group).and_return(nil) - expect(github).to receive(:create_team).with({entitlement_group: entitlement_group}).and_return(true) + expect(github).to receive(:create_team).with({entitlement_group:}).and_return(true) expect(github).to receive(:invalidate_predictive_cache).with(entitlement_group).and_return(nil) expect(github).to receive(:read_team).with(entitlement_group).and_return(github_team) expect(github).to receive(:sync_team).with(entitlement_group, github_team).and_return(true) diff --git a/spec/unit/entitlements/backend/github_team/service_spec.rb b/spec/unit/entitlements/backend/github_team/service_spec.rb index 1468997..dda0339 100644 --- a/spec/unit/entitlements/backend/github_team/service_spec.rb +++ b/spec/unit/entitlements/backend/github_team/service_spec.rb @@ -523,7 +523,7 @@ } ) - result = subject.send(:add_user_to_team, user: "blackmanx", team: team) + result = subject.send(:add_user_to_team, user: "blackmanx", team:) expect(result).to eq(true) end @@ -546,7 +546,7 @@ } ) - result = subject.send(:add_user_to_team, user: "blackmanx", team: team) + result = subject.send(:add_user_to_team, user: "blackmanx", team:) expect(result).to eq(true) end @@ -569,14 +569,14 @@ } ) - result = subject.send(:add_user_to_team, user: "blackmanx", team: team) + result = subject.send(:add_user_to_team, user: "blackmanx", team:) expect(result).to eq(false) end it "returns false when the user is ignored" do expect(subject).to receive(:org_members).and_return(Set.new(%w[ragamuffin])) - result = subject.send(:add_user_to_team, user: "blackmanx", team: team) + result = subject.send(:add_user_to_team, user: "blackmanx", team:) expect(result).to eq(false) end end @@ -598,14 +598,14 @@ expect(subject).to receive(:validate_team_id_and_slug!).with(1001, "russian-blues").and_return(true) expect(subject).to receive(:org_members).and_return(Set.new(%w[blackmanx])) - result = subject.send(:remove_user_from_team, user: "blackmanx", team: team) + result = subject.send(:remove_user_from_team, user: "blackmanx", team:) expect(result).to eq(true) end it "returns false when the user is ignored" do expect(subject).to receive(:org_members).and_return(Set.new(%w[ragamuffin])) - result = subject.send(:remove_user_from_team, user: "blackmanx", team: team) + result = subject.send(:remove_user_from_team, user: "blackmanx", team:) expect(result).to eq(false) end end diff --git a/spec/unit/entitlements/service/github_spec.rb b/spec/unit/entitlements/service/github_spec.rb index 68c91ce..ecf5ebe 100644 --- a/spec/unit/entitlements/service/github_spec.rb +++ b/spec/unit/entitlements/service/github_spec.rb @@ -99,7 +99,7 @@ context "when sourced from the cache" do it "returns true" do - cache[:predictive_state] = { by_dn: { admin_dn => { members: admins, metadata: nil }, member_dn => { members: members, metadata: nil } }, invalid: Set.new } + cache[:predictive_state] = { by_dn: { admin_dn => { members: admins, metadata: nil }, member_dn => { members:, metadata: nil } }, invalid: Set.new } expect(subject).not_to receive(:members_and_roles_from_rest) @@ -116,7 +116,7 @@ let(:answer) { { "monalisa" => "ADMIN", "ocicat" => "MEMBER", "blackmanx" => "MEMBER", "toyger" => "MEMBER" } } it "invaliates the cache" do - cache[:predictive_state] = { by_dn: { admin_dn => { members: admins, metadata: nil }, member_dn => { members: members, metadata: nil } }, invalid: Set.new } + cache[:predictive_state] = { by_dn: { admin_dn => { members: admins, metadata: nil }, member_dn => { members:, metadata: nil } }, invalid: Set.new } # First load should read from the cache. expect(subject.org_members).to eq(answer.map { |k, v| [k, v.downcase] }.to_h) @@ -214,8 +214,8 @@ it "returns the expected hash" do expect(subject).to receive(:octokit).and_return(octokit).twice - expect(octokit).to receive(:organization_members).with("kittensinc", { role: "admin" }).and_return(admins.map { |login| { login: login } }) - expect(octokit).to receive(:organization_members).with("kittensinc", { role: "member" }).and_return(members.map { |login| { login: login } }) + expect(octokit).to receive(:organization_members).with("kittensinc", { role: "admin" }).and_return(admins.map { |login| { login: } }) + expect(octokit).to receive(:organization_members).with("kittensinc", { role: "member" }).and_return(members.map { |login| { login: } }) result = subject.send(:members_and_roles_from_rest) expect(result).to eq({"ocicat"=>"MEMBER", "blackmanx"=>"MEMBER", "toyger"=>"MEMBER", "highlander"=>"MEMBER", "russianblue"=>"MEMBER", "ragamuffin"=>"MEMBER", "monalisa"=>"ADMIN", "peterbald"=>"MEMBER", "mainecoon"=>"MEMBER", "laperm"=>"MEMBER"}) diff --git a/spec/unit/entitlements_spec.rb b/spec/unit/entitlements_spec.rb index c6a8ec1..4ce4b69 100644 --- a/spec/unit/entitlements_spec.rb +++ b/spec/unit/entitlements_spec.rb @@ -260,7 +260,7 @@ expect(logger).to receive(:debug).with("Audit Auditor 1 completed successfully") expect(logger).to receive(:debug).with("Audit Auditor 2 completed successfully") - expect { described_class.execute(actions: actions) }.not_to raise_error + expect { described_class.execute(actions:) }.not_to raise_error end it "returns without error with no auditors configured" do @@ -279,7 +279,7 @@ expect(logger).not_to receive(:debug) - expect { described_class.execute(actions: actions) }.not_to raise_error + expect { described_class.execute(actions:) }.not_to raise_error end it "raises when setup of an auditor fails" do @@ -293,7 +293,7 @@ expect(auditor2).not_to receive(:setup) expect(auditor2).not_to receive(:commit) - expect { described_class.execute(actions: actions) }.to raise_error(exc) + expect { described_class.execute(actions:) }.to raise_error(exc) end it "raises (but runs other auditors) when an auditor fails" do @@ -333,7 +333,7 @@ allow(logger).to receive(:error) expect(logger).to receive(:error).with("Audit Auditor 1 failed: RuntimeError Boom") - expect { described_class.execute(actions: actions) }.to raise_error(exc) + expect { described_class.execute(actions:) }.to raise_error(exc) end it "raises when a provider fails and there are no auditors" do @@ -353,7 +353,7 @@ expect(logger).not_to receive(:debug) - expect { described_class.execute(actions: actions) }.to raise_error(exc) + expect { described_class.execute(actions:) }.to raise_error(exc) end it "raises (but runs the auditors) when a provider fails" do @@ -392,7 +392,7 @@ expect(logger).to receive(:debug).with("Audit Auditor 1 completed successfully") expect(logger).to receive(:debug).with("Audit Auditor 2 completed successfully") - expect { described_class.execute(actions: actions) }.to raise_error(exc) + expect { described_class.execute(actions:) }.to raise_error(exc) end it "raises the provider's exception when a provider and auditor both fail" do @@ -432,7 +432,7 @@ expect(logger).to receive(:debug).with("Audit Auditor 2 completed successfully") allow(logger).to receive(:error) # Stack trace - expect { described_class.execute(actions: actions) }.to raise_error(exc) + expect { described_class.execute(actions:) }.to raise_error(exc) end it "raises and logs a message when multiple auditors fail" do @@ -473,7 +473,7 @@ expect(logger).to receive(:error).with("Audit Auditor 2 failed: RuntimeError Boom Boom") allow(logger).to receive(:error) # Stack trace - expect { described_class.execute(actions: actions) }.to raise_error(exc) + expect { described_class.execute(actions:) }.to raise_error(exc) end end