Repository: electron-userland/electron-forge (ts)

Issue:
Feature Request: GitHub Enterprise release support
It would be great if electron-forge supported GitHub Enterprise releases. I didn't see a property in the config for GHE URL, unless I missed it.


Pull request:
feat(publisher): add GitHub Enterprise/HTTP proxy support to the GitHub publisher
* [x] I have read the [contribution documentation](https://github.com/electron-userland/electron-forge/blob/master/CONTRIBUTING.md) for this project.
* [x] I agree to follow the [code of conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project follows, as appropriate.
* [x] The changes are appropriately documented (if applicable).
* [x] The changes have sufficient test coverage (if applicable).
* [x] The testsuite passes successfully on my local machine (if applicable).

**Summarize your changes:**

Fixes #416.

Patch:
diff --git a/README.md b/README.md
index a1b60095c..1089e29c8 100644
--- a/README.md
+++ b/README.md
@@ -229,7 +229,7 @@ the JS file method mentioned above then you can use functions normally.
 
 | Target Name | Description | Required Config |
 |-------------|-------------|-----------------|
-| GitHub Releases - `github` | Makes a new release for the current version (if required) and uploads the make artifacts as release assets | `process.env.GITHUB_TOKEN` - A personal access token with access to your releases <br />`forge.github_repository.owner` - The owner of the GitHub repository<br />`forge.github_repository.name` - The name of the GitHub repository <br />`forge.github_repository.draft` - Create the release as a draft, defaults to `true` <br />`forge.github_repository.prerelease` - Identify the release as a prerelease, defaults to `false` |
+| GitHub Releases - `github` | Makes a new release for the current version (if required) and uploads the make artifacts as release assets | `process.env.GITHUB_TOKEN` - A personal access token with access to your releases <br />`forge.github_repository.owner` - The owner of the GitHub repository<br />`forge.github_repository.name` - The name of the GitHub repository <br />`forge.github_repository.draft` - Create the release as a draft, defaults to `true` <br />`forge.github_repository.prerelease` - Identify the release as a prerelease, defaults to `false` <br />`forge.github_repository.options` - An `Object` of [connection options](https://github.com/octokit/rest.js#usage), e.g., GitHub Enterprise settings or HTTP proxy URL |
 | Amazon S3 - `s3` | Uploads your artifacts to the given S3 bucket | `process.env.ELECTRON_FORGE_S3_SECRET_ACCESS_KEY` - Your secret access token for your AWS account _(falls back to the standard `AWS_SECRET_ACCESS_KEY` environment variable)_<br />`forge.s3.accessKeyId` - Your access key for your AWS account _(falls back to the standard `AWS_ACCESS_KEY_ID` environment variable)_<br />`forge.s3.bucket` - The name of the S3 bucket to upload to<br />`forge.s3.folder` - The folder path to upload to inside your bucket, defaults to your application version<br />`forge.s3.public` - Whether to make the S3 upload public, defaults to `false` |
 | [Electron Release Server](https://github.com/ArekSredzki/electron-release-server) - `electron-release-server` |  Makes a new release for the current version and uploads the artifacts to the correct platform/arch in the given version.  If the version already exists no upload will be performed.  The channel is determined from the current version. | `forge.electronReleaseServer.baseUrl` - The base URL of your release server, no trailing slash<br />`forge.electronReleaseServer.username` - The username for the admin panel on your server<br />`forge.electronReleaseServer.password` - The password for the admin panel on your server |
 | [Snapcraft](https://snapcraft.io/store/) - `snapStore` | Uploads generated Snaps to the Snap Store. | `forge.snapStore.release` - If specified, a comma-separated list of channels to release to. |
diff --git a/src/publishers/github.js b/src/publishers/github.js
index 51b1522e7..940b723e7 100644
--- a/src/publishers/github.js
+++ b/src/publishers/github.js
@@ -11,7 +11,7 @@ export default async ({ artifacts, packageJSON, forgeConfig, authToken, tag }) =
     throw 'In order to publish to github you must set the "github_repository.owner" and "github_repository.name" properties in your forge config. See the docs for more info'; // eslint-disable-line
   }
 
-  const github = new GitHub(authToken, true);
+  const github = new GitHub(authToken, true, forgeConfig.github_repository.options);
 
   let release;
   await asyncOra('Searching for target release', async () => {
diff --git a/src/util/github.js b/src/util/github.js
index 6ba7f8382..c50813aff 100644
--- a/src/util/github.js
+++ b/src/util/github.js
@@ -1,7 +1,13 @@
 import GitHubAPI from '@octokit/rest';
+import merge from 'lodash.merge';
 
 export default class GitHub {
-  constructor(authToken, requireAuth) {
+  constructor(authToken, requireAuth, options = {}) {
+    this.options = merge(
+      { protocol: 'https' },
+      options,
+      { headers: { 'user-agent': 'Electron Forge' } }
+    );
     if (authToken) {
       this.token = authToken;
     } else if (process.env.GITHUB_TOKEN) {
@@ -12,12 +18,7 @@ export default class GitHub {
   }
 
   getGitHub() {
-    const github = new GitHubAPI({
-      protocol: 'https',
-      headers: {
-        'user-agent': 'Electron Forge',
-      },
-    });
+    const github = new GitHubAPI(this.options);
     if (this.token) {
       github.authenticate({
         type: 'token',


Test patch:
diff --git a/test/fast/github_spec.js b/test/fast/github_spec.js
index a2e5bd8c5..71fc80ab3 100644
--- a/test/fast/github_spec.js
+++ b/test/fast/github_spec.js
@@ -12,8 +12,9 @@ describe('GitHub', () => {
     gitHubSpy = sinon.spy();
     gitHubAuthSpy = sinon.spy();
     MockGitHub = class {
-      constructor() {
+      constructor(options) {
         gitHubSpy();
+        this.options = options;
       }
 
       authenticate() {
@@ -43,6 +44,32 @@ describe('GitHub', () => {
       expect(gitHubSpy.callCount).to.equal(1);
     });
 
+    it('should be able to set the Enterprise URL settings', () => {
+      const gh = new GitHub('1234', true, {
+        host: 'github.example.com',
+        port: 8443,
+        pathPrefix: '/enterprise',
+      });
+      const api = gh.getGitHub();
+
+      expect(api.options).to.deep.equal({
+        protocol: 'https',
+        host: 'github.example.com',
+        port: 8443,
+        pathPrefix: '/enterprise',
+        headers: {
+          'user-agent': 'Electron Forge',
+        },
+      });
+    });
+
+    it('should not override the user agent', () => {
+      const gh = new GitHub('1234', true, { headers: { 'user-agent': 'Something' } });
+      const api = gh.getGitHub();
+
+      expect(api.options.headers['user-agent']).to.equal('Electron Forge');
+    });
+
     it('should authenticate if a token is present', () => {
       const gh = new GitHub('token');
       expect(gitHubAuthSpy.callCount).to.equal(0);