From 8eaca78580b0664386895a33b6ee62e84c464edb Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 1 Jun 2021 11:36:11 -0700 Subject: [PATCH] Add support for Remote Mirrors API --- lib/gitlab/client.rb | 1 + lib/gitlab/client/remote_mirrors.rb | 51 +++++++++++++++++ spec/fixtures/remote_mirror_create.json | 12 ++++ spec/fixtures/remote_mirror_edit.json | 12 ++++ spec/fixtures/remote_mirrors.json | 14 +++++ spec/gitlab/client/remote_mirrors_spec.rb | 70 +++++++++++++++++++++++ 6 files changed, 160 insertions(+) create mode 100644 lib/gitlab/client/remote_mirrors.rb create mode 100644 spec/fixtures/remote_mirror_create.json create mode 100644 spec/fixtures/remote_mirror_edit.json create mode 100644 spec/fixtures/remote_mirrors.json create mode 100644 spec/gitlab/client/remote_mirrors_spec.rb diff --git a/lib/gitlab/client.rb b/lib/gitlab/client.rb index a4848a503..1980bbcbd 100644 --- a/lib/gitlab/client.rb +++ b/lib/gitlab/client.rb @@ -49,6 +49,7 @@ class Client < API include ProjectReleases include Projects include ProtectedTags + include RemoteMirrors include Repositories include RepositoryFiles include RepositorySubmodules diff --git a/lib/gitlab/client/remote_mirrors.rb b/lib/gitlab/client/remote_mirrors.rb new file mode 100644 index 000000000..fb75a2006 --- /dev/null +++ b/lib/gitlab/client/remote_mirrors.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +class Gitlab::Client + # Defines methods related to remote mirrors. + # @see https://docs.gitlab.com/ee/api/remote_mirrors.html + module RemoteMirrors + # List a project's remote mirrors + # + # @example + # Gitlab.remote_mirrors(42) + # Gitlab.remote_mirrors('gitlab-org/gitlab') + # + # @param [Integer, String] project The ID or name of a project. + # @return [Array] + def remote_mirrors(project) + get("/projects/#{url_encode project}/remote_mirrors") + end + + # Create a remote mirror + # + # @example + # Gitlab.create_remote_mirror(42, 'https://mirror-bot@gitlab.com/gitlab-org/gitlab.git', enabled: true) + # + # @param [Integer, String] project The ID or name of a project. + # @param [String] url The full URL of the remote repository. + # @param [Hash] options A customizable set of options. + # @option options [Boolean] :enabled Determines if the mirror is enabled. + # @option options [Boolean] :only_protected_branches Determines if only protected branches are mirrored. + # @option options [Boolean] :keep_divergent_refs Determines if divergent refs are skipped. + # @return [Gitlab::ObjectifiedHash] + def create_remote_mirror(project, url, options = {}) + post("/projects/#{url_encode project}/remote_mirrors", body: options.merge(url: url)) + end + + # Update a remote mirror's attributes + # + # @example + # Gitlab.edit_remote_mirror(42, 66, only_protected_branches: true) + # + # @param [Integer, String] project The ID or name of a project. + # @param [Integer] id The ID of the remote mirror. + # @param [Hash] options A customizable set of options. + # @option options [Boolean] :enabled Determines if the mirror is enabled. + # @option options [Boolean] :only_protected_branches Determines if only protected branches are mirrored. + # @option options [Boolean] :keep_divergent_refs Determines if divergent refs are skipped. + # @return [Gitlab::ObjectifiedHash] + def edit_remote_mirror(project, id, options = {}) + put("/projects/#{url_encode project}/remote_mirrors/#{id}", body: options) + end + end +end diff --git a/spec/fixtures/remote_mirror_create.json b/spec/fixtures/remote_mirror_create.json new file mode 100644 index 000000000..7b96785f5 --- /dev/null +++ b/spec/fixtures/remote_mirror_create.json @@ -0,0 +1,12 @@ +{ + "enabled": false, + "id": 123456, + "last_error": null, + "last_successful_update_at": null, + "last_update_at": null, + "last_update_started_at": null, + "only_protected_branches": false, + "keep_divergent_refs": false, + "update_status": "none", + "url": "https://*****:*****@example.com/gitlab/example.git" +} diff --git a/spec/fixtures/remote_mirror_edit.json b/spec/fixtures/remote_mirror_edit.json new file mode 100644 index 000000000..6fd6272c4 --- /dev/null +++ b/spec/fixtures/remote_mirror_edit.json @@ -0,0 +1,12 @@ +{ + "enabled": false, + "id": 123456, + "last_error": null, + "last_successful_update_at": "2020-01-06T17:32:02.823Z", + "last_update_at": "2020-01-06T17:32:02.823Z", + "last_update_started_at": "2020-01-06T17:31:55.864Z", + "only_protected_branches": true, + "keep_divergent_refs": true, + "update_status": "finished", + "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git" +} diff --git a/spec/fixtures/remote_mirrors.json b/spec/fixtures/remote_mirrors.json new file mode 100644 index 000000000..60d00568a --- /dev/null +++ b/spec/fixtures/remote_mirrors.json @@ -0,0 +1,14 @@ +[ + { + "enabled": true, + "id": 123456, + "keep_divergent_refs": true, + "last_error": "Some refs have diverged and have not been updated on the remote:\n\nrefs/heads/master", + "last_successful_update_at": "2020-08-11T15:36:04.668Z", + "last_update_at": "2020-08-11T15:37:20.701Z", + "last_update_started_at": "2020-08-11T15:37:17.659Z", + "only_protected_branches": true, + "update_status": "failed", + "url": "https://*****:*****@gitlab.com/mirror/target.git" + } +] diff --git a/spec/gitlab/client/remote_mirrors_spec.rb b/spec/gitlab/client/remote_mirrors_spec.rb new file mode 100644 index 000000000..b4273c9e5 --- /dev/null +++ b/spec/gitlab/client/remote_mirrors_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Client do + describe '.remote_mirrors' do + before do + stub_get('/projects/5/remote_mirrors', 'remote_mirrors') + @mirrors = Gitlab.remote_mirrors(5) + end + + it 'gets the correct resource' do + expect(a_get('/projects/5/remote_mirrors')).to have_been_made + end + + it "returns a paginated response of project's push mirrors" do + expect(@mirrors).to be_an Gitlab::PaginatedResponse + expect(@mirrors.first).to be_a Gitlab::ObjectifiedHash + expect(@mirrors.first.enabled).to eq(true) + end + end + + describe '.create_remote_mirror' do + let(:api_path) { '/projects/5/remote_mirrors' } + let(:mirror_path) { 'https://username:token@example.com/gitlab/example.git' } + + before do + stub_post(api_path, 'remote_mirror_create') + @mirror = Gitlab.create_remote_mirror(5, mirror_path, enabled: false) + end + + it 'posts to the correct resource' do + expect(a_post(api_path).with(body: { url: mirror_path, enabled: false })) + .to have_been_made + end + + it 'returns a single remote mirror' do + expect(@mirror).to be_a Gitlab::ObjectifiedHash + expect(@mirror.enabled).to eq(false) + expect(@mirror.id).to eq(123_456) + expect(@mirror.url).to include('example.com/gitlab/example.git') + end + end + + describe '.edit_remote_mirror' do + let(:api_path) { '/projects/5/remote_mirrors/123456' } + + before do + stub_put(api_path, 'remote_mirror_edit') + @mirror = Gitlab.edit_remote_mirror( + 5, + 123_456, + only_protected_branches: true, + keep_divergent_refs: true + ) + end + + it 'puts to the correct resource' do + expect(a_put(api_path).with(body: { only_protected_branches: true, keep_divergent_refs: true })) + .to have_been_made + end + + it 'returns a single remote mirror' do + expect(@mirror).to be_a Gitlab::ObjectifiedHash + expect(@mirror.enabled).to eq(false) + expect(@mirror.only_protected_branches).to eq(true) + expect(@mirror.keep_divergent_refs).to eq(true) + end + end +end