* feat: update author and committer input defaults

* Update github-actions[bot]

* Update author to new email format

* feat: optional input for git ops token

* feat: allow push-to-fork to push to sibling repos (#2414)

Fixes #2412.

* build: update dist

* feat: update action runtime to node 20 (#2340)

* feat: add truncate warning to pull request body

* perf: unshallow only when necessary

* fix: remove the remote for the fork on completion

* feat: infer github server and api urls

* test: integration test fixes

* build: bump major version

* docs: update to v6

---------

Co-authored-by: Teko <112829523+Teko012@users.noreply.github.com>
Co-authored-by: Benjamin Gilbert <bgilbert@backtick.net>
This commit is contained in:
Peter Evans 2024-01-31 20:05:33 +09:00
parent bb809027fd
commit b1ddad2c99
24 changed files with 620 additions and 491 deletions

View file

@ -8,7 +8,7 @@ import {GitCommandManager} from '../lib/git-command-manager'
import * as path from 'path'
import {v4 as uuidv4} from 'uuid'
const REPO_PATH = '/git/local/test-base'
const REPO_PATH = '/git/local/repos/test-base'
const REMOTE_NAME = 'origin'
const TRACKED_FILE = 'a/tracked-file.txt'
@ -22,7 +22,7 @@ const INIT_COMMIT_MESSAGE = 'Add file to be a tracked file for tests'
const BRANCH = 'tests/create-pull-request/patch'
const BASE = DEFAULT_BRANCH
const FORK_REMOTE_URL = 'git://127.0.0.1/test-fork.git'
const FORK_REMOTE_URL = 'git://127.0.0.1/repos/test-fork.git'
const FORK_REMOTE_NAME = 'fork'
const ADD_PATHS_DEFAULT = []

View file

@ -5,18 +5,18 @@ set -euo pipefail
WORKINGDIR=$PWD
# Create and serve a remote repo
mkdir -p /git/remote
mkdir -p /git/remote/repos
git config --global init.defaultBranch main
git init --bare /git/remote/test-base.git
git init --bare /git/remote/repos/test-base.git
git daemon --verbose --enable=receive-pack --base-path=/git/remote --export-all /git/remote &>/dev/null &
# Give the daemon time to start
sleep 2
# Create a local clone and make an initial commit
mkdir -p /git/local
git clone git://127.0.0.1/test-base.git /git/local/test-base
cd /git/local/test-base
mkdir -p /git/local/repos
git clone git://127.0.0.1/repos/test-base.git /git/local/repos/test-base
cd /git/local/repos/test-base
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
echo "#test-base" > README.md
@ -30,8 +30,8 @@ git config -l
# Clone a server-side fork of the base repo
cd $WORKINGDIR
git clone --mirror git://127.0.0.1/test-base.git /git/remote/test-fork.git
cd /git/remote/test-fork.git
git clone --mirror git://127.0.0.1/repos/test-base.git /git/remote/repos/test-fork.git
cd /git/remote/repos/test-fork.git
git log -1 --pretty=oneline
# Restore the working directory

View file

@ -1,32 +1,32 @@
import {GitCommandManager} from '../lib/git-command-manager'
import {GitAuthHelper} from '../lib/git-auth-helper'
import {GitConfigHelper} from '../lib/git-config-helper'
const REPO_PATH = '/git/local/test-base'
const REPO_PATH = '/git/local/repos/test-base'
const extraheaderConfigKey = 'http.https://github.com/.extraheader'
const extraheaderConfigKey = 'http.https://127.0.0.1/.extraheader'
describe('git-auth-helper tests', () => {
describe('git-config-helper integration tests', () => {
let git: GitCommandManager
let gitAuthHelper: GitAuthHelper
let gitConfigHelper: GitConfigHelper
beforeAll(async () => {
git = await GitCommandManager.create(REPO_PATH)
gitAuthHelper = new GitAuthHelper(git)
})
it('tests save and restore with no persisted auth', async () => {
await gitAuthHelper.savePersistedAuth()
await gitAuthHelper.restorePersistedAuth()
const gitConfigHelper = await GitConfigHelper.create(git)
await gitConfigHelper.close()
})
it('tests configure and removal of auth', async () => {
await gitAuthHelper.configureToken('github-token')
const gitConfigHelper = await GitConfigHelper.create(git)
await gitConfigHelper.configureToken('github-token')
expect(await git.configExists(extraheaderConfigKey)).toBeTruthy()
expect(await git.getConfigValue(extraheaderConfigKey)).toEqual(
'AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2l0aHViLXRva2Vu'
)
await gitAuthHelper.removeAuth()
await gitConfigHelper.close()
expect(await git.configExists(extraheaderConfigKey)).toBeFalsy()
})
@ -34,37 +34,53 @@ describe('git-auth-helper tests', () => {
const extraheaderConfigValue = 'AUTHORIZATION: basic ***persisted-auth***'
await git.config(extraheaderConfigKey, extraheaderConfigValue)
await gitAuthHelper.savePersistedAuth()
const gitConfigHelper = await GitConfigHelper.create(git)
const exists = await git.configExists(extraheaderConfigKey)
expect(exists).toBeFalsy()
await gitAuthHelper.restorePersistedAuth()
await gitConfigHelper.close()
const configValue = await git.getConfigValue(extraheaderConfigKey)
expect(configValue).toEqual(extraheaderConfigValue)
await gitAuthHelper.removeAuth()
const unset = await git.tryConfigUnset(
extraheaderConfigKey,
'^AUTHORIZATION:'
)
expect(unset).toBeTruthy()
})
it('tests not adding/removing the safe.directory config when it already exists', async () => {
await git.config('safe.directory', '/another-value', true, true)
const gitConfigHelper = await GitConfigHelper.create(git)
expect(
await git.configExists('safe.directory', '/another-value', true)
).toBeTruthy()
await gitConfigHelper.close()
const unset = await git.tryConfigUnset(
'safe.directory',
'/another-value',
true
)
expect(unset).toBeTruthy()
})
it('tests adding and removing the safe.directory config', async () => {
await git.config('safe.directory', '/another-value', true, true)
await gitAuthHelper.removeSafeDirectory()
await gitAuthHelper.addSafeDirectory()
const gitConfigHelper = await GitConfigHelper.create(git)
expect(
await git.configExists('safe.directory', REPO_PATH, true)
).toBeTruthy()
await gitAuthHelper.addSafeDirectory()
await gitAuthHelper.removeSafeDirectory()
await gitConfigHelper.close()
expect(
await git.configExists('safe.directory', REPO_PATH, true)
).toBeFalsy()
expect(
await git.configExists('safe.directory', '/another-value', true)
).toBeTruthy()
})
})

View file

@ -0,0 +1,93 @@
import {GitConfigHelper} from '../lib/git-config-helper'
describe('git-config-helper unit tests', () => {
test('parseGitRemote successfully parses HTTPS remote URLs', async () => {
const remote1 = GitConfigHelper.parseGitRemote(
'https://github.com/peter-evans/create-pull-request'
)
expect(remote1.hostname).toEqual('github.com')
expect(remote1.protocol).toEqual('HTTPS')
expect(remote1.repository).toEqual('peter-evans/create-pull-request')
const remote2 = GitConfigHelper.parseGitRemote(
'https://xxx:x-oauth-basic@github.com/peter-evans/create-pull-request'
)
expect(remote2.hostname).toEqual('github.com')
expect(remote2.protocol).toEqual('HTTPS')
expect(remote2.repository).toEqual('peter-evans/create-pull-request')
const remote3 = GitConfigHelper.parseGitRemote(
'https://github.com/peter-evans/create-pull-request.git'
)
expect(remote3.hostname).toEqual('github.com')
expect(remote3.protocol).toEqual('HTTPS')
expect(remote3.repository).toEqual('peter-evans/create-pull-request')
const remote4 = GitConfigHelper.parseGitRemote(
'https://github.com/peter-evans/ungit'
)
expect(remote4.hostname).toEqual('github.com')
expect(remote4.protocol).toEqual('HTTPS')
expect(remote4.repository).toEqual('peter-evans/ungit')
const remote5 = GitConfigHelper.parseGitRemote(
'https://github.com/peter-evans/ungit.git'
)
expect(remote5.hostname).toEqual('github.com')
expect(remote5.protocol).toEqual('HTTPS')
expect(remote5.repository).toEqual('peter-evans/ungit')
const remote6 = GitConfigHelper.parseGitRemote(
'https://github.internal.company/peter-evans/create-pull-request'
)
expect(remote6.hostname).toEqual('github.internal.company')
expect(remote6.protocol).toEqual('HTTPS')
expect(remote6.repository).toEqual('peter-evans/create-pull-request')
})
test('parseGitRemote successfully parses SSH remote URLs', async () => {
const remote1 = GitConfigHelper.parseGitRemote(
'git@github.com:peter-evans/create-pull-request.git'
)
expect(remote1.hostname).toEqual('github.com')
expect(remote1.protocol).toEqual('SSH')
expect(remote1.repository).toEqual('peter-evans/create-pull-request')
const remote2 = GitConfigHelper.parseGitRemote(
'git@github.com:peter-evans/ungit.git'
)
expect(remote2.hostname).toEqual('github.com')
expect(remote2.protocol).toEqual('SSH')
expect(remote2.repository).toEqual('peter-evans/ungit')
const remote3 = GitConfigHelper.parseGitRemote(
'git@github.internal.company:peter-evans/create-pull-request.git'
)
expect(remote3.hostname).toEqual('github.internal.company')
expect(remote3.protocol).toEqual('SSH')
expect(remote3.repository).toEqual('peter-evans/create-pull-request')
})
test('parseGitRemote successfully parses GIT remote URLs', async () => {
// Unauthenticated git protocol for integration tests only
const remote1 = GitConfigHelper.parseGitRemote(
'git://127.0.0.1/repos/test-base.git'
)
expect(remote1.hostname).toEqual('127.0.0.1')
expect(remote1.protocol).toEqual('GIT')
expect(remote1.repository).toEqual('repos/test-base')
})
test('parseGitRemote fails to parse a remote URL', async () => {
const remoteUrl = 'https://github.com/peter-evans'
try {
GitConfigHelper.parseGitRemote(remoteUrl)
// Fail the test if an error wasn't thrown
expect(true).toEqual(false)
} catch (e: any) {
expect(e.message).toEqual(
`The format of '${remoteUrl}' is not a valid GitHub repository URL`
)
}
})
})

View file

@ -8,7 +8,7 @@ if [[ "$(docker images -q $IMAGE 2> /dev/null)" == "" || $ARG1 == "build" ]]; th
echo "Building Docker image $IMAGE ..."
cat > Dockerfile << EOF
FROM node:16-alpine
FROM node:20-alpine
RUN apk --no-cache add git git-daemon
RUN npm install jest jest-environment-jsdom --global
WORKDIR /cpr

View file

@ -44,63 +44,6 @@ describe('utils tests', () => {
)
})
test('getRemoteDetail successfully parses remote URLs', async () => {
const remote1 = utils.getRemoteDetail(
'https://github.com/peter-evans/create-pull-request'
)
expect(remote1.protocol).toEqual('HTTPS')
expect(remote1.repository).toEqual('peter-evans/create-pull-request')
const remote2 = utils.getRemoteDetail(
'https://xxx:x-oauth-basic@github.com/peter-evans/create-pull-request'
)
expect(remote2.protocol).toEqual('HTTPS')
expect(remote2.repository).toEqual('peter-evans/create-pull-request')
const remote3 = utils.getRemoteDetail(
'git@github.com:peter-evans/create-pull-request.git'
)
expect(remote3.protocol).toEqual('SSH')
expect(remote3.repository).toEqual('peter-evans/create-pull-request')
const remote4 = utils.getRemoteDetail(
'https://github.com/peter-evans/create-pull-request.git'
)
expect(remote4.protocol).toEqual('HTTPS')
expect(remote4.repository).toEqual('peter-evans/create-pull-request')
const remote5 = utils.getRemoteDetail(
'https://github.com/peter-evans/ungit'
)
expect(remote5.protocol).toEqual('HTTPS')
expect(remote5.repository).toEqual('peter-evans/ungit')
const remote6 = utils.getRemoteDetail(
'https://github.com/peter-evans/ungit.git'
)
expect(remote6.protocol).toEqual('HTTPS')
expect(remote6.repository).toEqual('peter-evans/ungit')
const remote7 = utils.getRemoteDetail(
'git@github.com:peter-evans/ungit.git'
)
expect(remote7.protocol).toEqual('SSH')
expect(remote7.repository).toEqual('peter-evans/ungit')
})
test('getRemoteDetail fails to parse a remote URL', async () => {
const remoteUrl = 'https://github.com/peter-evans'
try {
utils.getRemoteDetail(remoteUrl)
// Fail the test if an error wasn't thrown
expect(true).toEqual(false)
} catch (e: any) {
expect(e.message).toEqual(
`The format of '${remoteUrl}' is not a valid GitHub repository URL`
)
}
})
test('getRemoteUrl successfully returns remote URLs', async () => {
const url1 = utils.getRemoteUrl(
'HTTPS',