diff --git a/lib/datasource/npm.js b/lib/datasource/npm.js
index 36f4ff9d7b99a4c16b229b41e38c9a6e5080c9be..fc01fd8dd27fed598b53751e62b22ecbcbb303f6 100644
--- a/lib/datasource/npm.js
+++ b/lib/datasource/npm.js
@@ -146,7 +146,17 @@ async function getDependency(name, retries = 5) {
     let repositoryUrl;
 
     if (res.repository) {
-      repositoryUrl = parse(res.repository.url);
+      const extraBaseUrls = [];
+      // istanbul ignore if
+      if (process.env.GITHUB_ENDPOINT) {
+        const parsedEndpoint = url.parse(process.env.GITHUB_ENDPOINT);
+        extraBaseUrls.push(
+          parsedEndpoint.hostname,
+          `gist.${parsedEndpoint.hostname}`
+        );
+      }
+
+      repositoryUrl = parse(res.repository.url, { extraBaseUrls });
     }
     if (!repositoryUrl) {
       repositoryUrl = res.homepage;
diff --git a/lib/workers/pr/changelog/index.js b/lib/workers/pr/changelog/index.js
index a52a93c4d01f969484e2d09ba1148ea51cb7c9d5..341dbd843caca9815213b1b34519ab6004a9ec61 100644
--- a/lib/workers/pr/changelog/index.js
+++ b/lib/workers/pr/changelog/index.js
@@ -1,3 +1,5 @@
+const url = require('url');
+
 const { addReleaseNotes } = require('../release-notes');
 
 const sourceCache = require('./source-cache');
@@ -16,22 +18,77 @@ async function getChangeLogJSON(args) {
   if (!fromVersion || fromVersion === newVersion) {
     return null;
   }
-  // Return from cache if present
-  let res = await sourceCache.getChangeLogJSON(args);
-  if (res) {
-    return addReleaseNotes(res);
-  }
-  let pkg = null;
-  if (['npm', 'meteor'].includes(manager)) {
-    pkg = await managerNpm.getPackage(args);
-  }
 
-  if (manager === 'pip_requirements') {
-    pkg = await managerPip.getPackage(args);
+  let token;
+  let endpoint;
+  let gheBaseURL;
+  const opts = {
+    githubBaseURL: 'https://github.com/',
+  };
+
+  // istanbul ignore if
+  if (process.env.GITHUB_ENDPOINT) {
+    token = process.env.GITHUB_TOKEN;
+    endpoint = process.env.GITHUB_ENDPOINT;
+    const parsedEndpoint = url.parse(endpoint);
+    gheBaseURL = `${parsedEndpoint.protocol}//${parsedEndpoint.hostname}/`;
   }
 
-  res = await sourceGithub.getChangeLogJSON({ ...args, ...pkg });
+  try {
+    // Return from cache if present
+    let res = await sourceCache.getChangeLogJSON(args);
+    if (res) {
+      if (res.project && res.project.githubBaseURL !== gheBaseURL) {
+        logger.debug('Removing GHE token before calling addReleaseNotes');
+        delete process.env.GITHUB_ENDPOINT;
+        process.env.GITHUB_TOKEN = process.env.GITHUB_COM_TOKEN;
+      }
+    } else {
+      let pkg = null;
+      if (['npm', 'meteor'].includes(manager)) {
+        pkg = await managerNpm.getPackage(args);
+      }
+
+      if (manager === 'pip_requirements') {
+        pkg = await managerPip.getPackage(args);
+      }
 
-  await sourceCache.setChangeLogJSON(args, res);
-  return addReleaseNotes(res);
+      if (
+        pkg &&
+        pkg.repositoryUrl &&
+        gheBaseURL &&
+        pkg.repositoryUrl.startsWith(gheBaseURL)
+      ) {
+        logger.debug(
+          'Found package hosted on internal GHE. Preserving GHE token'
+        );
+        opts.githubBaseURL = gheBaseURL;
+      } else {
+        logger.debug('Removing GHE token before calling getChangeLogJSON');
+        delete process.env.GITHUB_ENDPOINT;
+        process.env.GITHUB_TOKEN = process.env.GITHUB_COM_TOKEN;
+      }
+
+      res = await sourceGithub.getChangeLogJSON({
+        ...args,
+        ...pkg,
+        ...opts,
+      });
+
+      await sourceCache.setChangeLogJSON(args, res);
+    }
+
+    const output = await addReleaseNotes(res);
+
+    return output;
+  } finally {
+    // wrap everything in a try/finally to ensure process.env.GITHUB_TOKEN is restore no matter if
+    // getChangeLogJSON and addReleaseNotes succed or fails
+    // istanbul ignore if
+    if (endpoint !== process.env.GITHUB_ENDPOINT) {
+      logger.debug('Restoring GHE token and endpoint');
+      process.env.GITHUB_TOKEN = token;
+      process.env.GITHUB_ENDPOINT = endpoint;
+    }
+  }
 }
diff --git a/lib/workers/pr/changelog/source-github.js b/lib/workers/pr/changelog/source-github.js
index de39aecdea5200b47a6623a78c3a2a74b6e09f9f..6a61089eff941367e721b58c99054037988c0e74 100644
--- a/lib/workers/pr/changelog/source-github.js
+++ b/lib/workers/pr/changelog/source-github.js
@@ -9,10 +9,9 @@ async function getTags(repository) {
   try {
     const versions = {};
 
-    const res = await ghGot(
-      `https://api.github.com/repos/${repository}/tags?per_page=100`,
-      { paginate: true }
-    );
+    const res = await ghGot(`repos/${repository}/tags?per_page=100`, {
+      paginate: true,
+    });
 
     const tags = (res && res.body) || [];
 
@@ -47,9 +46,7 @@ async function getRepositoryHead(repository, version) {
   }
   logger.trace({ repository, version }, 'Looking for commit SHA by date');
   try {
-    const res = await ghGot(
-      `https://api.github.com/repos/${repository}/commits/@{${version.date}}`
-    );
+    const res = await ghGot(`repos/${repository}/commits/@{${version.date}}`);
     const commit = res && res.body;
     return commit && commit.sha;
   } catch (err) {
@@ -59,6 +56,7 @@ async function getRepositoryHead(repository, version) {
 }
 
 async function getChangeLogJSON({
+  githubBaseURL,
   repositoryUrl,
   fromVersion,
   newVersion,
@@ -67,13 +65,13 @@ async function getChangeLogJSON({
   logger.debug('Checking for github source URL manually');
   const semverString = `>${fromVersion} <=${newVersion}`;
   logger.trace(`semverString: ${semverString}`);
-  if (!(repositoryUrl && repositoryUrl.startsWith('https://github.com/'))) {
+  if (!(repositoryUrl && repositoryUrl.startsWith(githubBaseURL))) {
     logger.debug('No repo found manually');
     return null;
   }
   logger.debug({ url: repositoryUrl }, 'Found github URL manually');
   const repository = repositoryUrl
-    .replace('https://github.com/', '')
+    .replace(githubBaseURL, '')
     .replace(/#.*/, '');
   if (repository.split('/').length !== 2) {
     logger.debug('Invalid github URL found');
@@ -106,7 +104,7 @@ async function getChangeLogJSON({
       const prevHead = await getHead(prev);
       const nextHead = await getHead(next);
       if (prevHead && nextHead) {
-        release.compare.url = `https://github.com/${repository}/compare/${prevHead}...${nextHead}`;
+        release.compare.url = `${githubBaseURL}${repository}/compare/${prevHead}...${nextHead}`;
       }
       releases.unshift(release);
     }
@@ -114,6 +112,7 @@ async function getChangeLogJSON({
 
   const res = {
     project: {
+      githubBaseURL,
       github: repository,
       repository: repositoryUrl,
     },
diff --git a/lib/workers/pr/index.js b/lib/workers/pr/index.js
index 2a01ad300755e60c8c7414072e225ec368d44ab6..36f3fedd7dbac2a9037be3ce90171a42bfe7547f 100644
--- a/lib/workers/pr/index.js
+++ b/lib/workers/pr/index.js
@@ -103,16 +103,6 @@ async function ensurePr(prConfig) {
 
   const commitRepos = [];
 
-  let token;
-  let endpoint;
-  // istanbul ignore if
-  if (process.env.GITHUB_ENDPOINT) {
-    logger.debug('Removing GHE token before calling changelog');
-    endpoint = process.env.GITHUB_ENDPOINT;
-    delete process.env.GITHUB_ENDPOINT;
-    token = process.env.GITHUB_TOKEN;
-    process.env.GITHUB_TOKEN = process.env.GITHUB_COM_TOKEN;
-  }
   // Get changelog and then generate template strings
   for (const upgrade of upgrades) {
     const upgradeKey = `${upgrade.depName}-${upgrade.manager}-${
@@ -149,12 +139,6 @@ async function ensurePr(prConfig) {
     }
     config.upgrades.push(upgrade);
   }
-  // istanbul ignore if
-  if (endpoint) {
-    logger.debug('Restoring GHE token and endpoint');
-    process.env.GITHUB_TOKEN = token;
-    process.env.GITHUB_ENDPOINT = endpoint;
-  }
 
   // Update the config object
   Object.assign(config, upgrades[0]);
diff --git a/lib/workers/pr/release-notes.js b/lib/workers/pr/release-notes.js
index 52c3887bda25c8d6c7c3e6b62facf53c6cd7ff55..06be88e0109077488ac27151dbf1090579e8ce3e 100644
--- a/lib/workers/pr/release-notes.js
+++ b/lib/workers/pr/release-notes.js
@@ -16,9 +16,7 @@ module.exports = {
 async function getReleaseList(repository) {
   logger.debug('getReleaseList()');
   try {
-    const res = await ghGot(
-      `https://api.github.com/repos/${repository}/releases?per_page=100`
-    );
+    const res = await ghGot(`repos/${repository}/releases?per_page=100`);
     return res.body.map(release => ({
       url: release.html_url,
       id: release.id,
@@ -32,19 +30,21 @@ async function getReleaseList(repository) {
   }
 }
 
-function massageBody(input) {
+function massageBody(input, githubBaseURL) {
   let body = input || '';
   // Convert line returns
   body = body.replace(/\r\n/g, '\n');
   // semantic-release cleanup
   body = body.replace(/^<a name="[^"]*"><\/a>\n/, '');
   body = body.replace(
-    /^##? \[[^\]]*\]\(https:\/\/github.com\/[^/]*\/[^/]*\/compare\/.*?\n/,
+    new RegExp(
+      `^##? \\[[^\\]]*\\]\\(${githubBaseURL}[^/]*\\/[^/]*\\/compare\\/.*?\\n`
+    ),
     ''
   );
   // Clean-up unnecessary commits link
   body = `\n${body}\n`.replace(
-    /\nhttps:\/\/github.com\/[^/]+\/[^/]+\/compare\/[^\n]+(\n|$)/,
+    new RegExp(`\\n${githubBaseURL}[^/]+\\/[^/]+\\/compare\\/[^\\n]+(\\n|$)`),
     '\n'
   );
   // Reduce headings size
@@ -56,17 +56,17 @@ function massageBody(input) {
   return body.trim();
 }
 
-async function getReleaseNotes(repository, version) {
+async function getReleaseNotes(repository, version, githubBaseURL) {
   logger.debug(`getReleaseNotes(${repository}, ${version})`);
   const releaseList = await getReleaseList(repository);
   let releaseNotes;
   releaseList.forEach(release => {
     if (release.tag === version || release.tag === `v${version}`) {
       releaseNotes = release;
-      releaseNotes.url = `https://github.com/${repository}/releases/${
+      releaseNotes.url = `${githubBaseURL}${repository}/releases/${
         release.tag
       }`;
-      releaseNotes.body = massageBody(releaseNotes.body);
+      releaseNotes.body = massageBody(releaseNotes.body, githubBaseURL);
       if (!releaseNotes.body.length) {
         releaseNotes = undefined;
       }
@@ -100,11 +100,11 @@ function sectionize(text, level) {
   return result;
 }
 
-async function getReleaseNotesMd(repository, version) {
+async function getReleaseNotesMd(repository, version, githubBaseURL) {
   logger.trace(`getReleaseNotes(${repository}, ${version})`);
   let changelogMd = '';
   try {
-    const apiPrefix = `https://api.github.com/repos/${repository}/contents/`;
+    const apiPrefix = `repos/${repository}/contents/`;
     const filesRes = await ghGot(apiPrefix);
     const files = filesRes.body
       .map(f => f.name)
@@ -141,10 +141,10 @@ async function getReleaseNotesMd(repository, version) {
           for (const word of title) {
             if (word.includes(version)) {
               logger.trace({ body }, 'Found release notes for v' + version);
-              let url = `https://github.com/${repository}/blob/master/CHANGELOG.md#`;
+              let url = `${githubBaseURL}${repository}/blob/master/CHANGELOG.md#`;
               url += title.join('-').replace(/[^A-Za-z0-9-]/g, '');
               return {
-                body: massageBody(body),
+                body: massageBody(body, githubBaseURL),
                 url,
               };
             }
@@ -168,10 +168,18 @@ async function addReleaseNotes(input) {
   const output = { ...input, versions: [] };
   const repository = input.project.github.replace(/\.git$/, '');
   for (const v of input.versions) {
-    let releaseNotes = await getReleaseNotesMd(repository, v.version);
+    let releaseNotes = await getReleaseNotesMd(
+      repository,
+      v.version,
+      input.project.githubBaseURL
+    );
     if (!releaseNotes) {
       logger.trace('No markdown release notes found for v' + v.version);
-      releaseNotes = await getReleaseNotes(repository, v.version);
+      releaseNotes = await getReleaseNotes(
+        repository,
+        v.version,
+        input.project.githubBaseURL
+      );
     }
     // Small hack to force display of release notes when there is a compare url
     if (!releaseNotes && v.compare.url) {
diff --git a/test/workers/pr/__snapshots__/changelog.spec.js.snap b/test/workers/pr/__snapshots__/changelog.spec.js.snap
index 62e5f122586fcdeaf602bb10b55afb8dba0a1b74..f1a994ef45ca25b28865989752da8b8abdc2a637 100644
--- a/test/workers/pr/__snapshots__/changelog.spec.js.snap
+++ b/test/workers/pr/__snapshots__/changelog.spec.js.snap
@@ -5,6 +5,7 @@ Object {
   "hasReleaseNotes": true,
   "project": Object {
     "github": "chalk/chalk",
+    "githubBaseURL": "https://github.com/",
     "repository": "https://github.com/chalk/chalk",
   },
   "versions": Array [
@@ -57,6 +58,7 @@ Object {
   "hasReleaseNotes": true,
   "project": Object {
     "github": "chalk/chalk",
+    "githubBaseURL": "https://github.com/",
     "repository": "https://github.com/chalk/chalk",
   },
   "versions": Array [
@@ -100,11 +102,61 @@ Object {
 }
 `;
 
+exports[`workers/pr/changelog getChangeLogJSON supports github enterprise 1`] = `
+Object {
+  "hasReleaseNotes": true,
+  "project": Object {
+    "github": "chalk/chalk",
+    "githubBaseURL": "https://github-enterprise.example.com/",
+    "repository": "https://github-enterprise.example.com/chalk/chalk",
+  },
+  "versions": Array [
+    Object {
+      "changes": Array [],
+      "compare": Object {},
+      "date": undefined,
+      "releaseNotes": undefined,
+      "version": "2.5.2",
+    },
+    Object {
+      "changes": Array [],
+      "compare": Object {},
+      "date": "2017-12-24T03:20:46.238Z",
+      "releaseNotes": undefined,
+      "version": "2.4.2",
+    },
+    Object {
+      "changes": Array [],
+      "compare": Object {
+        "url": "https://github-enterprise.example.com/chalk/chalk/compare/npm_2.2.2...npm_2.3.0",
+      },
+      "date": "2017-10-24T03:20:46.238Z",
+      "releaseNotes": Object {
+        "url": "https://github-enterprise.example.com/chalk/chalk/compare/npm_2.2.2...npm_2.3.0",
+      },
+      "version": "2.3.0",
+    },
+    Object {
+      "changes": Array [],
+      "compare": Object {
+        "url": "https://github-enterprise.example.com/chalk/chalk/compare/npm_1.0.0...npm_2.2.2",
+      },
+      "date": undefined,
+      "releaseNotes": Object {
+        "url": "https://github-enterprise.example.com/chalk/chalk/compare/npm_1.0.0...npm_2.2.2",
+      },
+      "version": "2.2.2",
+    },
+  ],
+}
+`;
+
 exports[`workers/pr/changelog getChangeLogJSON supports pip 1`] = `
 Object {
   "hasReleaseNotes": false,
   "project": Object {
     "github": "chalk/chalk",
+    "githubBaseURL": "https://github.com/",
     "repository": "https://github.com/chalk/chalk",
   },
   "versions": Array [
@@ -145,6 +197,7 @@ Object {
   "hasReleaseNotes": true,
   "project": Object {
     "github": "chalk/chalk",
+    "githubBaseURL": "https://github.com/",
     "repository": "https://github.com/chalk/chalk",
   },
   "versions": Array [
@@ -197,6 +250,7 @@ Object {
   "hasReleaseNotes": true,
   "project": Object {
     "github": "chalk/chalk",
+    "githubBaseURL": "https://github.com/",
     "repository": "https://github.com/chalk/chalk",
   },
   "versions": Array [
diff --git a/test/workers/pr/changelog.spec.js b/test/workers/pr/changelog.spec.js
index 9f8b5d643fdd6cf953324733b08c2c344b0d1225..95091ba7015b06c3c7e78edf34d273f1f3610f2e 100644
--- a/test/workers/pr/changelog.spec.js
+++ b/test/workers/pr/changelog.spec.js
@@ -173,5 +173,18 @@ describe('workers/pr/changelog', () => {
         await getChangeLogJSON({ ...upgrade, manager: 'pip_requirements' })
       ).toBe(null);
     });
+    it('supports github enterprise', async () => {
+      // clear the mock
+      npmRegistry.getDependency.mockReset();
+      const res = npmResponse();
+      res.repositoryUrl = 'https://github-enterprise.example.com/chalk/chalk';
+      npmRegistry.getDependency.mockReturnValueOnce(Promise.resolve(res));
+
+      const endpoint = process.env.GITHUB_ENDPOINT;
+      process.env.GITHUB_ENDPOINT = 'https://github-enterprise.example.com/';
+      expect(await getChangeLogJSON({ ...upgrade })).toMatchSnapshot();
+
+      process.env.GITHUB_ENDPOINT = endpoint;
+    });
   });
 });
diff --git a/test/workers/pr/index.spec.js b/test/workers/pr/index.spec.js
index 7e6ae6743250f9ad91ead95289c11b5a332e9308..daaab7ba23e3ec58591cca88ffe6cec5879a0f02 100644
--- a/test/workers/pr/index.spec.js
+++ b/test/workers/pr/index.spec.js
@@ -6,6 +6,7 @@ jest.mock('../../../lib/workers/pr/changelog');
 changelogHelper.getChangeLogJSON = jest.fn();
 changelogHelper.getChangeLogJSON.mockReturnValue({
   project: {
+    githubBaseURL: 'https://github.com/',
     github: 'renovateapp/dummy',
     repository: 'https://github.com/renovateapp/dummy',
   },
diff --git a/test/workers/pr/release-notes.spec.js b/test/workers/pr/release-notes.spec.js
index 4a4ae3beff784eecf88a3daabb05330f07dd49e1..3b2a1f05d17397e337af70abaad754c8c74ce582 100644
--- a/test/workers/pr/release-notes.spec.js
+++ b/test/workers/pr/release-notes.spec.js
@@ -33,20 +33,32 @@ describe('workers/pr/release-notes', () => {
       ghGot.mockReturnValueOnce({
         body: [{ tag_name: 'v1.0.0' }, { tag_name: 'v1.0.1' }],
       });
-      const res = await getReleaseNotes('some/repository', '1.0.0');
+      const res = await getReleaseNotes(
+        'some/repository',
+        '1.0.0',
+        'https://github.com/'
+      );
       expect(res).toMatchSnapshot();
     });
   });
   describe('getReleaseNotesMd()', () => {
     it('handles not found', async () => {
-      const res = await getReleaseNotesMd('chalk', '2.0.0');
+      const res = await getReleaseNotesMd(
+        'chalk',
+        '2.0.0',
+        'https://github.com/'
+      );
       expect(res).toBe(null);
     });
     it('handles files mismatch', async () => {
       ghGot.mockReturnValueOnce({
         body: [{ name: 'lib' }, { name: 'README.md' }],
       });
-      const res = await getReleaseNotesMd('chalk', '2.0.0');
+      const res = await getReleaseNotesMd(
+        'chalk',
+        '2.0.0',
+        'https://github.com/'
+      );
       expect(res).toBe(null);
     });
     it('handles wrong format', async () => {
@@ -57,7 +69,11 @@ describe('workers/pr/release-notes', () => {
             content: Buffer.from('not really markdown').toString('base64'),
           },
         });
-      const res = await getReleaseNotesMd('some/repository1', '1.0.0');
+      const res = await getReleaseNotesMd(
+        'some/repository1',
+        '1.0.0',
+        'https://github.com/'
+      );
       expect(res).toBe(null);
     });
     it('handles bad markdown', async () => {
@@ -68,7 +84,11 @@ describe('workers/pr/release-notes', () => {
             content: Buffer.from(`#\nha\nha\n#\nha\nha`).toString('base64'),
           },
         });
-      const res = await getReleaseNotesMd('some/repository2', '1.0.0');
+      const res = await getReleaseNotesMd(
+        'some/repository2',
+        '1.0.0',
+        'https://github.com/'
+      );
       expect(res).toBe(null);
     });
     it('parses angular.js', async () => {
@@ -79,7 +99,11 @@ describe('workers/pr/release-notes', () => {
             content: Buffer.from(angularJsChangelogMd).toString('base64'),
           },
         });
-      const res = await getReleaseNotesMd('angular/angular.js', '1.6.9');
+      const res = await getReleaseNotesMd(
+        'angular/angular.js',
+        '1.6.9',
+        'https://github.com/'
+      );
       expect(res).not.toBe(null);
       expect(res).toMatchSnapshot();
     });
@@ -91,7 +115,11 @@ describe('workers/pr/release-notes', () => {
             content: Buffer.from(jestChangelogMd).toString('base64'),
           },
         });
-      const res = await getReleaseNotesMd('facebook/jest', '22.0.0');
+      const res = await getReleaseNotesMd(
+        'facebook/jest',
+        '22.0.0',
+        'https://github.com/'
+      );
       expect(res).not.toBe(null);
       expect(res).toMatchSnapshot();
     });
@@ -103,7 +131,11 @@ describe('workers/pr/release-notes', () => {
             content: Buffer.from(jsYamlChangelogMd).toString('base64'),
           },
         });
-      const res = await getReleaseNotesMd('nodeca/js-yaml', '3.10.0');
+      const res = await getReleaseNotesMd(
+        'nodeca/js-yaml',
+        '3.10.0',
+        'https://github.com/'
+      );
       expect(res).not.toBe(null);
       expect(res).toMatchSnapshot();
     });