From 65751488a8389dd39988dd31ab9622b55c866262 Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Thu, 4 Apr 2024 09:25:16 +0200 Subject: [PATCH] [SCM-1022] jgit push failure is not failing the build This closes #203 --- .../checkin/GitCheckInCommandTckTest.java | 65 +++++++++++++++++++ .../command/checkin/JGitCheckInCommand.java | 22 ++++++- 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/checkin/GitCheckInCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/checkin/GitCheckInCommandTckTest.java index ce6e5938e..53e612a15 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/checkin/GitCheckInCommandTckTest.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/checkin/GitCheckInCommandTckTest.java @@ -19,11 +19,19 @@ package org.apache.maven.scm.provider.git.command.checkin; import java.io.File; +import java.io.IOException; +import org.apache.maven.scm.PlexusJUnit4TestSupport; +import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.command.checkin.CheckInScmResult; import org.apache.maven.scm.command.checkout.CheckOutScmResult; import org.apache.maven.scm.provider.git.GitScmTestUtils; import org.apache.maven.scm.repository.ScmRepository; import org.apache.maven.scm.tck.command.checkin.CheckInCommandTckTest; +import org.codehaus.plexus.util.FileUtils; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; /** * @author Mark Struberg @@ -44,4 +52,61 @@ protected CheckOutScmResult checkOut(File workingDirectory, ScmRepository reposi GitScmTestUtils.setDefaulGitConfig(workingDirectory); } } + + @Test + public void testUpToDatePush() throws Exception { + File checkedOutRepo = getWorkingCopy(); + + ScmRepository scmRepository = getScmManager().makeScmRepository(getScmUrl()); + checkoutRepoInto(checkedOutRepo, scmRepository); + + // Add a default user to the config + GitScmTestUtils.setDefaulGitConfig(checkedOutRepo); + + CheckInScmResult result = + getScmManager().checkIn(scmRepository, new ScmFileSet(checkedOutRepo), "No change commit message"); + + assertResultIsSuccess(result); + } + + @Test + public void testRejectedNonFastForwardPush() throws Exception { + File blockingRepo = PlexusJUnit4TestSupport.getTestFile("target/scm-test/blocking-repo"); + File rejectedRepo = PlexusJUnit4TestSupport.getTestFile("target/scm-test/rejected-repo"); + + ScmRepository scmRepository = getScmManager().makeScmRepository(getScmUrl()); + checkoutRepoInto(rejectedRepo, scmRepository); + checkoutRepoInto(blockingRepo, scmRepository); + + // Add a default user to the config + GitScmTestUtils.setDefaulGitConfig(rejectedRepo); + GitScmTestUtils.setDefaulGitConfig(blockingRepo); + + ScmFileSet blockingFileSet = createWorkspaceChange(rejectedRepo); + + CheckInScmResult blockingResult = getScmManager().checkIn(scmRepository, blockingFileSet, "Blocking commit"); + assertResultIsSuccess(blockingResult); + + ScmFileSet rejectedFileSet = createWorkspaceChange(blockingRepo); + + CheckInScmResult checkInScmResult = getScmManager().checkIn(scmRepository, rejectedFileSet, "Rejected commit"); + assertFalse( + "check-in should have been rejected since fast forward was not possible", checkInScmResult.isSuccess()); + } + + private CheckOutScmResult checkoutRepoInto(File workingCopy, ScmRepository scmRepository) throws Exception { + FileUtils.deleteDirectory(workingCopy); + workingCopy.mkdir(); + + CheckOutScmResult result = getScmManager().checkOut(scmRepository, new ScmFileSet(workingCopy), null); + + assertResultIsSuccess(result); + return result; + } + + private ScmFileSet createWorkspaceChange(File repo) throws IOException { + File beerFile = new File(repo.getAbsolutePath(), "beer.xml"); + FileUtils.fileWrite(beerFile.getAbsolutePath(), "1 litre"); + return new ScmFileSet(repo, beerFile.getName()); + } } diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java index 762b936d2..3b123904f 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java @@ -43,7 +43,9 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.UserConfig; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.RefSpec; +import org.eclipse.jgit.transport.RemoteRefUpdate; /** * This provider uses the following strategy to discover the committer and author name/mail for a commit: @@ -139,7 +141,19 @@ protected CheckInScmResult executeCheckInCommand( } RefSpec refSpec = new RefSpec(Constants.R_HEADS + branch + ":" + Constants.R_HEADS + branch); logger.info("push changes to remote... " + refSpec); - JGitUtils.push(git, (GitScmProviderRepository) repo, refSpec); + Iterable pushResultList = JGitUtils.push(git, (GitScmProviderRepository) repo, refSpec); + + for (PushResult pushResult : pushResultList) { + for (RemoteRefUpdate remoteRefUpdate : pushResult.getRemoteUpdates()) { + if (!isSuccessStatus(remoteRefUpdate.getStatus())) { + return new CheckInScmResult( + "JGit checkin", + "The git-push command failed, with status: " + remoteRefUpdate.getStatus(), + remoteRefUpdate.getMessage(), + false); + } + } + } } return new CheckInScmResult("JGit checkin", checkedInFiles); @@ -150,7 +164,13 @@ protected CheckInScmResult executeCheckInCommand( } } + private boolean isSuccessStatus(RemoteRefUpdate.Status remoteRefUpdateStatus) { + return remoteRefUpdateStatus == RemoteRefUpdate.Status.OK + || remoteRefUpdateStatus == RemoteRefUpdate.Status.UP_TO_DATE; + } + private static final class UserInfo { + final String name; final String email;