From 0ef8931302c3560f64c7b78c03036ad395493fe3 Mon Sep 17 00:00:00 2001 From: nobe4 Date: Wed, 28 Oct 2026 21:50:40 +0100 Subject: [PATCH 1/7] feat(service): catch 403 when someone blocks the invitation This happened just now, and should only warn, but not fail. --- .../backend/github_org/service.rb | 7 ++++-- lib/version.rb | 2 +- .../backend/github_org/service_spec.rb | 22 +++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/entitlements/backend/github_org/service.rb b/lib/entitlements/backend/github_org/service.rb index 17062e0..7ba89ec 100644 --- a/lib/entitlements/backend/github_org/service.rb +++ b/lib/entitlements/backend/github_org/service.rb @@ -46,7 +46,7 @@ def add_user_to_organization(user, role) Entitlements.logger.debug "#{identifier} add_user_to_organization(user=#{user}, org=#{org}, role=#{role})" begin - new_membership = Retryable.with_context(:default, not: [Octokit::NotFound]) do + new_membership = Retryable.with_context(:default, not: [Octokit::NotFound, Octokit::Forbidden]) do octokit.update_organization_membership(org, user:, role:) end rescue Octokit::NotFound => e @@ -54,9 +54,12 @@ def add_user_to_organization(user, role) Entitlements.logger.warn "User #{user} not found in GitHub instance #{identifier}, ignoring." return false - rescue Octokit::UnprocessableEntity => e + rescue Octokit::UnprocessableEntity => e # code 422 Entitlements.logger.warn "Unprocessable entity when adding #{user} to organization #{org} with role #{role}: #{e.message}. This likely means the user blocked the invite, so we're ignoring them, but someone should check it." return false + rescue Octokit::Forbidden => e # code 403 + Entitlements.logger.warn "Forbidden from adding #{user} to organization #{org} with role #{role}: #{e.message}." + return false end # Happy path diff --git a/lib/version.rb b/lib/version.rb index 7f933cc..9bc799e 100644 --- a/lib/version.rb +++ b/lib/version.rb @@ -2,6 +2,6 @@ module Entitlements module Version - VERSION = "1.2.6" + VERSION = "1.2.7" end end diff --git a/spec/unit/entitlements/backend/github_org/service_spec.rb b/spec/unit/entitlements/backend/github_org/service_spec.rb index 05c8a99..5d4824a 100644 --- a/spec/unit/entitlements/backend/github_org/service_spec.rb +++ b/spec/unit/entitlements/backend/github_org/service_spec.rb @@ -223,6 +223,28 @@ expect(result).to eq(false) end end + + context "when the API returns a forbidden error" do + it "warns and returns false" do + expect(logger).to receive(:debug).with("github.fake add_user_to_organization(user=bob, org=kittensinc, role=admin)") + expect(logger).to receive(:debug).with("Setting up GitHub API connection to https://github.fake/api/v3/") + expect(logger).to receive(:warn).with(/Forbidden from adding bob to organization kittensinc with role admin/) + + stub_request(:put, "https://github.fake/api/v3/orgs/kittensinc/memberships/bob").to_return( + status: 403, + headers: { + "Content-type" => "application/json" + }, + body: JSON.generate({ + "message" => "Forbidden", + "documentation_url" => "https://docs.github.com/rest" + }) + ) + + result = subject.send(:add_user_to_organization, "bob", "admin") + expect(result).to eq(false) + end + end end end From b18e329564989e84ee58b023d142db313d3b6905 Mon Sep 17 00:00:00 2001 From: nobe4 Date: Wed, 28 Oct 2026 21:55:10 +0100 Subject: [PATCH 2/7] fix: bump version --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e5e595e..e44c0a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - entitlements-github-plugin (1.2.6) + entitlements-github-plugin (1.2.7) contracts (~> 0.17.0) faraday (~> 2.0) faraday-net_http_persistent (~> 2.3) @@ -186,4 +186,4 @@ DEPENDENCIES webmock (~> 3.23, >= 3.23.1) BUNDLED WITH - 2.5.9 + 2.7.2 From aadea5bac7d104be9685f1554f1a367f5ea83f95 Mon Sep 17 00:00:00 2001 From: nobe4 Date: Thu, 29 Oct 2026 10:17:00 +0100 Subject: [PATCH 3/7] fix: bump ruby to 3.4.0 --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 9c25013..1809198 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.6 +3.4.0 From c5c7c9a3f0668a5e3cddc05edbced9bd8c7ea4bc Mon Sep 17 00:00:00 2001 From: nobe4 Date: Thu, 29 Oct 2026 10:17:34 +0100 Subject: [PATCH 4/7] fix: bump ruby to 3.4.9 to match the main repo --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 1809198..7bcbb38 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.4.0 +3.4.9 From cb50e9040e9d504487e25783d40e3e747b82d121 Mon Sep 17 00:00:00 2001 From: nobe4 Date: Thu, 29 Oct 2026 10:20:55 +0100 Subject: [PATCH 5/7] fix(test): update matrix with only valid ruby versions --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b0e653..e5afa80 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - ruby: [ '3.1.2', '3.1.4', '3.2.2', '3.2.3', '3.3.0', '3.3.1' ] + ruby: ["3.3.0", "3.3.1", "3.4.9"] steps: - name: checkout From 59f1fa2723b1157b14fb5632f756e8095d5cc41b Mon Sep 17 00:00:00 2001 From: Stephen Hosom Date: Tue, 3 Nov 2026 14:34:33 -0500 Subject: [PATCH 6/7] fix(ci): pin Linux runners to Ubuntu 24.04 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 54046087-4229-4709-8593-e419853fd0d1 --- .github/workflows/build.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2880523..a0000e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-24.04, macos-latest] runs-on: ${{ matrix.os }} steps: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 516de00..b1cd599 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ permissions: jobs: lint: name: lint - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: checkout diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e5afa80..4ea8fbb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ permissions: jobs: test: name: test - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 strategy: matrix: From d13f9a431e9ddc194a9e16f88f0de0339c0600e6 Mon Sep 17 00:00:00 2001 From: Stephen Hosom Date: Tue, 3 Nov 2026 14:53:41 -0500 Subject: [PATCH 7/7] fix(ci): preserve required Linux build check name Keep the Ubuntu 24.04 runner while reporting the build (ubuntu-latest) check required by branch protection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 674f9dc1-7d96-43ea-b4c1-cd96c8792f52 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0000e9..ee6481d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ permissions: jobs: build: - name: build + name: build (${{ matrix.os == 'ubuntu-24.04' && 'ubuntu-latest' || matrix.os }}) strategy: matrix: