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

V6 #2717

Merged
merged 12 commits into from Jan 31, 2024
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Expand Up @@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
cache: npm
- run: npm ci
- run: npm run build
Expand Down Expand Up @@ -68,8 +68,8 @@ jobs:
uses: ./
with:
commit-message: '[CI] test ${{ matrix.target }}'
committer: GitHub <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>
title: '[CI] test ${{ matrix.target }}'
body: |
- CI test case for target '${{ matrix.target }}'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/cpr-example-command.yml
Expand Up @@ -16,8 +16,8 @@ jobs:
uses: ./
with:
commit-message: Update report
committer: GitHub <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>
signoff: false
title: '[Example] Update report'
body: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-major-version.yml
Expand Up @@ -11,8 +11,8 @@ on:
type: choice
description: The major version tag to update
options:
- v4
- v5
- v6

jobs:
tag:
Expand Down
27 changes: 14 additions & 13 deletions README.md
Expand Up @@ -21,7 +21,7 @@ Create Pull Request action will:

- [Concepts, guidelines and advanced usage](docs/concepts-guidelines.md)
- [Examples](docs/examples.md)
- [Updating to v5](docs/updating.md)
- [Updating to v6](docs/updating.md)
- [Common issues](docs/common-issues.md)

## Usage
Expand All @@ -32,10 +32,10 @@ Create Pull Request action will:
# Make changes to pull request here

- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
```

You can also pin to a [specific release](https://github.com/peter-evans/create-pull-request/releases) version in the format `@v5.x.x`
You can also pin to a [specific release](https://github.com/peter-evans/create-pull-request/releases) version in the format `@v6.x.x`

### Workflow permissions

Expand All @@ -53,11 +53,12 @@ All inputs are **optional**. If not set, sensible defaults will be used.
| Name | Description | Default |
| --- | --- | --- |
| `token` | `GITHUB_TOKEN` (permissions `contents: write` and `pull-requests: write`) or a `repo` scoped [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token). | `GITHUB_TOKEN` |
| `git-token` | The [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) that the action will use for git operations. | Defaults to the value of `token` |
| `path` | Relative path under `GITHUB_WORKSPACE` to the repository. | `GITHUB_WORKSPACE` |
| `add-paths` | A comma or newline-separated list of file paths to commit. Paths should follow git's [pathspec](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec) syntax. If no paths are specified, all new and modified files are added. See [Add specific paths](#add-specific-paths). | |
| `commit-message` | The message to use when committing changes. See [commit-message](#commit-message). | `[create-pull-request] automated change` |
| `committer` | The committer name and email address in the format `Display Name <email@address.com>`. Defaults to the GitHub Actions bot user. | `GitHub <noreply@github.com>` |
| `author` | The author name and email address in the format `Display Name <email@address.com>`. Defaults to the user who triggered the workflow run. | `${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>` |
| `committer` | The committer name and email address in the format `Display Name <email@address.com>`. Defaults to the GitHub Actions bot user. | `github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>` |
| `author` | The author name and email address in the format `Display Name <email@address.com>`. Defaults to the user who triggered the workflow run. | `${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>` |
| `signoff` | Add [`Signed-off-by`](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---signoff) line by the committer at the end of the commit log message. | `false` |
| `branch` | The pull request branch name. | `create-pull-request/patch` |
| `delete-branch` | Delete the `branch` if it doesn't have an active pull request associated with it. See [delete-branch](#delete-branch). | `false` |
Expand Down Expand Up @@ -99,7 +100,7 @@ If you want branches to be deleted immediately on merge then you should use GitH
For self-hosted runners behind a corporate proxy set the `https_proxy` environment variable.
```yml
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
env:
https_proxy: http://<proxy_address>:<port>
```
Expand All @@ -119,7 +120,7 @@ Note that in order to read the step outputs the action step must have an id.
```yml
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
- name: Check outputs
if: ${{ steps.cpr.outputs.pull-request-number }}
run: |
Expand Down Expand Up @@ -182,7 +183,7 @@ File changes that do not match one of the paths will be stashed and restored aft

```yml
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
with:
add-paths: |
*.java
Expand All @@ -209,7 +210,7 @@ Note that the repository must be checked out on a branch with a remote, it won't
- name: Uncommitted change
run: date +%s > report.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
```

### Create a project card
Expand All @@ -219,7 +220,7 @@ To create a project card for the pull request, pass the `pull-request-number` st
```yml
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6

- name: Create or Update Project Card
if: ${{ steps.cpr.outputs.pull-request-number }}
Expand Down Expand Up @@ -254,12 +255,12 @@ jobs:

- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.PAT }}
commit-message: Update report
committer: GitHub <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>
signoff: false
branch: example-patches
delete-branch: true
Expand Down
4 changes: 2 additions & 2 deletions __test__/create-or-update-branch.int.test.ts
Expand Up @@ -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'
Expand All @@ -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 = []
Expand Down
14 changes: 7 additions & 7 deletions __test__/entrypoint.sh
Expand Up @@ -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
Expand All @@ -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
Expand Down
@@ -1,70 +1,86 @@
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()
})

it('tests save and restore of persisted auth', async () => {
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 adding and removing the safe.directory config', async () => {
it('tests not adding/removing the safe.directory config when it already exists', 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', '/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 () => {
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()
})
})
93 changes: 93 additions & 0 deletions __test__/git-config-helper.unit.test.ts
@@ -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`
)
}
})
})