Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

determine default branch #278

Merged
merged 1 commit into from Jun 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -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
Expand Down
7 changes: 0 additions & 7 deletions __test__/input-helper.test.ts
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Expand Up @@ -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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we update this to have required: true?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not required that the user enter a value. It has a default.

description: >
Personal access token (PAT) used to fetch the repository. The PAT is configured
Expand Down
36 changes: 32 additions & 4 deletions dist/index.js
Expand Up @@ -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);
Expand Down Expand Up @@ -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 });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericsciple We are using this action on our repository's .wiki repo, and our respective action has been failing recently as the API returns "Not Found" for those. Could this be an oversight here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the heads up! And sorry for the disruption :(

I will look into the scenario shortly...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Fortunately was an easy fix on our end :)

Is it even possible to change the wiki default branch name? If not, maybe for those repositories the old hard-coded "logic" could be maintained for now.

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);
Expand Down Expand Up @@ -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}$/)) {
Expand Down Expand Up @@ -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');
Expand Down
11 changes: 11 additions & 0 deletions src/git-source-provider.ts
Expand Up @@ -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)
Expand Down
32 changes: 32 additions & 0 deletions src/github-api-helper.ts
Expand Up @@ -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,
Expand Down
6 changes: 1 addition & 5 deletions src/input-helper.ts
Expand Up @@ -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}$/)) {
Expand Down Expand Up @@ -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})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a breaking change? Does the action need a token if checking out a public repo?

If we're making this required, we should update the action.yml file with required: true for this input as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Today it already needs a token but fails with a bad error #221

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally it doesnt need to be specified, because the default value works.

However we've seen cases where it's empty:

  • Folks have set it to ''
  • Due to fork PR a secret doesnt get mapped in

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's empty, can I still checkout from a public repo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No today it fails like this:

/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +559278e5d4074a5495dceca4d32edaa1acc01724:refs/remotes/origin/master
##[error]fatal: could not read Username for 'https://github.com': terminal prompts disabled


// SSH
result.sshKey = core.getInput('ssh-key')
Expand Down