Compare commits

...

7 Commits

Author SHA1 Message Date
Peter Evans
2b011faafd fix: add check for missing token input (#1324) 2022-11-28 16:10:24 +09:00
Peter Evans
331d02c7e2 fix: support github server url for pushing to fork (#1318)
* feat: support github server url for pushing to fork (#1315)

Co-authored-by: Kevin Zhu <kevin.zhu@sap.com>

* fix: code formatting

* test: fix tests for getRemoteUrl

Co-authored-by: MildC <kevin.xizhu@gmail.com>
Co-authored-by: Kevin Zhu <kevin.zhu@sap.com>
2022-11-24 11:52:04 +09:00
Peter Evans
d7db273d6c fix: handle update after force pushing base to a new commit (#1307) 2022-11-22 10:42:29 +09:00
Peter Evans
ee93d78b55 test: set default branch to main (#1310) 2022-11-11 16:15:15 +09:00
Peter Evans
6c704eb7a8 docs: clarify limitations of push-to-fork with restricted token 2022-10-24 14:29:43 +09:00
Peter Evans
88bf0de51c docs: correct examples 2022-10-21 14:01:58 +09:00
Peter Evans
b38e8b0abe docs: replace set-output in example 2022-10-18 17:01:36 +09:00
9 changed files with 261 additions and 46 deletions

View File

@@ -14,7 +14,7 @@ const REMOTE_NAME = 'origin'
const TRACKED_FILE = 'a/tracked-file.txt' const TRACKED_FILE = 'a/tracked-file.txt'
const UNTRACKED_FILE = 'b/untracked-file.txt' const UNTRACKED_FILE = 'b/untracked-file.txt'
const DEFAULT_BRANCH = 'tests/master' const DEFAULT_BRANCH = 'tests/main'
const NOT_BASE_BRANCH = 'tests/branch-that-is-not-the-base' const NOT_BASE_BRANCH = 'tests/branch-that-is-not-the-base'
const NOT_EXIST_BRANCH = 'tests/branch-that-does-not-exist' const NOT_EXIST_BRANCH = 'tests/branch-that-does-not-exist'
@@ -108,10 +108,10 @@ describe('create-or-update-branch tests', () => {
// Check there are no local changes that might be destroyed by running these tests // Check there are no local changes that might be destroyed by running these tests
expect(await git.isDirty(true)).toBeFalsy() expect(await git.isDirty(true)).toBeFalsy()
// Fetch the default branch // Fetch the default branch
await git.fetch(['master:refs/remotes/origin/master']) await git.fetch(['main:refs/remotes/origin/main'])
// Create a "not base branch" for the test run // Create a "not base branch" for the test run
await git.checkout('master') await git.checkout('main')
await git.checkout(NOT_BASE_BRANCH, 'HEAD') await git.checkout(NOT_BASE_BRANCH, 'HEAD')
await createFile(TRACKED_FILE) await createFile(TRACKED_FILE)
await git.exec(['add', '-A']) await git.exec(['add', '-A'])
@@ -123,7 +123,7 @@ describe('create-or-update-branch tests', () => {
]) ])
// Create a new default branch for the test run with a tracked file // Create a new default branch for the test run with a tracked file
await git.checkout('master') await git.checkout('main')
await git.checkout(DEFAULT_BRANCH, 'HEAD') await git.checkout(DEFAULT_BRANCH, 'HEAD')
await createFile(TRACKED_FILE) await createFile(TRACKED_FILE)
await git.exec(['add', '-A']) await git.exec(['add', '-A'])
@@ -631,6 +631,69 @@ describe('create-or-update-branch tests', () => {
).toBeTruthy() ).toBeTruthy()
}) })
it('tests create, force push of base branch, and update with identical changes', async () => {
// If the base branch is force pushed to a different commit when there is an open
// pull request, the branch must be reset to rebase the changes on the base.
// Create tracked and untracked file changes
const changes = await createChanges()
const commitMessage = uuidv4()
const result = await createOrUpdateBranch(
git,
commitMessage,
'',
BRANCH,
REMOTE_NAME,
false,
ADD_PATHS_DEFAULT
)
expect(result.action).toEqual('created')
expect(await getFileContent(TRACKED_FILE)).toEqual(changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(changes.untracked)
expect(
await gitLogMatches([commitMessage, INIT_COMMIT_MESSAGE])
).toBeTruthy()
// Push pull request branch to remote
await git.push([
'--force-with-lease',
REMOTE_NAME,
`HEAD:refs/heads/${BRANCH}`
])
await afterTest(false)
await beforeTest()
// Force push the base branch to a different commit
const amendedCommitMessage = uuidv4()
await git.commit(['--amend', '-m', amendedCommitMessage])
await git.push([
'--force',
REMOTE_NAME,
`HEAD:refs/heads/${DEFAULT_BRANCH}`
])
// Create the same tracked and untracked file changes (no change on update)
const _changes = await createChanges(changes.tracked, changes.untracked)
const _commitMessage = uuidv4()
const _result = await createOrUpdateBranch(
git,
_commitMessage,
'',
BRANCH,
REMOTE_NAME,
false,
ADD_PATHS_DEFAULT
)
expect(_result.action).toEqual('updated')
expect(_result.hasDiffWithBase).toBeTruthy()
expect(await getFileContent(TRACKED_FILE)).toEqual(_changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(_changes.untracked)
expect(
await gitLogMatches([_commitMessage, amendedCommitMessage])
).toBeTruthy()
})
it('tests create and update with commits on the working base (during the workflow)', async () => { it('tests create and update with commits on the working base (during the workflow)', async () => {
// Create commits on the working base // Create commits on the working base
const commits = await createCommits(git) const commits = await createCommits(git)
@@ -1519,6 +1582,75 @@ describe('create-or-update-branch tests', () => {
).toBeTruthy() ).toBeTruthy()
}) })
it('tests create, force push of base branch, and update with identical changes (WBNB)', async () => {
// If the base branch is force pushed to a different commit when there is an open
// pull request, the branch must be reset to rebase the changes on the base.
// Set the working base to a branch that is not the pull request base
await git.checkout(NOT_BASE_BRANCH)
// Create tracked and untracked file changes
const changes = await createChanges()
const commitMessage = uuidv4()
const result = await createOrUpdateBranch(
git,
commitMessage,
BASE,
BRANCH,
REMOTE_NAME,
false,
ADD_PATHS_DEFAULT
)
expect(result.action).toEqual('created')
expect(await getFileContent(TRACKED_FILE)).toEqual(changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(changes.untracked)
expect(
await gitLogMatches([commitMessage, INIT_COMMIT_MESSAGE])
).toBeTruthy()
// Push pull request branch to remote
await git.push([
'--force-with-lease',
REMOTE_NAME,
`HEAD:refs/heads/${BRANCH}`
])
await afterTest(false)
await beforeTest()
// Force push the base branch to a different commit
const amendedCommitMessage = uuidv4()
await git.commit(['--amend', '-m', amendedCommitMessage])
await git.push([
'--force',
REMOTE_NAME,
`HEAD:refs/heads/${DEFAULT_BRANCH}`
])
// Set the working base to a branch that is not the pull request base
await git.checkout(NOT_BASE_BRANCH)
// Create the same tracked and untracked file changes (no change on update)
const _changes = await createChanges(changes.tracked, changes.untracked)
const _commitMessage = uuidv4()
const _result = await createOrUpdateBranch(
git,
_commitMessage,
BASE,
BRANCH,
REMOTE_NAME,
false,
ADD_PATHS_DEFAULT
)
expect(_result.action).toEqual('updated')
expect(_result.hasDiffWithBase).toBeTruthy()
expect(await getFileContent(TRACKED_FILE)).toEqual(_changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(_changes.untracked)
expect(
await gitLogMatches([_commitMessage, amendedCommitMessage])
).toBeTruthy()
})
it('tests create and update with commits on the working base (during the workflow) (WBNB)', async () => { it('tests create and update with commits on the working base (during the workflow) (WBNB)', async () => {
// Set the working base to a branch that is not the pull request base // Set the working base to a branch that is not the pull request base
await git.checkout(NOT_BASE_BRANCH) await git.checkout(NOT_BASE_BRANCH)

View File

@@ -6,6 +6,7 @@ WORKINGDIR=$PWD
# Create and serve a remote repo # Create and serve a remote repo
mkdir -p /git/remote mkdir -p /git/remote
git config --global init.defaultBranch main
git init --bare /git/remote/test-base.git git init --bare /git/remote/test-base.git
git daemon --verbose --enable=receive-pack --base-path=/git/remote --export-all /git/remote &>/dev/null & git daemon --verbose --enable=receive-pack --base-path=/git/remote --export-all /git/remote &>/dev/null &

View File

@@ -90,11 +90,28 @@ describe('utils tests', () => {
}) })
test('getRemoteUrl successfully returns remote URLs', async () => { test('getRemoteUrl successfully returns remote URLs', async () => {
const url1 = utils.getRemoteUrl('HTTPS', 'peter-evans/create-pull-request') const url1 = utils.getRemoteUrl(
'HTTPS',
'github.com',
'peter-evans/create-pull-request'
)
expect(url1).toEqual('https://github.com/peter-evans/create-pull-request') expect(url1).toEqual('https://github.com/peter-evans/create-pull-request')
const url2 = utils.getRemoteUrl('SSH', 'peter-evans/create-pull-request') const url2 = utils.getRemoteUrl(
'SSH',
'github.com',
'peter-evans/create-pull-request'
)
expect(url2).toEqual('git@github.com:peter-evans/create-pull-request.git') expect(url2).toEqual('git@github.com:peter-evans/create-pull-request.git')
const url3 = utils.getRemoteUrl(
'HTTPS',
'mygithubserver.com',
'peter-evans/create-pull-request'
)
expect(url3).toEqual(
'https://mygithubserver.com/peter-evans/create-pull-request'
)
}) })
test('secondsSinceEpoch returns the number of seconds since the Epoch', async () => { test('secondsSinceEpoch returns the number of seconds since the Epoch', async () => {

47
dist/index.js vendored
View File

@@ -74,18 +74,30 @@ function tryFetch(git, remote, branch) {
}); });
} }
exports.tryFetch = tryFetch; exports.tryFetch = tryFetch;
// Return the number of commits that branch2 is ahead of branch1
function commitsAhead(git, branch1, branch2) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield git.revList([`${branch1}...${branch2}`], ['--right-only', '--count']);
return Number(result);
});
}
// Return true if branch2 is ahead of branch1 // Return true if branch2 is ahead of branch1
function isAhead(git, branch1, branch2) { function isAhead(git, branch1, branch2) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const result = yield git.revList([`${branch1}...${branch2}`], ['--right-only', '--count']); return (yield commitsAhead(git, branch1, branch2)) > 0;
return Number(result) > 0; });
}
// Return the number of commits that branch2 is behind branch1
function commitsBehind(git, branch1, branch2) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield git.revList([`${branch1}...${branch2}`], ['--left-only', '--count']);
return Number(result);
}); });
} }
// Return true if branch2 is behind branch1 // Return true if branch2 is behind branch1
function isBehind(git, branch1, branch2) { function isBehind(git, branch1, branch2) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const result = yield git.revList([`${branch1}...${branch2}`], ['--left-only', '--count']); return (yield commitsBehind(git, branch1, branch2)) > 0;
return Number(result) > 0;
}); });
} }
// Return true if branch2 is even with branch1 // Return true if branch2 is even with branch1
@@ -214,9 +226,16 @@ function createOrUpdateBranch(git, commitMessage, base, branch, branchRemoteName
// branches after merging. In particular, it catches a case where the branch was // branches after merging. In particular, it catches a case where the branch was
// squash merged but not deleted. We need to reset to make sure it doesn't appear // squash merged but not deleted. We need to reset to make sure it doesn't appear
// to have a diff with the base due to different commits for the same changes. // to have a diff with the base due to different commits for the same changes.
// - If the number of commits ahead of the base branch differs between the branch and
// temp branch. This catches a case where the base branch has been force pushed to
// a new commit.
// For changes on base this reset is equivalent to a rebase of the pull request branch. // For changes on base this reset is equivalent to a rebase of the pull request branch.
const tempBranchCommitsAhead = yield commitsAhead(git, base, tempBranch);
const branchCommitsAhead = yield commitsAhead(git, base, branch);
if ((yield git.hasDiff([`${branch}..${tempBranch}`])) || if ((yield git.hasDiff([`${branch}..${tempBranch}`])) ||
!(yield isAhead(git, base, tempBranch))) { branchCommitsAhead != tempBranchCommitsAhead ||
!(tempBranchCommitsAhead > 0) // !isAhead
) {
core.info(`Resetting '${branch}'`); core.info(`Resetting '${branch}'`);
// Alternatively, git switch -C branch tempBranch // Alternatively, git switch -C branch tempBranch
yield git.checkout(branch, tempBranch); yield git.checkout(branch, tempBranch);
@@ -292,6 +311,9 @@ function createPullRequest(inputs) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
let gitAuthHelper; let gitAuthHelper;
try { try {
if (!inputs.token) {
throw new Error(`Input 'token' not supplied. Unable to continue.`);
}
// Get the repository path // Get the repository path
const repoPath = utils.getRepoPath(inputs.path); const repoPath = utils.getRepoPath(inputs.path);
// Create a git command manager // Create a git command manager
@@ -320,7 +342,7 @@ function createPullRequest(inputs) {
throw new Error(`Repository '${branchRepository}' is not a fork of '${baseRemote.repository}'. Unable to continue.`); throw new Error(`Repository '${branchRepository}' is not a fork of '${baseRemote.repository}'. Unable to continue.`);
} }
// Add a remote for the fork // Add a remote for the fork
const remoteUrl = utils.getRemoteUrl(baseRemote.protocol, branchRepository); const remoteUrl = utils.getRemoteUrl(baseRemote.protocol, baseRemote.hostname, branchRepository);
yield git.exec(['remote', 'add', 'fork', remoteUrl]); yield git.exec(['remote', 'add', 'fork', remoteUrl]);
} }
core.endGroup(); core.endGroup();
@@ -1228,11 +1250,13 @@ function getRemoteDetail(remoteUrl) {
if (!githubServerMatch) { if (!githubServerMatch) {
throw new Error('Could not parse GitHub Server name'); throw new Error('Could not parse GitHub Server name');
} }
const httpsUrlPattern = new RegExp('^https?://.*@?' + githubServerMatch[1] + '/(.+/.+?)(\\.git)?$', 'i'); const hostname = githubServerMatch[1];
const sshUrlPattern = new RegExp('^git@' + githubServerMatch[1] + ':(.+/.+)\\.git$', 'i'); const httpsUrlPattern = new RegExp('^https?://.*@?' + hostname + '/(.+/.+?)(\\.git)?$', 'i');
const sshUrlPattern = new RegExp('^git@' + hostname + ':(.+/.+)\\.git$', 'i');
const httpsMatch = remoteUrl.match(httpsUrlPattern); const httpsMatch = remoteUrl.match(httpsUrlPattern);
if (httpsMatch) { if (httpsMatch) {
return { return {
hostname,
protocol: 'HTTPS', protocol: 'HTTPS',
repository: httpsMatch[1] repository: httpsMatch[1]
}; };
@@ -1240,6 +1264,7 @@ function getRemoteDetail(remoteUrl) {
const sshMatch = remoteUrl.match(sshUrlPattern); const sshMatch = remoteUrl.match(sshUrlPattern);
if (sshMatch) { if (sshMatch) {
return { return {
hostname,
protocol: 'SSH', protocol: 'SSH',
repository: sshMatch[1] repository: sshMatch[1]
}; };
@@ -1247,10 +1272,10 @@ function getRemoteDetail(remoteUrl) {
throw new Error(`The format of '${remoteUrl}' is not a valid GitHub repository URL`); throw new Error(`The format of '${remoteUrl}' is not a valid GitHub repository URL`);
} }
exports.getRemoteDetail = getRemoteDetail; exports.getRemoteDetail = getRemoteDetail;
function getRemoteUrl(protocol, repository) { function getRemoteUrl(protocol, hostname, repository) {
return protocol == 'HTTPS' return protocol == 'HTTPS'
? `https://github.com/${repository}` ? `https://${hostname}/${repository}`
: `git@github.com:${repository}.git`; : `git@${hostname}:${repository}.git`;
} }
exports.getRemoteUrl = getRemoteUrl; exports.getRemoteUrl = getRemoteUrl;
function secondsSinceEpoch() { function secondsSinceEpoch() {

View File

@@ -214,8 +214,9 @@ How to use SSH (deploy keys) with create-pull-request action:
Instead of pushing pull request branches to the repository you want to update, you can push them to a fork of that repository. Instead of pushing pull request branches to the repository you want to update, you can push them to a fork of that repository.
This allows you to employ the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) by using a dedicated user acting as a [machine account](https://docs.github.com/en/github/site-policy/github-terms-of-service#3-account-requirements). This allows you to employ the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) by using a dedicated user acting as a [machine account](https://docs.github.com/en/github/site-policy/github-terms-of-service#3-account-requirements).
This user has no access to the main repository. This user only has `read` access to the main repository.
It will use their own fork to push code and create the pull request. It will use their own fork to push code and create the pull request.
Note that if you choose to use this method (not give the machine account `write` access to the repository) the following inputs cannot be used: `labels`, `assignees`, `reviewers`, `team-reviewers` and `milestone`.
1. Create a new GitHub user and login. 1. Create a new GitHub user and login.
2. Fork the repository that you will be creating pull requests in. 2. Fork the repository that you will be creating pull requests in.

View File

@@ -282,8 +282,10 @@ jobs:
- name: Get Latest Swagger UI Release - name: Get Latest Swagger UI Release
id: swagger-ui id: swagger-ui
run: | run: |
echo ::set-output name=release_tag::$(curl -sL https://api.github.com/repos/swagger-api/swagger-ui/releases/latest | jq -r ".tag_name") release_tag=$(curl -sL https://api.github.com/repos/swagger-api/swagger-ui/releases/latest | jq -r ".tag_name")
echo ::set-output name=current_tag::$(<swagger-ui.version) echo "release_tag=$release_tag" >> $GITHUB_OUTPUT
current_tag=$(<swagger-ui.version)
echo "current_tag=$current_tag" >> $GITHUB_OUTPUT
- name: Update Swagger UI - name: Update Swagger UI
if: steps.swagger-ui.outputs.current_tag != steps.swagger-ui.outputs.release_tag if: steps.swagger-ui.outputs.current_tag != steps.swagger-ui.outputs.release_tag
env: env:
@@ -475,7 +477,9 @@ jobs:
args: --exit-code --recursive --in-place --aggressive --aggressive . args: --exit-code --recursive --in-place --aggressive --aggressive .
- name: Set autopep8 branch name - name: Set autopep8 branch name
id: vars id: vars
run: echo ::set-output name=branch-name::"autopep8-patches/${{ github.head_ref }}" run: |
branch-name="autopep8-patches/${{ github.head_ref }}"
echo "branch-name=$branch-name" >> $GITHUB_OUTPUT
- name: Create Pull Request - name: Create Pull Request
if: steps.autopep8.outputs.exit-code == 2 if: steps.autopep8.outputs.exit-code == 2
uses: peter-evans/create-pull-request@v4 uses: peter-evans/create-pull-request@v4
@@ -525,16 +529,17 @@ jobs:
### Dynamic configuration using variables ### Dynamic configuration using variables
The following examples show how configuration for the action can be dynamically defined in a previous workflow step. The following examples show how configuration for the action can be dynamically defined in a previous workflow step.
Note that the step where output variables are defined must have an id.
The recommended method is to use [`set-output`](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter). Note that the step where output variables are defined must have an id.
```yml ```yml
- name: Set output variables - name: Set output variables
id: vars id: vars
run: | run: |
echo ::set-output name=pr_title::"[Test] Add report file $(date +%d-%m-%Y)" pr_title="[Test] Add report file $(date +%d-%m-%Y)"
echo ::set-output name=pr_body::"This PR was auto-generated on $(date +%d-%m-%Y) \ pr_body="This PR was auto-generated on $(date +%d-%m-%Y) \
by [create-pull-request](https://github.com/peter-evans/create-pull-request)." by [create-pull-request](https://github.com/peter-evans/create-pull-request)."
echo "pr_title=$pr_title" >> $GITHUB_OUTPUT
echo "pr_body=$pr_body" >> $GITHUB_OUTPUT
- name: Create Pull Request - name: Create Pull Request
uses: peter-evans/create-pull-request@v4 uses: peter-evans/create-pull-request@v4
with: with:
@@ -545,16 +550,15 @@ The recommended method is to use [`set-output`](https://docs.github.com/en/actio
### Setting the pull request body from a file ### Setting the pull request body from a file
This example shows how file content can be read into a variable and passed to the action. This example shows how file content can be read into a variable and passed to the action.
The content must be [escaped to preserve newlines](https://github.community/t/set-output-truncates-multiline-strings/16852/3).
```yml ```yml
- id: get-pr-body - id: get-pr-body
run: | run: |
body=$(cat pr-body.txt) body=$(cat pr-body.txt)
body="${body//'%'/'%25'}" delimiter="$(openssl rand -hex 8)"
body="${body//$'\n'/'%0A'}" echo "body<<$delimiter" >> $GITHUB_OUTPUT
body="${body//$'\r'/'%0D'}" echo "$body" >> $GITHUB_OUTPUT
echo ::set-output name=body::$body echo "$delimiter" >> $GITHUB_OUTPUT
- name: Create Pull Request - name: Create Pull Request
uses: peter-evans/create-pull-request@v4 uses: peter-evans/create-pull-request@v4

View File

@@ -43,17 +43,39 @@ export async function tryFetch(
} }
} }
// Return the number of commits that branch2 is ahead of branch1
async function commitsAhead(
git: GitCommandManager,
branch1: string,
branch2: string
): Promise<number> {
const result = await git.revList(
[`${branch1}...${branch2}`],
['--right-only', '--count']
)
return Number(result)
}
// Return true if branch2 is ahead of branch1 // Return true if branch2 is ahead of branch1
async function isAhead( async function isAhead(
git: GitCommandManager, git: GitCommandManager,
branch1: string, branch1: string,
branch2: string branch2: string
): Promise<boolean> { ): Promise<boolean> {
return (await commitsAhead(git, branch1, branch2)) > 0
}
// Return the number of commits that branch2 is behind branch1
async function commitsBehind(
git: GitCommandManager,
branch1: string,
branch2: string
): Promise<number> {
const result = await git.revList( const result = await git.revList(
[`${branch1}...${branch2}`], [`${branch1}...${branch2}`],
['--right-only', '--count'] ['--left-only', '--count']
) )
return Number(result) > 0 return Number(result)
} }
// Return true if branch2 is behind branch1 // Return true if branch2 is behind branch1
@@ -62,11 +84,7 @@ async function isBehind(
branch1: string, branch1: string,
branch2: string branch2: string
): Promise<boolean> { ): Promise<boolean> {
const result = await git.revList( return (await commitsBehind(git, branch1, branch2)) > 0
[`${branch1}...${branch2}`],
['--left-only', '--count']
)
return Number(result) > 0
} }
// Return true if branch2 is even with branch1 // Return true if branch2 is even with branch1
@@ -226,10 +244,16 @@ export async function createOrUpdateBranch(
// branches after merging. In particular, it catches a case where the branch was // branches after merging. In particular, it catches a case where the branch was
// squash merged but not deleted. We need to reset to make sure it doesn't appear // squash merged but not deleted. We need to reset to make sure it doesn't appear
// to have a diff with the base due to different commits for the same changes. // to have a diff with the base due to different commits for the same changes.
// - If the number of commits ahead of the base branch differs between the branch and
// temp branch. This catches a case where the base branch has been force pushed to
// a new commit.
// For changes on base this reset is equivalent to a rebase of the pull request branch. // For changes on base this reset is equivalent to a rebase of the pull request branch.
const tempBranchCommitsAhead = await commitsAhead(git, base, tempBranch)
const branchCommitsAhead = await commitsAhead(git, base, branch)
if ( if (
(await git.hasDiff([`${branch}..${tempBranch}`])) || (await git.hasDiff([`${branch}..${tempBranch}`])) ||
!(await isAhead(git, base, tempBranch)) branchCommitsAhead != tempBranchCommitsAhead ||
!(tempBranchCommitsAhead > 0) // !isAhead
) { ) {
core.info(`Resetting '${branch}'`) core.info(`Resetting '${branch}'`)
// Alternatively, git switch -C branch tempBranch // Alternatively, git switch -C branch tempBranch

View File

@@ -35,6 +35,10 @@ export interface Inputs {
export async function createPullRequest(inputs: Inputs): Promise<void> { export async function createPullRequest(inputs: Inputs): Promise<void> {
let gitAuthHelper let gitAuthHelper
try { try {
if (!inputs.token) {
throw new Error(`Input 'token' not supplied. Unable to continue.`)
}
// Get the repository path // Get the repository path
const repoPath = utils.getRepoPath(inputs.path) const repoPath = utils.getRepoPath(inputs.path)
// Create a git command manager // Create a git command manager
@@ -74,6 +78,7 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
// Add a remote for the fork // Add a remote for the fork
const remoteUrl = utils.getRemoteUrl( const remoteUrl = utils.getRemoteUrl(
baseRemote.protocol, baseRemote.protocol,
baseRemote.hostname,
branchRepository branchRepository
) )
await git.exec(['remote', 'add', 'fork', remoteUrl]) await git.exec(['remote', 'add', 'fork', remoteUrl])

View File

@@ -32,6 +32,7 @@ export function getRepoPath(relativePath?: string): string {
} }
interface RemoteDetail { interface RemoteDetail {
hostname: string
protocol: string protocol: string
repository: string repository: string
} }
@@ -46,18 +47,18 @@ export function getRemoteDetail(remoteUrl: string): RemoteDetail {
throw new Error('Could not parse GitHub Server name') throw new Error('Could not parse GitHub Server name')
} }
const hostname = githubServerMatch[1]
const httpsUrlPattern = new RegExp( const httpsUrlPattern = new RegExp(
'^https?://.*@?' + githubServerMatch[1] + '/(.+/.+?)(\\.git)?$', '^https?://.*@?' + hostname + '/(.+/.+?)(\\.git)?$',
'i'
)
const sshUrlPattern = new RegExp(
'^git@' + githubServerMatch[1] + ':(.+/.+)\\.git$',
'i' 'i'
) )
const sshUrlPattern = new RegExp('^git@' + hostname + ':(.+/.+)\\.git$', 'i')
const httpsMatch = remoteUrl.match(httpsUrlPattern) const httpsMatch = remoteUrl.match(httpsUrlPattern)
if (httpsMatch) { if (httpsMatch) {
return { return {
hostname,
protocol: 'HTTPS', protocol: 'HTTPS',
repository: httpsMatch[1] repository: httpsMatch[1]
} }
@@ -66,6 +67,7 @@ export function getRemoteDetail(remoteUrl: string): RemoteDetail {
const sshMatch = remoteUrl.match(sshUrlPattern) const sshMatch = remoteUrl.match(sshUrlPattern)
if (sshMatch) { if (sshMatch) {
return { return {
hostname,
protocol: 'SSH', protocol: 'SSH',
repository: sshMatch[1] repository: sshMatch[1]
} }
@@ -76,10 +78,14 @@ export function getRemoteDetail(remoteUrl: string): RemoteDetail {
) )
} }
export function getRemoteUrl(protocol: string, repository: string): string { export function getRemoteUrl(
protocol: string,
hostname: string,
repository: string
): string {
return protocol == 'HTTPS' return protocol == 'HTTPS'
? `https://github.com/${repository}` ? `https://${hostname}/${repository}`
: `git@github.com:${repository}.git` : `git@${hostname}:${repository}.git`
} }
export function secondsSinceEpoch(): number { export function secondsSinceEpoch(): number {