From 7a841de7e66aa23ff8975765d363bc4d4d8586d0 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@keylocation.sg>
Date: Sat, 8 Jul 2017 06:01:02 +0200
Subject: [PATCH] feat(onboarding): dependencies.pinVersions=true for private
 repos (#475)

Closes #369
---
 lib/workers/repository/onboarding.js          | 19 +++++++
 .../__snapshots__/onboarding.spec.js.snap     | 53 ++++++++++++++++++-
 test/workers/repository/onboarding.spec.js    | 35 ++++++++++++
 3 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/lib/workers/repository/onboarding.js b/lib/workers/repository/onboarding.js
index 0fd7ff1227..169a4d5e4e 100644
--- a/lib/workers/repository/onboarding.js
+++ b/lib/workers/repository/onboarding.js
@@ -8,6 +8,7 @@ const onboardPrTitle = 'Configure Renovate';
 
 module.exports = {
   determineSemanticCommits,
+  isRepoPrivate,
   createBranch,
   ensurePr,
   getOnboardingStatus,
@@ -27,11 +28,29 @@ async function determineSemanticCommits(config) {
   return true;
 }
 
+async function isRepoPrivate(config) {
+  let repoIsPrivate = true;
+  for (const packageFile of config.packageFiles) {
+    const fileName =
+      typeof packageFile === 'string' ? packageFile : packageFile.packageFile;
+    const packageContent = await config.api.getFileJson(fileName);
+    repoIsPrivate = repoIsPrivate && packageContent && packageContent.private;
+  }
+  return repoIsPrivate === true;
+}
+
 async function createBranch(config) {
   const onboardingConfig = configParser.getOnboardingConfig(config);
   onboardingConfig.semanticCommits = await module.exports.determineSemanticCommits(
     config
   );
+  const repoIsPrivate = await module.exports.isRepoPrivate(config);
+  if (repoIsPrivate) {
+    config.logger.debug('Repo is private - pinning dependencies versions');
+  } else {
+    config.logger.debug('Repo is not private - unpinning versions');
+    onboardingConfig.depTypes[0].pinVersions = false;
+  }
   const onboardingConfigString = `${stringify(onboardingConfig)}\n`;
   await config.api.commitFilesToBranch(
     onboardBranchName,
diff --git a/test/workers/repository/__snapshots__/onboarding.spec.js.snap b/test/workers/repository/__snapshots__/onboarding.spec.js.snap
index ef25ad33f9..b46c692780 100644
--- a/test/workers/repository/__snapshots__/onboarding.spec.js.snap
+++ b/test/workers/repository/__snapshots__/onboarding.spec.js.snap
@@ -212,7 +212,11 @@ Array [
   \\"schedule\\": [],
   \\"packageFiles\\": [],
   \\"depTypes\\": [
-    {\\"depType\\": \\"dependencies\\", \\"semanticPrefix\\": \\"fix(deps): \\"},
+    {
+      \\"depType\\": \\"dependencies\\",
+      \\"semanticPrefix\\": \\"fix(deps): \\",
+      \\"pinVersions\\": false
+    },
     \\"devDependencies\\",
     \\"optionalDependencies\\"
   ],
@@ -249,7 +253,11 @@ Array [
   \\"schedule\\": [],
   \\"packageFiles\\": [],
   \\"depTypes\\": [
-    {\\"depType\\": \\"dependencies\\", \\"semanticPrefix\\": \\"fix(deps): \\"},
+    {
+      \\"depType\\": \\"dependencies\\",
+      \\"semanticPrefix\\": \\"fix(deps): \\",
+      \\"pinVersions\\": false
+    },
     \\"devDependencies\\",
     \\"optionalDependencies\\"
   ],
@@ -274,3 +282,44 @@ Array [
   "Add renovate.json",
 ]
 `;
+
+exports[`lib/workers/repository/onboarding getOnboardingStatus(config) pins private repos 1`] = `
+Array [
+  "renovate/configure",
+  Array [
+    Object {
+      "contents": "{
+  \\"enabled\\": true,
+  \\"timezone\\": null,
+  \\"schedule\\": [],
+  \\"packageFiles\\": [],
+  \\"depTypes\\": [
+    {
+      \\"depType\\": \\"dependencies\\",
+      \\"semanticPrefix\\": \\"fix(deps): \\",
+      \\"pinVersions\\": false
+    },
+    \\"devDependencies\\",
+    \\"optionalDependencies\\"
+  ],
+  \\"ignoreDeps\\": [],
+  \\"pinVersions\\": true,
+  \\"separateMajorReleases\\": true,
+  \\"semanticCommits\\": false,
+  \\"semanticPrefix\\": \\"chore(deps): \\",
+  \\"rebaseStalePrs\\": false,
+  \\"prCreation\\": \\"immediate\\",
+  \\"automerge\\": \\"none\\",
+  \\"branchName\\": \\"renovate/{{depName}}-{{newVersionMajor}}.x\\",
+  \\"commitMessage\\": \\"{{semanticPrefix}}Update dependency {{depName}} to version {{newVersion}}\\",
+  \\"labels\\": [],
+  \\"assignees\\": [],
+  \\"reviewers\\": []
+}
+",
+      "name": "renovate.json",
+    },
+  ],
+  "Add renovate.json",
+]
+`;
diff --git a/test/workers/repository/onboarding.spec.js b/test/workers/repository/onboarding.spec.js
index 1b8b93284e..fec0365ed4 100644
--- a/test/workers/repository/onboarding.spec.js
+++ b/test/workers/repository/onboarding.spec.js
@@ -3,6 +3,32 @@ const logger = require('../../_fixtures/logger');
 const defaultConfig = require('../../../lib/config/defaults').getConfig();
 
 describe('lib/workers/repository/onboarding', () => {
+  describe('isRepoPrivate(config)', () => {
+    let config;
+    beforeEach(() => {
+      config = {
+        api: {
+          getFileJson: jest.fn(),
+        },
+        packageFiles: [
+          'package.json',
+          {
+            packageFile: 'a/package.json',
+          },
+        ],
+      };
+    });
+    it('returns true if all are private', async () => {
+      config.api.getFileJson.mockReturnValueOnce({ private: true });
+      config.api.getFileJson.mockReturnValueOnce({ private: true });
+      expect(await onboarding.isRepoPrivate(config)).toBe(true);
+    });
+    it('returns false if some are not private', async () => {
+      config.api.getFileJson.mockReturnValueOnce({ private: true });
+      config.api.getFileJson.mockReturnValueOnce({});
+      expect(await onboarding.isRepoPrivate(config)).toBe(false);
+    });
+  });
   describe('ensurePr(config, branchUpgrades)', () => {
     let config;
     let branchUpgrades;
@@ -182,6 +208,7 @@ describe('lib/workers/repository/onboarding', () => {
       };
       config.logger = logger;
       config.detectedPackageFiles = true;
+      onboarding.isRepoPrivate = jest.fn();
     });
     it('returns true if onboarding is false', async () => {
       config.onboarding = false;
@@ -235,5 +262,13 @@ describe('lib/workers/repository/onboarding', () => {
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0]).toMatchSnapshot();
     });
+    it('pins private repos', async () => {
+      onboarding.isRepoPrivate.mockReturnValueOnce(true);
+      const res = await onboarding.getOnboardingStatus(config);
+      expect(res).toEqual(false);
+      expect(config.api.findPr.mock.calls.length).toBe(1);
+      expect(config.api.commitFilesToBranch.mock.calls.length).toBe(1);
+      expect(config.api.commitFilesToBranch.mock.calls[0]).toMatchSnapshot();
+    });
   });
 });
-- 
GitLab