Skip to content

Commit

Permalink
don't make a rest call for repo exists check, instead inspect the err… (
Browse files Browse the repository at this point in the history
  • Loading branch information
dylan-smith authored Aug 17, 2022
1 parent c897700 commit 31fc7fe
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 146 deletions.
1 change: 1 addition & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Added `create-team` command to `gh gei`.
- Reduced # of REST API calls used to avoid rate limiting challenges
- Changed how we do the version check to avoid warnings about being rate limited
- Checks for an environment variable GEI_DEBUG_MODE and if set to 'true' will emit additional data in the verbose log file
15 changes: 0 additions & 15 deletions src/Octoshift/GithubApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,6 @@ public virtual async Task<IEnumerable<string>> GetRepos(string org)
return await _client.GetAllAsync(url).Select(x => (string)x["name"]).ToListAsync();
}

public virtual async Task<bool> RepoExists(string org, string repo)
{
var url = $"{_apiUrl}/repos/{org}/{repo}";

try
{
await _client.GetAsync(url);
return true;
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.NotFound or HttpStatusCode.Moved)
{
return false;
}
}

public virtual async Task RemoveTeamMember(string org, string teamSlug, string member)
{
var url = $"{_apiUrl}/orgs/{org}/teams/{teamSlug}/memberships/{member}";
Expand Down
83 changes: 0 additions & 83 deletions src/OctoshiftCLI.Tests/GithubApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1615,89 +1615,6 @@ ... on User {
result.Should().BeEquivalentTo(expectedReclaimMannequinResponse);
}

[Fact]
public async Task RepoExists_Should_Return_True_If_Repo_Exists()
{
// Arrange
const string url = $"https://api.github.com/repos/{GITHUB_ORG}/{GITHUB_REPO}";

_githubClientMock.Setup(m => m.GetAsync(url)).ReturnsAsync("{ \"id\": 12345 }");

// Act
var result = await _githubApi.RepoExists(GITHUB_ORG, GITHUB_REPO);

// Assert
result.Should().BeTrue();
}

[Fact]
public async Task RepoExists_Should_Return_False_If_Repo_Does_Not_Exist_404()
{
// Arrange
const string url = $"https://api.github.com/repos/{GITHUB_ORG}/{GITHUB_REPO}";

_githubClientMock
.Setup(m => m.GetAsync(url))
.Throws(new HttpRequestException(null, null, HttpStatusCode.NotFound));

// Act
var result = await _githubApi.RepoExists(GITHUB_ORG, GITHUB_REPO);

// Assert
result.Should().BeFalse();
}

[Fact]
public async Task RepoExists_Should_Return_False_If_Repo_Does_Not_Exist_301()
{
// Arrange
const string url = $"https://api.github.com/repos/{GITHUB_ORG}/{GITHUB_REPO}";

_githubClientMock
.Setup(m => m.GetAsync(url))
.Throws(new HttpRequestException(null, null, HttpStatusCode.Moved));

// Act
var result = await _githubApi.RepoExists(GITHUB_ORG, GITHUB_REPO);

// Assert
result.Should().BeFalse();
}

[Fact]
public async Task RepoExists_Throws_When_Underlying_HttpResponseException_Status_Is_Not_NotFound_Or_Moved()
{
// Arrange
const string url = $"https://api.github.com/repos/{GITHUB_ORG}/{GITHUB_REPO}";

_githubClientMock
.Setup(m => m.GetAsync(url))
.Throws(new HttpRequestException(null, null, HttpStatusCode.MultipleChoices));

// Act, Assert
await _githubApi
.Invoking(async client => await client.RepoExists(GITHUB_ORG, GITHUB_REPO))
.Should()
.ThrowAsync<HttpRequestException>();
}

[Fact]
public async Task RepoExists_Does_Not_Swallow_Exceptions()
{
// Arrange
const string url = $"https://api.github.com/repos/{GITHUB_ORG}/{GITHUB_REPO}";

_githubClientMock
.Setup(m => m.GetAsync(url))
.Throws(new InvalidOperationException());

// Act, Assert
await _githubApi
.Invoking(async client => await client.RepoExists(GITHUB_ORG, GITHUB_REPO))
.Should()
.ThrowAsync<InvalidOperationException>();
}

[Fact]
public async Task StartMetadataArchiveGeneration_Returns_The_Initiated_Migration_Id()
{
Expand Down
24 changes: 16 additions & 8 deletions src/OctoshiftCLI.Tests/ado2gh/Commands/MigrateRepoCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public void Should_Have_Options()
public async Task Happy_Path()
{
// Arrange
_mockGithubApi.Setup(x => x.RepoExists(GITHUB_ORG, GITHUB_REPO).Result).Returns(false);
_mockGithubApi.Setup(x => x.GetOrganizationId(GITHUB_ORG).Result).Returns(GITHUB_ORG_ID);
_mockGithubApi.Setup(x => x.CreateAdoMigrationSource(GITHUB_ORG_ID, null).Result).Returns(MIGRATION_SOURCE_ID);
_mockGithubApi
Expand Down Expand Up @@ -102,7 +101,6 @@ public async Task Happy_Path()
await _command.Invoke(ADO_ORG, ADO_TEAM_PROJECT, ADO_REPO, GITHUB_ORG, GITHUB_REPO, wait: false);

// Assert
_mockGithubApi.Verify(m => m.RepoExists(GITHUB_ORG, GITHUB_REPO));
_mockGithubApi.Verify(m => m.GetOrganizationId(GITHUB_ORG));
_mockGithubApi.Verify(m => m.CreateAdoMigrationSource(GITHUB_ORG_ID, null));
_mockGithubApi.Verify(m => m.StartMigration(MIGRATION_SOURCE_ID, ADO_REPO_URL, GITHUB_ORG_ID, GITHUB_REPO, ADO_TOKEN, GITHUB_TOKEN, null, null, false));
Expand All @@ -115,10 +113,24 @@ public async Task Happy_Path()
}

[Fact]
public async Task Idempotency_Stop_If_Target_Exists()
public async Task Skip_Migration_If_Target_Repo_Exists()
{
// Arrange
_mockGithubApi.Setup(x => x.RepoExists(GITHUB_ORG, GITHUB_REPO).Result).Returns(true);
_mockGithubApi.Setup(x => x.GetOrganizationId(GITHUB_ORG).Result).Returns(GITHUB_ORG_ID);
_mockGithubApi.Setup(x => x.CreateAdoMigrationSource(GITHUB_ORG_ID, null).Result).Returns(MIGRATION_SOURCE_ID);
_mockGithubApi
.Setup(x => x.StartMigration(
MIGRATION_SOURCE_ID,
ADO_REPO_URL,
GITHUB_ORG_ID,
GITHUB_REPO,
ADO_TOKEN,
GITHUB_TOKEN,
null,
null,
false).Result)
.Throws(new OctoshiftCliException($"A repository called {GITHUB_ORG}/{GITHUB_REPO} already exists"));

_mockGithubApiFactory.Setup(m => m.Create(It.IsAny<string>(), It.IsAny<string>())).Returns(_mockGithubApi.Object);

_mockEnvironmentVariableProvider
Expand All @@ -138,12 +150,8 @@ public async Task Idempotency_Stop_If_Target_Exists()
await _command.Invoke(ADO_ORG, ADO_TEAM_PROJECT, ADO_REPO, GITHUB_ORG, GITHUB_REPO, wait: false);

// Assert
_mockGithubApi.Verify(m => m.RepoExists(GITHUB_ORG, GITHUB_REPO));

_mockOctoLogger.Verify(m => m.LogWarning(It.IsAny<string>()), Times.Exactly(1));
actualLogOutput.Should().Contain(expectedLogOutput);

_mockGithubApi.VerifyNoOtherCalls();
}

[Fact]
Expand Down
20 changes: 8 additions & 12 deletions src/OctoshiftCLI.Tests/gei/Commands/MigrateRepoCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ public async Task Happy_Path_Without_Wait()
var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}";
var migrationId = Guid.NewGuid().ToString();

_mockGithubApi.Setup(x => x.RepoExists(TARGET_ORG, TARGET_REPO).Result).Returns(false);
_mockGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId);
_mockGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId);
_mockGithubApi.Setup(x => x.StartMigration(migrationSourceId, githubRepoUrl, githubOrgId, TARGET_REPO, sourceGithubPat, targetGithubPat, null, null, false).Result).Returns(migrationId);
Expand Down Expand Up @@ -120,7 +119,6 @@ public async Task Happy_Path_Without_Wait()
await _command.Invoke(args);

// Assert
_mockGithubApi.Verify(m => m.RepoExists(TARGET_ORG, TARGET_REPO));
_mockGithubApi.Verify(m => m.GetOrganizationId(TARGET_ORG));
_mockGithubApi.Verify(m => m.CreateGhecMigrationSource(githubOrgId));
_mockGithubApi.Verify(m => m.StartMigration(migrationSourceId, githubRepoUrl, githubOrgId, TARGET_REPO, sourceGithubPat, targetGithubPat, null, null, false));
Expand All @@ -133,18 +131,20 @@ public async Task Happy_Path_Without_Wait()
}

[Fact]
public async Task Idempotency_Stop_If_Target_Exists()
public async Task Skip_Migration_If_Target_Repo_Exists()
{
// Arrange
var githubOrgId = Guid.NewGuid().ToString();
var migrationSourceId = Guid.NewGuid().ToString();
var sourceGithubPat = Guid.NewGuid().ToString();
var targetGithubPat = Guid.NewGuid().ToString();
var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}";
var migrationId = Guid.NewGuid().ToString();

_mockGithubApi.Setup(x => x.RepoExists(TARGET_ORG, TARGET_REPO).Result).Returns(true);
_mockGithubApi.Setup(x => x.StartMigration(migrationSourceId, githubRepoUrl, githubOrgId, TARGET_REPO, sourceGithubPat, targetGithubPat, "", "", false).Result).Returns(migrationId);
_mockGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId);
_mockGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId);
_mockGithubApi
.Setup(x => x.StartMigration(migrationSourceId, githubRepoUrl, githubOrgId, TARGET_REPO, sourceGithubPat, targetGithubPat, null, null, false).Result)
.Throws(new OctoshiftCliException($"A repository called {TARGET_ORG}/{TARGET_REPO} already exists"));

_mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken()).Returns(sourceGithubPat);
_mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken()).Returns(targetGithubPat);
Expand All @@ -155,7 +155,7 @@ public async Task Idempotency_Stop_If_Target_Exists()
_mockOctoLogger.Setup(m => m.LogInformation(It.IsAny<string>())).Callback<string>(s => actualLogOutput.Add(s));
_mockOctoLogger.Setup(m => m.LogWarning(It.IsAny<string>())).Callback<string>(s => actualLogOutput.Add(s));

var expectedLogWarningOutput = $"The Org '{TARGET_ORG}' already contains a repository with the name '{TARGET_REPO}'. No operation will be performed";
var expectedLogOutput = $"The Org '{TARGET_ORG}' already contains a repository with the name '{TARGET_REPO}'. No operation will be performed";

// Act
var args = new MigrateRepoCommandArgs
Expand All @@ -170,12 +170,8 @@ public async Task Idempotency_Stop_If_Target_Exists()
await _command.Invoke(args);

// Assert
_mockGithubApi.Verify(m => m.RepoExists(TARGET_ORG, TARGET_REPO));

_mockOctoLogger.Verify(m => m.LogWarning(It.IsAny<string>()), Times.Exactly(1));
actualLogOutput.Should().Contain(expectedLogWarningOutput);

_mockGithubApi.VerifyNoOtherCalls();
actualLogOutput.Should().Contain(expectedLogOutput);
}

[Fact]
Expand Down
23 changes: 17 additions & 6 deletions src/ado2gh/Commands/MigrateRepoCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,29 @@ public async Task Invoke(string adoOrg, string adoTeamProject, string adoRepo, s

githubPat ??= _environmentVariableProvider.GithubPersonalAccessToken();
var githubApi = _githubApiFactory.Create(targetPersonalAccessToken: githubPat);
if (await githubApi.RepoExists(githubOrg, githubRepo))
{
_log.LogWarning($"The Org '{githubOrg}' already contains a repository with the name '{githubRepo}'. No operation will be performed");
return;
}

var adoRepoUrl = GetAdoRepoUrl(adoOrg, adoTeamProject, adoRepo);

adoPat ??= _environmentVariableProvider.AdoPersonalAccessToken();
var githubOrgId = await githubApi.GetOrganizationId(githubOrg);
var migrationSourceId = await githubApi.CreateAdoMigrationSource(githubOrgId, null);
var migrationId = await githubApi.StartMigration(migrationSourceId, adoRepoUrl, githubOrgId, githubRepo, adoPat, githubPat);

string migrationId;

try
{
migrationId = await githubApi.StartMigration(migrationSourceId, adoRepoUrl, githubOrgId, githubRepo, adoPat, githubPat);
}
catch (OctoshiftCliException ex)
{
if (ex.Message == $"A repository called {githubOrg}/{githubRepo} already exists")
{
_log.LogWarning($"The Org '{githubOrg}' already contains a repository with the name '{githubRepo}'. No operation will be performed");
return;
}

throw;
}

if (!wait)
{
Expand Down
23 changes: 17 additions & 6 deletions src/bbs2gh/Commands/MigrateRepoCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,29 @@ public async Task Invoke(string adoOrg, string adoTeamProject, string adoRepo, s

githubPat ??= _environmentVariableProvider.GithubPersonalAccessToken();
var githubApi = _githubApiFactory.Create(targetPersonalAccessToken: githubPat);
if (await githubApi.RepoExists(githubOrg, githubRepo))
{
_log.LogWarning($"The Org '{githubOrg}' already contains a repository with the name '{githubRepo}'. No operation will be performed");
return;
}

var adoRepoUrl = GetAdoRepoUrl(adoOrg, adoTeamProject, adoRepo);

adoPat ??= _environmentVariableProvider.AdoPersonalAccessToken();
var githubOrgId = await githubApi.GetOrganizationId(githubOrg);
var migrationSourceId = await githubApi.CreateAdoMigrationSource(githubOrgId, null);
var migrationId = await githubApi.StartMigration(migrationSourceId, adoRepoUrl, githubOrgId, githubRepo, adoPat, githubPat);

string migrationId;

try
{
migrationId = await githubApi.StartMigration(migrationSourceId, adoRepoUrl, githubOrgId, githubRepo, adoPat, githubPat);
}
catch (OctoshiftCliException ex)
{
if (ex.Message == $"A repository called {githubOrg}/{githubRepo} already exists")
{
_log.LogWarning($"The Org '{githubOrg}' already contains a repository with the name '{githubRepo}'. No operation will be performed");
return;
}

throw;
}

if (!wait)
{
Expand Down
41 changes: 25 additions & 16 deletions src/gei/Commands/MigrateRepoCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,6 @@ public async Task Invoke(MigrateRepoCommandArgs args)

var githubApi = _targetGithubApiFactory.Create(args.TargetApiUrl, args.GithubTargetPat);

if (await githubApi.RepoExists(args.GithubTargetOrg, args.TargetRepo))
{
_log.LogWarning($"The Org '{args.GithubTargetOrg}' already contains a repository with the name '{args.TargetRepo}'. No operation will be performed");
return;
}

var githubOrgId = await githubApi.GetOrganizationId(args.GithubTargetOrg);
var sourceRepoUrl = GetSourceRepoUrl(args);
var sourceToken = GetSourceToken(args);
Expand All @@ -204,16 +198,31 @@ public async Task Invoke(MigrateRepoCommandArgs args)
? await githubApi.CreateGhecMigrationSource(githubOrgId)
: await githubApi.CreateAdoMigrationSource(githubOrgId, args.AdoServerUrl);

var migrationId = await githubApi.StartMigration(
migrationSourceId,
sourceRepoUrl,
githubOrgId,
args.TargetRepo,
sourceToken,
targetToken,
args.GitArchiveUrl,
args.MetadataArchiveUrl,
args.SkipReleases);
string migrationId;

try
{
migrationId = await githubApi.StartMigration(
migrationSourceId,
sourceRepoUrl,
githubOrgId,
args.TargetRepo,
sourceToken,
targetToken,
args.GitArchiveUrl,
args.MetadataArchiveUrl,
args.SkipReleases);
}
catch (OctoshiftCliException ex)
{
if (ex.Message == $"A repository called {args.GithubTargetOrg}/{args.TargetRepo} already exists")
{
_log.LogWarning($"The Org '{args.GithubTargetOrg}' already contains a repository with the name '{args.TargetRepo}'. No operation will be performed");
return;
}

throw;
}

if (!args.Wait)
{
Expand Down

0 comments on commit 31fc7fe

Please sign in to comment.