diff --git a/Makefile b/Makefile
index 466fafd1..f1fe2cbe 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ mvn-docker-build:
#TODO: add --abort-on-container-exit to docker-compose once itests can be made not to flap see issue #21
integration-test:
@-echo git_api_token=${ITEST_GH_TOKEN} > $(CURDIR)/itest.env
- user_itest_secrets_file_secret=$(CURDIR)/itest.env docker-compose up
+ user_itest_secrets_file_secret=$(CURDIR)/itest.env docker compose up
rm itest.env
get-main-project-dirs:
diff --git a/dockerfile-image-update/pom.xml b/dockerfile-image-update/pom.xml
index 3809295a..79af83f3 100644
--- a/dockerfile-image-update/pom.xml
+++ b/dockerfile-image-update/pom.xml
@@ -159,6 +159,16 @@
logging-interceptor
4.9.1
+
+ com.auth0
+ java-jwt
+ 3.18.1
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.68
+
diff --git a/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/CommandLine.java b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/CommandLine.java
index 745cecf2..0f42e19c 100644
--- a/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/CommandLine.java
+++ b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/CommandLine.java
@@ -112,6 +112,14 @@ static ArgumentParser getArgumentParser() {
.setDefault(false) //To prevent null from being returned by the argument
.required(false)
.help("Enable debug logging, including git wire logs.");
+ parser.addArgument("--" + SKIP_GITHUB_APP_ID)
+ .type(String.class)
+ .required(false)
+ .help("Github app ID of the Github App upon whose presence we skip sending the DFIU PR.");
+ parser.addArgument("--" + SKIP_GITHUB_APP_KEY)
+ .type(String.class)
+ .required(false)
+ .help("Path to the Github app key of the Github App upon whose presence we skip sending the DFIU PR.");
return parser;
}
@@ -253,7 +261,7 @@ public static GitHubBuilder shouldAddWireLogger(final GitHubBuilder builder, fin
logger.setLevel(HttpLoggingInterceptor.Level.HEADERS);
logger.redactHeader("Authorization");
- builder.withConnector(new OkHttpGitHubConnector(new OkHttpClient.Builder()
+ builder.withConnector(new OkHttpGitHubConnector(new OkHttpClient.Builder()
.addInterceptor(logger)
.build()));
}
diff --git a/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/Constants.java b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/Constants.java
index 194f7112..cde999a8 100644
--- a/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/Constants.java
+++ b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/Constants.java
@@ -42,6 +42,8 @@ private Constants() {
public static final String IGNORE_IMAGE_STRING = "x";
public static final String FILE_NAMES_TO_SEARCH = "filenamestosearch";
public static final String RATE_LIMIT_PR_CREATION = "rate_limit_pr_creations";
+ public static final String SKIP_GITHUB_APP_ID = "skipAppId";
+ public static final String SKIP_GITHUB_APP_KEY = "skipAppKey";
public static final String DEBUG = "debug";
//max number of PRs to be sent (or tokens to be added) per DEFAULT_RATE_LIMIT_DURATION(per hour in this case)
public static final long DEFAULT_RATE_LIMIT = 60;
diff --git a/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/GithubAppCheck.java b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/GithubAppCheck.java
new file mode 100644
index 00000000..ddf8dc48
--- /dev/null
+++ b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/GithubAppCheck.java
@@ -0,0 +1,134 @@
+package com.salesforce.dockerfileimageupdate.utils;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.salesforce.dockerfileimageupdate.CommandLine;
+import net.sourceforge.argparse4j.inf.Namespace;
+import org.bouncycastle.util.io.pem.PemReader;
+import org.kohsuke.github.GitHub;
+import org.kohsuke.github.GitHubBuilder;
+import org.kohsuke.github.HttpException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.Security;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.time.Instant;
+import java.util.Date;
+
+public class GithubAppCheck {
+ private static final Logger log = LoggerFactory.getLogger(GithubAppCheck.class);
+
+ private final String appId;
+ private final String privateKeyPath;
+ private String jwt;
+ private Instant jwtExpiry;
+ private GitHub gitHub;
+
+ public GithubAppCheck(final Namespace ns){
+ this.appId = ns.get(Constants.SKIP_GITHUB_APP_ID);
+ this.privateKeyPath = ns.get(Constants.SKIP_GITHUB_APP_KEY);
+ this.jwt = null;
+ this.jwtExpiry = null;
+ this.gitHub = null;
+ if (this.appId != null && this.privateKeyPath != null) {
+ try {
+ generateJWT(this.appId, this.privateKeyPath);
+ } catch (GeneralSecurityException | IOException exception) {
+ log.warn("Could not initialise JWT due to exception: {}", exception.getMessage());
+ }
+ try {
+ this.gitHub = new GitHubBuilder()
+ .withEndpoint(CommandLine.gitApiUrl(ns))
+ .withJwtToken(jwt)
+ .build();
+ } catch (IOException exception) {
+ log.warn("Could not initialise github due to exception: {}", exception.getMessage());
+ }
+ }
+ else {
+ log.warn("Could not find any Github app ID and Github app Key in the declared list. Hence assuming this class is no longer needed");
+ }
+ }
+
+ /**
+ * Method to verify whether the github app is installed on a repository or not.
+ * @param fullRepoName = The repository full name, i.e, of the format "owner/repoName". Eg: "Salesforce/dockerfile-image-update"
+ * @return True if github app is installed, false otherwise.
+ */
+ protected boolean isGithubAppEnabledOnRepository(String fullRepoName) {
+ refreshJwtIfNeeded(appId, privateKeyPath);
+ try {
+ gitHub.getApp().getInstallationByRepository(fullRepoName.split("/")[0], fullRepoName.split("/")[1]);
+ return true;
+ } catch (HttpException exception) {
+ if (exception.getResponseCode() != 404) {
+ // Log for any HTTP status code other than 404 Not found.
+ log.warn("Caught a HTTPException {} while trying to get app installation. Defaulting to False", exception.getMessage());
+ }
+ return false;
+ } catch (IOException exception) {
+ // Most often happens on timeout scenarios.
+ log.warn("Caught a IOException {} while trying to get app installation. Defaulting to False", exception.getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * Method to refresh the JWT token if needed. Checks the JWT expiry time, and if it is 60s away from expiring, refreshes it.
+ * @param appId = The id of the Github App to generate the JWT for
+ * @param privateKeyPath = The path to the private key of the Github App to generate the JWT for
+ */
+ private void refreshJwtIfNeeded(String appId, String privateKeyPath) {
+ if (jwt == null || jwtExpiry.isBefore(Instant.now().minusSeconds(60))) { // Adding a buffer to ensure token validity
+ try {
+ generateJWT(appId, privateKeyPath);
+ } catch (IOException | GeneralSecurityException exception) {
+ log.warn("Could not refresh the JWT due to exception: {}", exception.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Method to generate the JWT used to access the Github App APIs. We generate the JWT to be valid for 600 seconds.
+ * Along with the JWT value, the jwtExpiry value is set to the time of 600 sec from now.
+ * @param appId = The id of the Github App to generate the JWT for
+ * @param privateKeyPath = The path to the private key of the Github App to generate the JWT for
+ * @throws IOException
+ * @throws GeneralSecurityException
+ */
+ private void generateJWT(String appId, String privateKeyPath) throws IOException, GeneralSecurityException {
+ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+ RSAPrivateKey privateKey = getRSAPrivateKey(privateKeyPath);
+
+ Algorithm algorithm = Algorithm.RSA256(null, privateKey);
+ Instant now = Instant.now();
+ jwt = JWT.create()
+ .withIssuer(appId)
+ .withIssuedAt(Date.from(now))
+ .withExpiresAt(Date.from(now.plusSeconds(600))) // 10 minutes expiration
+ .sign(algorithm);
+ jwtExpiry = now.plusSeconds(600);
+ }
+
+ /**
+ * The method to get the private key in an RSA Encoded format. Makes use of org.bouncycastle.util
+ * @param privateKeyPath
+ * @return
+ * @throws IOException
+ * @throws GeneralSecurityException
+ */
+ private RSAPrivateKey getRSAPrivateKey(String privateKeyPath) throws IOException, GeneralSecurityException {
+ try (PemReader pemReader = new PemReader(new FileReader(new File(privateKeyPath)))) {
+ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pemReader.readPemObject().getContent());
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ return (RSAPrivateKey) keyFactory.generatePrivate(spec);
+ }
+ }
+}
diff --git a/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/PullRequests.java b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/PullRequests.java
index b99987c7..c07c8659 100644
--- a/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/PullRequests.java
+++ b/dockerfile-image-update/src/main/java/com/salesforce/dockerfileimageupdate/utils/PullRequests.java
@@ -25,6 +25,7 @@ public void prepareToCreate(final Namespace ns,
pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch);
List exceptions = new ArrayList<>();
List skippedRepos = new ArrayList<>();
+ GithubAppCheck githubAppCheck = new GithubAppCheck(ns);
for (String currUserRepo : pathToDockerfilesInParentRepo.keySet()) {
Optional forkWithContentPaths =
pathToDockerfilesInParentRepo.get(currUserRepo).stream().findFirst();
@@ -32,8 +33,8 @@ public void prepareToCreate(final Namespace ns,
try {
//If the repository has been onboarded to renovate enterprise, skip sending the DFIU PR
if(ns.getBoolean(Constants.CHECK_FOR_RENOVATE)
- && (isRenovateEnabled(Constants.RENOVATE_CONFIG_FILEPATHS, forkWithContentPaths.get()))) {
- log.info("Found a renovate configuration file in the repo {}. Skip sending DFIU PRs to this repository.", forkWithContentPaths.get().getParent().getFullName());
+ && (githubAppCheck.isGithubAppEnabledOnRepository(forkWithContentPaths.get().getParent().getFullName()))) {
+ log.info("The repo {} is onboarded onto Renovate. Hence, skip sending DFIU PRs to this repository.", forkWithContentPaths.get().getParent().getFullName());
} else {
dockerfileGitHubUtil.changeDockerfiles(ns,
pathToDockerfilesInParentRepo,
diff --git a/dockerfile-image-update/src/test/java/com/salesforce/dockerfileimageupdate/utils/PullRequestsTest.java b/dockerfile-image-update/src/test/java/com/salesforce/dockerfileimageupdate/utils/PullRequestsTest.java
index d1aaf477..b746ff1e 100644
--- a/dockerfile-image-update/src/test/java/com/salesforce/dockerfileimageupdate/utils/PullRequestsTest.java
+++ b/dockerfile-image-update/src/test/java/com/salesforce/dockerfileimageupdate/utils/PullRequestsTest.java
@@ -17,144 +17,135 @@
import static org.testng.Assert.assertThrows;
public class PullRequestsTest {
- @Test
- public void testPullRequestsPrepareToCreateSuccessful() throws Exception {
- Map nsMap = ImmutableMap.of(Constants.IMG,
- "image", Constants.TAG,
- "tag", Constants.STORE,
- "store", Constants.SKIP_PR_CREATION,
- false, Constants.CHECK_FOR_RENOVATE, false);
- Namespace ns = new Namespace(nsMap);
- PullRequests pullRequests = new PullRequests();
- GitHubPullRequestSender pullRequestSender = mock(GitHubPullRequestSender.class);
- PagedSearchIterable contentsFoundWithImage = mock(PagedSearchIterable.class);
- GitForkBranch gitForkBranch = mock(GitForkBranch.class);
- DockerfileGitHubUtil dockerfileGitHubUtil = mock(DockerfileGitHubUtil.class);
- RateLimiter rateLimiter = Mockito.spy(new RateLimiter());
- Multimap pathToDockerfilesInParentRepo = ArrayListMultimap.create();
- GitHubContentToProcess gitHubContentToProcess = mock(GitHubContentToProcess.class);
- pathToDockerfilesInParentRepo.put("repo1", gitHubContentToProcess);
- pathToDockerfilesInParentRepo.put("repo2", gitHubContentToProcess);
- when(pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch)).thenReturn(pathToDockerfilesInParentRepo);
-
-
- pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
- gitForkBranch, dockerfileGitHubUtil, rateLimiter);
-
- verify(dockerfileGitHubUtil, times(2)).changeDockerfiles(eq(ns),
- eq(pathToDockerfilesInParentRepo),
- eq(gitHubContentToProcess), anyList(), eq(gitForkBranch),
- eq(rateLimiter));
- }
-
- @Test(expectedExceptions = IOException.class)
- public void testPullRequestsPrepareThrowsException() throws Exception {
- Map nsMap = ImmutableMap.of(Constants.IMG,
- "image", Constants.TAG,
- "tag", Constants.STORE,
- "store", Constants.SKIP_PR_CREATION,
- false, Constants.CHECK_FOR_RENOVATE, false);
- Namespace ns = new Namespace(nsMap);
- PullRequests pullRequests = new PullRequests();
- GitHubPullRequestSender pullRequestSender = mock(GitHubPullRequestSender.class);
- PagedSearchIterable contentsFoundWithImage = mock(PagedSearchIterable.class);
- GitForkBranch gitForkBranch = mock(GitForkBranch.class);
- RateLimiter rateLimiter = Mockito.spy(new RateLimiter());
- DockerfileGitHubUtil dockerfileGitHubUtil = mock(DockerfileGitHubUtil.class);
- Multimap pathToDockerfilesInParentRepo = ArrayListMultimap.create();
- GitHubContentToProcess gitHubContentToProcess = mock(GitHubContentToProcess.class);
- pathToDockerfilesInParentRepo.put("repo1", gitHubContentToProcess);
- GHRepository ghRepository = mock(GHRepository.class);
-
- when(pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch)).thenReturn(pathToDockerfilesInParentRepo);
- ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class);
- when(gitHubContentToProcess.getParent()).thenReturn(ghRepository);
- when(ghRepository.getFullName()).thenReturn("repo");
- doThrow(new IOException("Exception")).when(dockerfileGitHubUtil).changeDockerfiles(
- eq(ns),
- eq(pathToDockerfilesInParentRepo),
- eq(gitHubContentToProcess),
- anyList(),
- eq(gitForkBranch),
- eq(rateLimiter));
-
- pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
- gitForkBranch, dockerfileGitHubUtil, rateLimiter);
-
- assertThrows(IOException.class, () -> pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
- gitForkBranch, dockerfileGitHubUtil, rateLimiter));
- }
+ @Test
+ public void testPullRequestsPrepareToCreateSuccessful() throws Exception {
+ Map nsMap = ImmutableMap.of(Constants.IMG,
+ "image", Constants.TAG,
+ "tag", Constants.STORE,
+ "store", Constants.SKIP_PR_CREATION,
+ false, Constants.CHECK_FOR_RENOVATE, false);
+ Namespace ns = new Namespace(nsMap);
+ PullRequests pullRequests = new PullRequests();
+ GitHubPullRequestSender pullRequestSender = mock(GitHubPullRequestSender.class);
+ PagedSearchIterable contentsFoundWithImage = mock(PagedSearchIterable.class);
+ GitForkBranch gitForkBranch = mock(GitForkBranch.class);
+ DockerfileGitHubUtil dockerfileGitHubUtil = mock(DockerfileGitHubUtil.class);
+ GithubAppCheck githubAppCheck = mock(GithubAppCheck.class);
+ RateLimiter rateLimiter = Mockito.spy(new RateLimiter());
+ Multimap pathToDockerfilesInParentRepo = ArrayListMultimap.create();
+ GitHubContentToProcess gitHubContentToProcess = mock(GitHubContentToProcess.class);
+ pathToDockerfilesInParentRepo.put("repo1", gitHubContentToProcess);
+ pathToDockerfilesInParentRepo.put("repo2", gitHubContentToProcess);
+ when(pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch)).thenReturn(pathToDockerfilesInParentRepo);
+
+ pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
+ gitForkBranch, dockerfileGitHubUtil, rateLimiter);
+
+ verify(dockerfileGitHubUtil, times(2)).changeDockerfiles(eq(ns),
+ eq(pathToDockerfilesInParentRepo),
+ eq(gitHubContentToProcess), anyList(), eq(gitForkBranch),
+ eq(rateLimiter));
+ }
+
+ @Test(expectedExceptions = IOException.class)
+ public void testPullRequestsPrepareThrowsException() throws Exception {
+ Map nsMap = ImmutableMap.of(Constants.IMG,
+ "image", Constants.TAG,
+ "tag", Constants.STORE,
+ "store", Constants.SKIP_PR_CREATION,
+ false, Constants.CHECK_FOR_RENOVATE, false);
+ Namespace ns = new Namespace(nsMap);
+ PullRequests pullRequests = new PullRequests();
+ GitHubPullRequestSender pullRequestSender = mock(GitHubPullRequestSender.class);
+ PagedSearchIterable contentsFoundWithImage = mock(PagedSearchIterable.class);
+ GitForkBranch gitForkBranch = mock(GitForkBranch.class);
+ RateLimiter rateLimiter = Mockito.spy(new RateLimiter());
+ DockerfileGitHubUtil dockerfileGitHubUtil = mock(DockerfileGitHubUtil.class);
+ GithubAppCheck githubAppCheck = mock(GithubAppCheck.class);
+ Multimap pathToDockerfilesInParentRepo = ArrayListMultimap.create();
+ GitHubContentToProcess gitHubContentToProcess = mock(GitHubContentToProcess.class);
+ pathToDockerfilesInParentRepo.put("repo1", gitHubContentToProcess);
+ GHRepository ghRepository = mock(GHRepository.class);
+
+ when(pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch)).thenReturn(pathToDockerfilesInParentRepo);
+ ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class);
+ when(gitHubContentToProcess.getParent()).thenReturn(ghRepository);
+ when(ghRepository.getFullName()).thenReturn("repo");
+ doThrow(new IOException("Exception")).when(dockerfileGitHubUtil).changeDockerfiles(
+ eq(ns),
+ eq(pathToDockerfilesInParentRepo),
+ eq(gitHubContentToProcess),
+ anyList(),
+ eq(gitForkBranch),
+ eq(rateLimiter));
+
+ pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
+ gitForkBranch, dockerfileGitHubUtil, rateLimiter);
+
+ assertThrows(IOException.class, () -> pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
+ gitForkBranch, dockerfileGitHubUtil, rateLimiter));
+ }
+
+ @Test
+ public void testPullRequestsPrepareToCreateWhenNoDockerfileFound() throws Exception {
+ Map nsMap = ImmutableMap.of(Constants.IMG,
+ "image", Constants.TAG,
+ "tag", Constants.STORE,
+ "store", Constants.SKIP_PR_CREATION,
+ false, Constants.CHECK_FOR_RENOVATE, false);
+ Namespace ns = new Namespace(nsMap);
+ PullRequests pullRequests = new PullRequests();
+ GitHubPullRequestSender pullRequestSender = mock(GitHubPullRequestSender.class);
+ PagedSearchIterable contentsFoundWithImage = mock(PagedSearchIterable.class);
+ GitForkBranch gitForkBranch = mock(GitForkBranch.class);
+ GithubAppCheck githubAppCheck = mock(GithubAppCheck.class);
+ RateLimiter rateLimiter = Mockito.spy(new RateLimiter());
+ DockerfileGitHubUtil dockerfileGitHubUtil = mock(DockerfileGitHubUtil.class);
+ Multimap pathToDockerfilesInParentRepo = mock(Multimap.class);
+ GitHubContentToProcess gitHubContentToProcess = mock(GitHubContentToProcess.class);
+ when(pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch)).thenReturn(pathToDockerfilesInParentRepo);
+ Set currUsers = new HashSet<>();
+ currUsers.add("repo1");
+ when(pathToDockerfilesInParentRepo.keySet()).thenReturn(currUsers);
+ pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
+ gitForkBranch, dockerfileGitHubUtil, rateLimiter);
+
+ verify(dockerfileGitHubUtil, times(0)).changeDockerfiles(eq(ns),
+ eq(pathToDockerfilesInParentRepo),
+ eq(gitHubContentToProcess), anyList(), eq(gitForkBranch),eq(rateLimiter));
+ }
@Test
- public void testPullRequestsPrepareToCreateWhenNoDockerfileFound() throws Exception {
+ public void testPullRequestsPrepareSkipsSendingPRIfRepoOnboardedToRenovate() throws Exception {
Map nsMap = ImmutableMap.of(Constants.IMG,
- "image", Constants.TAG,
- "tag", Constants.STORE,
- "store", Constants.SKIP_PR_CREATION,
- false, Constants.CHECK_FOR_RENOVATE, false);
+ "image", Constants.TAG,
+ "tag", Constants.STORE,
+ "store", Constants.SKIP_PR_CREATION,
+ false, Constants.CHECK_FOR_RENOVATE, true);
Namespace ns = new Namespace(nsMap);
PullRequests pullRequests = new PullRequests();
GitHubPullRequestSender pullRequestSender = mock(GitHubPullRequestSender.class);
PagedSearchIterable contentsFoundWithImage = mock(PagedSearchIterable.class);
GitForkBranch gitForkBranch = mock(GitForkBranch.class);
+ GithubAppCheck githubAppCheck = mock(GithubAppCheck.class);
RateLimiter rateLimiter = Mockito.spy(new RateLimiter());
DockerfileGitHubUtil dockerfileGitHubUtil = mock(DockerfileGitHubUtil.class);
Multimap pathToDockerfilesInParentRepo = mock(Multimap.class);
GitHubContentToProcess gitHubContentToProcess = mock(GitHubContentToProcess.class);
+ GHRepository ghRepository = mock(GHRepository.class);
+
when(pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch)).thenReturn(pathToDockerfilesInParentRepo);
Set currUsers = new HashSet<>();
currUsers.add("repo1");
when(pathToDockerfilesInParentRepo.keySet()).thenReturn(currUsers);
- pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
- gitForkBranch, dockerfileGitHubUtil, rateLimiter);
-
- verify(dockerfileGitHubUtil, times(0)).changeDockerfiles(eq(ns),
- eq(pathToDockerfilesInParentRepo),
- eq(gitHubContentToProcess), anyList(), eq(gitForkBranch),eq(rateLimiter));
- }
-
- @Test
- public void testPullRequestsPrepareSkipsSendingPRIfRepoOnboardedToRenovate() throws Exception {
- Map nsMap = ImmutableMap.of(
- Constants.IMG, "image",
- Constants.TAG, "tag",
- Constants.STORE,"store",
- Constants.SKIP_PR_CREATION,false,
- Constants.CHECK_FOR_RENOVATE, true);
-
-
- Namespace ns = new Namespace(nsMap);
- PullRequests pullRequests = new PullRequests();
- GitHubPullRequestSender pullRequestSender = mock(GitHubPullRequestSender.class);
- PagedSearchIterable contentsFoundWithImage = mock(PagedSearchIterable.class);
- GitForkBranch gitForkBranch = mock(GitForkBranch.class);
- DockerfileGitHubUtil dockerfileGitHubUtil = mock(DockerfileGitHubUtil.class);
- RateLimiter rateLimiter = Mockito.spy(new RateLimiter());
- Multimap pathToDockerfilesInParentRepo = ArrayListMultimap.create();
- GitHubContentToProcess gitHubContentToProcess = mock(GitHubContentToProcess.class);
- pathToDockerfilesInParentRepo.put("repo1", gitHubContentToProcess);
- pathToDockerfilesInParentRepo.put("repo2", gitHubContentToProcess);
- pathToDockerfilesInParentRepo.put("repo3", gitHubContentToProcess);
- GHContent content = mock(GHContent.class);
- InputStream inputStream1 = new ByteArrayInputStream("{someKey:someValue}".getBytes());
- InputStream inputStream2 = new ByteArrayInputStream("{enabled:false}".getBytes());
- GHRepository ghRepository = mock(GHRepository.class);
-
- when(pullRequestSender.forkRepositoriesFoundAndGetPathToDockerfiles(contentsFoundWithImage, gitForkBranch)).thenReturn(pathToDockerfilesInParentRepo);
when(gitHubContentToProcess.getParent()).thenReturn(ghRepository);
- //Fetch the content of the renovate.json file for the 3 repos.
- // The first one returns a file with regular json content.
- // The second one returns a file with the key 'enabled' set to 'false' to replicate a repo that has been onboarded to renovate but has it disabled
- // The third repo does not have the renovate.json file
- when(ghRepository.getFileContent(anyString())).thenReturn(content).thenReturn(content).thenThrow(new FileNotFoundException());
- when(ghRepository.getFullName()).thenReturn("org/repo");
- when(content.read()).thenReturn(inputStream1).thenReturn(inputStream2);
+ when(ghRepository.getFullName()).thenReturn("repoParent");
+ when(githubAppCheck.isGithubAppEnabledOnRepository(anyString())).thenReturn(true);
pullRequests.prepareToCreate(ns, pullRequestSender, contentsFoundWithImage,
gitForkBranch, dockerfileGitHubUtil, rateLimiter);
- //Verify that the DFIU PR is skipped for the first repo, but is sent to the other two repos
- verify(dockerfileGitHubUtil, times(2)).changeDockerfiles(eq(ns),
+ verify(dockerfileGitHubUtil, times(0)).changeDockerfiles(eq(ns),
eq(pathToDockerfilesInParentRepo),
eq(gitHubContentToProcess), anyList(), eq(gitForkBranch),
eq(rateLimiter));