From 00a3be89340a3ce8d704f82f44a5e7f9e3a84dfe Mon Sep 17 00:00:00 2001
From: eric sciple <ericsciple@users.noreply.github.com>
Date: Tue, 16 Jun 2020 13:41:01 -0400
Subject: [PATCH] determine default branch (#278)

---
 README.md                     |  2 +-
 __test__/input-helper.test.ts |  7 -------
 action.yml                    |  2 +-
 dist/index.js                 | 36 +++++++++++++++++++++++++++++++----
 src/git-source-provider.ts    | 11 +++++++++++
 src/github-api-helper.ts      | 32 +++++++++++++++++++++++++++++++
 src/input-helper.ts           |  6 +-----
 7 files changed, 78 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index 9104f8b..f647b6e 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous
 
     # The branch, tag or SHA to checkout. When checking out the repository that
     # triggered a workflow, this defaults to the reference or SHA for that event.
-    # Otherwise, defaults to `master`.
+    # Otherwise, uses the default branch.
     ref: ''
 
     # Personal access token (PAT) used to fetch the repository. The PAT is configured
diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts
index 00732ef..920bc8e 100644
--- a/__test__/input-helper.test.ts
+++ b/__test__/input-helper.test.ts
@@ -110,13 +110,6 @@ describe('input-helper tests', () => {
     )
   })
 
-  it('sets correct default ref/sha for other repo', () => {
-    inputs.repository = 'some-owner/some-other-repo'
-    const settings: IGitSourceSettings = inputHelper.getInputs()
-    expect(settings.ref).toBe('refs/heads/master')
-    expect(settings.commit).toBeFalsy()
-  })
-
   it('sets ref to empty when explicit sha', () => {
     inputs.ref = '1111111111222222222233333333334444444444'
     const settings: IGitSourceSettings = inputHelper.getInputs()
diff --git a/action.yml b/action.yml
index 58e11b7..71655da 100644
--- a/action.yml
+++ b/action.yml
@@ -8,7 +8,7 @@ inputs:
     description: >
       The branch, tag or SHA to checkout. When checking out the repository that
       triggered a workflow, this defaults to the reference or SHA for that
-      event.  Otherwise, defaults to `master`.
+      event.  Otherwise, uses the default branch.
   token:
     description: >
       Personal access token (PAT) used to fetch the repository. The PAT is configured
diff --git a/dist/index.js b/dist/index.js
index 0c78d25..4ade91c 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -6114,6 +6114,12 @@ function getSource(settings) {
         // Repository URL
         core.info(`Syncing repository: ${settings.repositoryOwner}/${settings.repositoryName}`);
         const repositoryUrl = urlHelper.getFetchUrl(settings);
+        // Determine the default branch
+        if (!settings.ref && !settings.commit) {
+            core.startGroup('Determining the default branch');
+            settings.ref = yield githubApiHelper.getDefaultBranch(settings.authToken, settings.repositoryOwner, settings.repositoryName);
+            core.endGroup();
+        }
         // Remove conflicting file path
         if (fsHelper.fileExistsSync(settings.repositoryPath)) {
             yield io.rmRF(settings.repositoryPath);
@@ -9569,6 +9575,31 @@ function downloadRepository(authToken, owner, repo, ref, commit, repositoryPath)
     });
 }
 exports.downloadRepository = downloadRepository;
+/**
+ * Looks up the default branch name
+ */
+function getDefaultBranch(authToken, owner, repo) {
+    return __awaiter(this, void 0, void 0, function* () {
+        return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
+            core.info('Retrieving the default branch name');
+            const octokit = new github.GitHub(authToken);
+            const response = yield octokit.repos.get({ owner, repo });
+            if (response.status != 200) {
+                throw new Error(`Unexpected response from GitHub API. Status: ${response.status}, Data: ${response.data}`);
+            }
+            // Print the default branch
+            let result = response.data.default_branch;
+            core.info(`Default branch '${result}'`);
+            assert.ok(result, 'default_branch cannot be empty');
+            // Prefix with 'refs/heads'
+            if (!result.startsWith('refs/')) {
+                result = `refs/heads/${result}`;
+            }
+            return result;
+        }));
+    });
+}
+exports.getDefaultBranch = getDefaultBranch;
 function downloadArchive(authToken, owner, repo, ref, commit) {
     return __awaiter(this, void 0, void 0, function* () {
         const octokit = new github.GitHub(authToken);
@@ -14471,9 +14502,6 @@ function getInputs() {
                 result.ref = `refs/heads/${result.ref}`;
             }
         }
-        if (!result.ref && !result.commit) {
-            result.ref = 'refs/heads/master';
-        }
     }
     // SHA?
     else if (result.ref.match(/^[0-9a-fA-F]{40}$/)) {
@@ -14508,7 +14536,7 @@ function getInputs() {
     core.debug(`submodules = ${result.submodules}`);
     core.debug(`recursive submodules = ${result.nestedSubmodules}`);
     // Auth token
-    result.authToken = core.getInput('token');
+    result.authToken = core.getInput('token', { required: true });
     // SSH
     result.sshKey = core.getInput('ssh-key');
     result.sshKnownHosts = core.getInput('ssh-known-hosts');
diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts
index 89c16b5..25fba04 100644
--- a/src/git-source-provider.ts
+++ b/src/git-source-provider.ts
@@ -19,6 +19,17 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
   )
   const repositoryUrl = urlHelper.getFetchUrl(settings)
 
+  // Determine the default branch
+  if (!settings.ref && !settings.commit) {
+    core.startGroup('Determining the default branch')
+    settings.ref = await githubApiHelper.getDefaultBranch(
+      settings.authToken,
+      settings.repositoryOwner,
+      settings.repositoryName
+    )
+    core.endGroup()
+  }
+
   // Remove conflicting file path
   if (fsHelper.fileExistsSync(settings.repositoryPath)) {
     await io.rmRF(settings.repositoryPath)
diff --git a/src/github-api-helper.ts b/src/github-api-helper.ts
index e559c45..7a09638 100644
--- a/src/github-api-helper.ts
+++ b/src/github-api-helper.ts
@@ -67,6 +67,38 @@ export async function downloadRepository(
   io.rmRF(extractPath)
 }
 
+/**
+ * Looks up the default branch name
+ */
+export async function getDefaultBranch(
+  authToken: string,
+  owner: string,
+  repo: string
+): Promise<string> {
+  return await retryHelper.execute(async () => {
+    core.info('Retrieving the default branch name')
+    const octokit = new github.GitHub(authToken)
+    const response = await octokit.repos.get({owner, repo})
+    if (response.status != 200) {
+      throw new Error(
+        `Unexpected response from GitHub API. Status: ${response.status}, Data: ${response.data}`
+      )
+    }
+
+    // Print the default branch
+    let result = response.data.default_branch
+    core.info(`Default branch '${result}'`)
+    assert.ok(result, 'default_branch cannot be empty')
+
+    // Prefix with 'refs/heads'
+    if (!result.startsWith('refs/')) {
+      result = `refs/heads/${result}`
+    }
+
+    return result
+  })
+}
+
 async function downloadArchive(
   authToken: string,
   owner: string,
diff --git a/src/input-helper.ts b/src/input-helper.ts
index 11a1ab6..eabb9e0 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -68,10 +68,6 @@ export function getInputs(): IGitSourceSettings {
         result.ref = `refs/heads/${result.ref}`
       }
     }
-
-    if (!result.ref && !result.commit) {
-      result.ref = 'refs/heads/master'
-    }
   }
   // SHA?
   else if (result.ref.match(/^[0-9a-fA-F]{40}$/)) {
@@ -110,7 +106,7 @@ export function getInputs(): IGitSourceSettings {
   core.debug(`recursive submodules = ${result.nestedSubmodules}`)
 
   // Auth token
-  result.authToken = core.getInput('token')
+  result.authToken = core.getInput('token', {required: true})
 
   // SSH
   result.sshKey = core.getInput('ssh-key')