mirror of
https://github.com/tauri-apps/create-pull-request.git
synced 2026-01-31 00:35:18 +01:00
Compare commits
1 Commits
v2.8.0
...
example-pa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cf9e1e2c4 |
@@ -1,3 +0,0 @@
|
||||
dist/
|
||||
lib/
|
||||
node_modules/
|
||||
@@ -1,19 +1,17 @@
|
||||
{
|
||||
"env": { "node": true, "jest": true },
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": { "ecmaVersion": 9, "sourceType": "module" },
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/errors",
|
||||
"plugin:import/warnings",
|
||||
"plugin:import/typescript",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier/@typescript-eslint"
|
||||
],
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"rules": {
|
||||
"@typescript-eslint/camelcase": "off"
|
||||
}
|
||||
}
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"rules": {
|
||||
}
|
||||
}
|
||||
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* @peter-evans
|
||||
127
.github/workflows/ci.yml
vendored
127
.github/workflows/ci.yml
vendored
@@ -1,127 +0,0 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- 'docs/**'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- 'docs/**'
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12.x
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- run: npm ci
|
||||
- run: npm run clean
|
||||
- run: npm run build
|
||||
- run: npm run format-check
|
||||
- run: npm run lint
|
||||
- run: npm run test
|
||||
- run: npm run package
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
|
||||
test:
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target: [built, committed]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: master
|
||||
- if: matrix.target == 'built' || github.event_name == 'pull_request'
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
|
||||
- name: Create change
|
||||
run: date +%s > report.txt
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: ./
|
||||
with:
|
||||
commit-message: '[CI] test ${{ matrix.target }}'
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
|
||||
title: '[CI] test ${{ matrix.target }}'
|
||||
body: |
|
||||
- CI test case for target '${{ matrix.target }}'
|
||||
|
||||
Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
branch: ci-test-${{ matrix.target }}
|
||||
|
||||
- name: Close Pull
|
||||
uses: peter-evans/close-pull@v1
|
||||
with:
|
||||
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
comment: '[CI] test ${{ matrix.target }}'
|
||||
delete-branch: true
|
||||
|
||||
commentTestSuiteHelp:
|
||||
if: github.event_name == 'pull_request'
|
||||
needs: [test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@v1
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ github.event.number }}
|
||||
comment-author: 'github-actions[bot]'
|
||||
body-includes: Full test suite slash command
|
||||
|
||||
- if: steps.fc.outputs.comment-id == ''
|
||||
name: Create comment
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.number }}
|
||||
body: |
|
||||
Full test suite slash command (repository admin only)
|
||||
```
|
||||
/test repository=${{ github.event.pull_request.head.repo.full_name }} branch=${{ github.event.pull_request.head.ref }} build=true
|
||||
```
|
||||
|
||||
package:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
needs: [test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: rm -rf dist
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v2
|
||||
with:
|
||||
commit-message: Update distribution
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
|
||||
title: Update distribution
|
||||
body: |
|
||||
- Updates the distribution for changes on `master`
|
||||
|
||||
Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
branch: update-distribution
|
||||
8
.github/workflows/cpr-example-command.yml
vendored
8
.github/workflows/cpr-example-command.yml
vendored
@@ -7,10 +7,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Create report file
|
||||
run: date +%s > report.txt
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: ./
|
||||
@@ -29,15 +27,15 @@ jobs:
|
||||
assignees: peter-evans
|
||||
reviewers: peter-evans
|
||||
milestone: 1
|
||||
project: Example Project
|
||||
project-column: To do
|
||||
draft: false
|
||||
branch: example-patches
|
||||
request-to-parent: false
|
||||
|
||||
- name: Check outputs
|
||||
run: |
|
||||
echo "Pull Request Number - ${{ env.PULL_REQUEST_NUMBER }}"
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pr_number }}"
|
||||
- name: Add reaction
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
|
||||
19
.github/workflows/dockerhub-description.yml
vendored
Normal file
19
.github/workflows/dockerhub-description.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Update Docker Hub Description
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- README.md
|
||||
- .github/workflows/dockerhub-description.yml
|
||||
jobs:
|
||||
dockerHubDescription:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v2.1.0
|
||||
env:
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
DOCKERHUB_REPOSITORY: peterevans/create-pull-request
|
||||
31
.github/workflows/update-dep.yml
vendored
31
.github/workflows/update-dep.yml
vendored
@@ -1,31 +0,0 @@
|
||||
name: Update Dependencies
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 1 * * 4'
|
||||
jobs:
|
||||
update-dep:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12.x'
|
||||
- name: Update dependencies
|
||||
run: |
|
||||
npx -p npm-check-updates ncu -u
|
||||
npm install
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v2
|
||||
with:
|
||||
token: ${{ secrets.ACTIONS_BOT_TOKEN }}
|
||||
commit-message: Update dependencies
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: actions-bot <actions-bot@users.noreply.github.com>
|
||||
title: Update dependencies
|
||||
body: |
|
||||
- Dependency updates
|
||||
|
||||
Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
branch: update-dependencies
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,7 +1,6 @@
|
||||
__pycache__
|
||||
.python-version
|
||||
|
||||
lib/
|
||||
node_modules/
|
||||
node_modules
|
||||
|
||||
.DS_Store
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
dist/
|
||||
lib/
|
||||
node_modules/
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "avoid",
|
||||
"parser": "typescript"
|
||||
}
|
||||
34
README.md
34
README.md
@@ -1,5 +1,4 @@
|
||||
# <img width="24" height="24" src="docs/assets/logo.svg"> Create Pull Request
|
||||
[](https://github.com/peter-evans/create-pull-request/actions?query=workflow%3ACI)
|
||||
[](https://github.com/marketplace/actions/create-pull-request)
|
||||
|
||||
A GitHub action to create a pull request for changes to your repository in the actions workspace.
|
||||
@@ -50,17 +49,17 @@ All inputs are **optional**. If not set, sensible default values will be used.
|
||||
| `labels` | A comma separated list of labels. | |
|
||||
| `assignees` | A comma separated list of assignees (GitHub usernames). | |
|
||||
| `reviewers` | A comma separated list of reviewers (GitHub usernames) to request a review from. | |
|
||||
| `team-reviewers` | A comma separated list of GitHub teams to request a review from. A `repo` scoped [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) may be required. See [this issue](https://github.com/peter-evans/create-pull-request/issues/155). | |
|
||||
| `team-reviewers` | A comma separated list of GitHub teams to request a review from. | |
|
||||
| `milestone` | The number of the milestone to associate this pull request with. | |
|
||||
| `project` | *Deprecated*. See [Create a project card](#create-a-project-card) for details. | |
|
||||
| `project-column` | *Deprecated*. See [Create a project card](#create-a-project-card) for details. | |
|
||||
| `project` | The name of the project for which a card should be created. Requires `project-column`. | |
|
||||
| `project-column` | The name of the project column under which a card should be created. Requires `project`. | |
|
||||
| `draft` | Create a [draft pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). | `false` |
|
||||
| `branch` | The branch name. See [Branch naming](#branch-naming) for details. | `create-pull-request/patch` |
|
||||
| `request-to-parent` | Create the pull request in the parent repository of the checked out fork. See [push pull request branches to a fork](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#push-pull-request-branches-to-a-fork) for details. | `false` |
|
||||
| `base` | Sets the pull request base branch. | Defaults to the branch checked out in the workflow. |
|
||||
| `branch-suffix` | The branch suffix type. Valid values are `random`, `timestamp` and `short-commit-hash`. See [Branch naming](#branch-naming) for details. | |
|
||||
|
||||
### Action outputs
|
||||
**Outputs**
|
||||
|
||||
The pull request number is output as both an environment variable and a step output.
|
||||
Note that in order to read the step output the action step must have an id.
|
||||
@@ -72,7 +71,7 @@ Note that in order to read the step output the action step must have an id.
|
||||
- name: Check outputs
|
||||
run: |
|
||||
echo "Pull Request Number - ${{ env.PULL_REQUEST_NUMBER }}"
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pr_number }}"
|
||||
```
|
||||
|
||||
### Checkout
|
||||
@@ -144,23 +143,6 @@ As well as relying on the action to handle uncommitted changes, you can addition
|
||||
uses: peter-evans/create-pull-request@v2
|
||||
```
|
||||
|
||||
### Create a project card
|
||||
|
||||
To create a project card for the pull request, pass the `pull-request-number` step output to [create-or-update-project-card](https://github.com/peter-evans/create-or-update-project-card) action.
|
||||
|
||||
```yml
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@v2
|
||||
|
||||
- name: Create or Update Project Card
|
||||
uses: peter-evans/create-or-update-project-card@v1
|
||||
with:
|
||||
project-name: My project
|
||||
column-name: My column
|
||||
issue-number: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
```
|
||||
|
||||
## Reference Example
|
||||
|
||||
The following workflow is a reference example that sets all the main inputs.
|
||||
@@ -197,16 +179,18 @@ jobs:
|
||||
reviewers: peter-evans
|
||||
team-reviewers: owners, maintainers
|
||||
milestone: 1
|
||||
project: Example Project
|
||||
project-column: To do
|
||||
draft: false
|
||||
branch: example-patches
|
||||
request-to-parent: false
|
||||
- name: Check outputs
|
||||
run: |
|
||||
echo "Pull Request Number - ${{ env.PULL_REQUEST_NUMBER }}"
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pr_number }}"
|
||||
```
|
||||
|
||||
An example based on the above reference configuration creates pull requests that look like this:
|
||||
This reference configuration will create pull requests that look like this:
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
import * as path from 'path'
|
||||
import {
|
||||
ConfigOption,
|
||||
getRepoPath,
|
||||
execGit,
|
||||
addConfigOption,
|
||||
unsetConfigOption,
|
||||
configOptionExists,
|
||||
getConfigOption,
|
||||
getAndUnsetConfigOption
|
||||
} from '../lib/git'
|
||||
|
||||
const originalGitHubWorkspace = process.env['GITHUB_WORKSPACE']
|
||||
|
||||
describe('git tests', () => {
|
||||
beforeAll(() => {
|
||||
// GitHub workspace
|
||||
process.env['GITHUB_WORKSPACE'] = __dirname
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
// Restore GitHub workspace
|
||||
delete process.env['GITHUB_WORKSPACE']
|
||||
if (originalGitHubWorkspace) {
|
||||
process.env['GITHUB_WORKSPACE'] = originalGitHubWorkspace
|
||||
}
|
||||
})
|
||||
|
||||
test('getRepoPath', async () => {
|
||||
expect(getRepoPath()).toEqual(process.env['GITHUB_WORKSPACE'])
|
||||
expect(getRepoPath('foo')).toEqual(
|
||||
path.resolve(process.env['GITHUB_WORKSPACE'] || '', 'foo')
|
||||
)
|
||||
})
|
||||
|
||||
test('execGit', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
['config', '--local', '--name-only', '--get-regexp', 'remote.origin.url'],
|
||||
true
|
||||
)
|
||||
expect(result.exitCode).toEqual(0)
|
||||
expect(result.stdout.trim()).toEqual('remote.origin.url')
|
||||
})
|
||||
|
||||
it('adds and unsets a config option', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const add = await addConfigOption(
|
||||
repoPath,
|
||||
'test.add.and.unset.config.option',
|
||||
'foo'
|
||||
)
|
||||
expect(add).toBeTruthy()
|
||||
const unset = await unsetConfigOption(
|
||||
repoPath,
|
||||
'test.add.and.unset.config.option'
|
||||
)
|
||||
expect(unset).toBeTruthy()
|
||||
})
|
||||
|
||||
it('adds and unsets a config option with value regex', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const add = await addConfigOption(
|
||||
repoPath,
|
||||
'test.add.and.unset.config.option',
|
||||
'foo bar'
|
||||
)
|
||||
expect(add).toBeTruthy()
|
||||
const unset = await unsetConfigOption(
|
||||
repoPath,
|
||||
'test.add.and.unset.config.option',
|
||||
'^foo'
|
||||
)
|
||||
expect(unset).toBeTruthy()
|
||||
})
|
||||
|
||||
test('configOptionExists returns true', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const result = await configOptionExists(repoPath, 'remote.origin.url')
|
||||
expect(result).toBeTruthy()
|
||||
})
|
||||
|
||||
test('configOptionExists returns false', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const result = await configOptionExists(repoPath, 'this.key.does.not.exist')
|
||||
expect(result).toBeFalsy()
|
||||
})
|
||||
|
||||
it('successfully retrieves a config option', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const add = await addConfigOption(repoPath, 'test.get.config.option', 'foo')
|
||||
expect(add).toBeTruthy()
|
||||
const option = await getConfigOption(repoPath, 'test.get.config.option')
|
||||
expect(option.value).toEqual('foo')
|
||||
const unset = await unsetConfigOption(repoPath, 'test.get.config.option')
|
||||
expect(unset).toBeTruthy()
|
||||
})
|
||||
|
||||
it('gets a config option with value regex', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const add = await addConfigOption(
|
||||
repoPath,
|
||||
'test.get.config.option',
|
||||
'foo bar'
|
||||
)
|
||||
expect(add).toBeTruthy()
|
||||
const option = await getConfigOption(
|
||||
repoPath,
|
||||
'test.get.config.option',
|
||||
'^foo'
|
||||
)
|
||||
expect(option.value).toEqual('foo bar')
|
||||
const unset = await unsetConfigOption(
|
||||
repoPath,
|
||||
'test.get.config.option',
|
||||
'^foo'
|
||||
)
|
||||
expect(unset).toBeTruthy()
|
||||
})
|
||||
|
||||
it('gets and unsets a config option', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const add = await addConfigOption(
|
||||
repoPath,
|
||||
'test.get.and.unset.config.option',
|
||||
'foo'
|
||||
)
|
||||
expect(add).toBeTruthy()
|
||||
const getAndUnset = await getAndUnsetConfigOption(
|
||||
repoPath,
|
||||
'test.get.and.unset.config.option'
|
||||
)
|
||||
expect(getAndUnset.value).toEqual('foo')
|
||||
})
|
||||
|
||||
it('gets and unsets a config option with value regex', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const add = await addConfigOption(
|
||||
repoPath,
|
||||
'test.get.and.unset.config.option',
|
||||
'foo bar'
|
||||
)
|
||||
expect(add).toBeTruthy()
|
||||
const getAndUnset = await getAndUnsetConfigOption(
|
||||
repoPath,
|
||||
'test.get.and.unset.config.option',
|
||||
'^foo'
|
||||
)
|
||||
expect(getAndUnset.value).toEqual('foo bar')
|
||||
})
|
||||
|
||||
it('fails to get and unset a config option', async () => {
|
||||
const repoPath = getRepoPath()
|
||||
const getAndUnset = await getAndUnsetConfigOption(
|
||||
repoPath,
|
||||
'this.key.does.not.exist'
|
||||
)
|
||||
expect(getAndUnset.name).toEqual('')
|
||||
expect(getAndUnset.value).toEqual('')
|
||||
})
|
||||
})
|
||||
@@ -27,11 +27,9 @@ inputs:
|
||||
milestone:
|
||||
description: 'The number of the milestone to associate this pull request with.'
|
||||
project:
|
||||
description: 'Deprecated. See README for details.'
|
||||
description: 'The name of the project for which a card should be created.'
|
||||
project-column:
|
||||
description: 'Deprecated. See README for details.'
|
||||
draft:
|
||||
description: 'Create a draft pull request'
|
||||
description: 'The name of the project column under which a card should be created.'
|
||||
branch:
|
||||
description: 'The pull request branch name.'
|
||||
request-to-parent:
|
||||
@@ -42,7 +40,7 @@ inputs:
|
||||
branch-suffix:
|
||||
description: 'The branch suffix type.'
|
||||
outputs:
|
||||
pull-request-number:
|
||||
pr_number:
|
||||
description: 'The pull request number'
|
||||
runs:
|
||||
using: 'node12'
|
||||
|
||||
2
dist/cpr/create_or_update_pull_request.py
vendored
2
dist/cpr/create_or_update_pull_request.py
vendored
@@ -113,8 +113,6 @@ def create_or_update_pull_request(
|
||||
|
||||
# Set the output variables
|
||||
os.system(f"echo ::set-env name=PULL_REQUEST_NUMBER::{pull_request.number}")
|
||||
os.system(f"echo ::set-output name=pull-request-number::{pull_request.number}")
|
||||
# 'pr_number' is deprecated
|
||||
os.system(f"echo ::set-output name=pr_number::{pull_request.number}")
|
||||
|
||||
# Set labels, assignees and milestone
|
||||
|
||||
0
dist/cpr/create_pull_request.py
vendored
Normal file → Executable file
0
dist/cpr/create_pull_request.py
vendored
Normal file → Executable file
6
dist/cpr/requirements.txt
vendored
6
dist/cpr/requirements.txt
vendored
@@ -1,4 +1,2 @@
|
||||
setuptools==46.2.0
|
||||
wheel==0.34.2
|
||||
GitPython==3.1.2
|
||||
PyGithub==1.51
|
||||
GitPython==3.1.0
|
||||
PyGithub==1.47
|
||||
|
||||
3220
dist/index.js
vendored
3220
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
BIN
dist/vendor/Deprecated-1.2.10.tar.gz
vendored
BIN
dist/vendor/Deprecated-1.2.10.tar.gz
vendored
Binary file not shown.
BIN
dist/vendor/Deprecated-1.2.7.tar.gz
vendored
Normal file
BIN
dist/vendor/Deprecated-1.2.7.tar.gz
vendored
Normal file
Binary file not shown.
BIN
dist/vendor/GitPython-3.1.0.tar.gz
vendored
Normal file
BIN
dist/vendor/GitPython-3.1.0.tar.gz
vendored
Normal file
Binary file not shown.
BIN
dist/vendor/GitPython-3.1.2.tar.gz
vendored
BIN
dist/vendor/GitPython-3.1.2.tar.gz
vendored
Binary file not shown.
BIN
dist/vendor/PyGithub-1.47.tar.gz
vendored
Normal file
BIN
dist/vendor/PyGithub-1.47.tar.gz
vendored
Normal file
Binary file not shown.
BIN
dist/vendor/PyGithub-1.51.tar.gz
vendored
BIN
dist/vendor/PyGithub-1.51.tar.gz
vendored
Binary file not shown.
BIN
dist/vendor/certifi-2019.11.28.tar.gz
vendored
Normal file
BIN
dist/vendor/certifi-2019.11.28.tar.gz
vendored
Normal file
Binary file not shown.
BIN
dist/vendor/certifi-2020.4.5.1.tar.gz
vendored
BIN
dist/vendor/certifi-2020.4.5.1.tar.gz
vendored
Binary file not shown.
Binary file not shown.
BIN
dist/vendor/setuptools-46.2.0.zip
vendored
BIN
dist/vendor/setuptools-46.2.0.zip
vendored
Binary file not shown.
BIN
dist/vendor/smmap-3.0.1.tar.gz
vendored
Normal file
BIN
dist/vendor/smmap-3.0.1.tar.gz
vendored
Normal file
Binary file not shown.
BIN
dist/vendor/smmap-3.0.4.tar.gz
vendored
BIN
dist/vendor/smmap-3.0.4.tar.gz
vendored
Binary file not shown.
BIN
dist/vendor/urllib3-1.25.8.tar.gz
vendored
Normal file
BIN
dist/vendor/urllib3-1.25.8.tar.gz
vendored
Normal file
Binary file not shown.
BIN
dist/vendor/urllib3-1.25.9.tar.gz
vendored
BIN
dist/vendor/urllib3-1.25.9.tar.gz
vendored
Binary file not shown.
BIN
dist/vendor/wheel-0.34.2.tar.gz
vendored
BIN
dist/vendor/wheel-0.34.2.tar.gz
vendored
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 414 KiB |
@@ -90,7 +90,7 @@ Workflows triggered by `pull_request` events will by default check out a [merge
|
||||
|
||||
### Restrictions on forked repositories
|
||||
|
||||
GitHub Actions have imposed restrictions on events triggered by a forked repository. Specifically, the `pull_request` event triggered by a fork opening a pull request in the upstream repository.
|
||||
GitHub Actions have imposed restrictions on events triggered by a forked repository. For example, the `pull_request` event triggered by a fork opening a pull request in the upstream repository.
|
||||
|
||||
- Events from forks cannot access secrets, except for for the default `GITHUB_TOKEN`.
|
||||
> With the exception of GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository.
|
||||
@@ -101,7 +101,7 @@ GitHub Actions have imposed restrictions on events triggered by a forked reposit
|
||||
|
||||
[GitHub Actions: Permissions for the GITHUB_TOKEN](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#permissions-for-the-github_token)
|
||||
|
||||
These restrictions mean that during a `pull_request` event triggered by a forked repository, actions have no write access to GitHub resources and will fail on attempt.
|
||||
These restrictions mean that during a `pull_request` event triggered by a forked repository the action will be unable to commit changes to a branch.
|
||||
|
||||
A job condition can be added to prevent workflows from executing when triggered by a repository fork.
|
||||
|
||||
@@ -129,7 +129,7 @@ There are a number of workarounds with different pros and cons.
|
||||
- Use the default `GITHUB_TOKEN` and allow the action to create pull requests that have no checks enabled. Manually close pull requests and immediately reopen them. This will enable `on: pull_request` workflows to run and be added as checks.
|
||||
- Use a `repo` scoped [Personal Access Token (PAT)](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) created on an account that has write access to the repository that pull requests are being created in. This is the standard workaround and [recommended by GitHub](https://help.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token). However, the PAT cannot be scoped to a specific repository so the token becomes a very sensitive secret. If this is a concern, the PAT can instead be created for a dedicated [machine account](https://help.github.com/en/github/site-policy/github-terms-of-service#3-account-requirements) that has collaborator access to the repository. Also note that because the account that owns the PAT will be the creator of pull requests, that user account will be unable to perform actions such as request changes or approve the pull request.
|
||||
- Use [SSH (deploy keys)](#push-using-ssh-deploy-keys) to push the pull request branch. This is arguably more secure than using a PAT because deploy keys can be set per repository. However, this method will only trigger `on: push` workflows.
|
||||
- Use a [machine account that creates pull requests from its own fork](#push-pull-request-branches-to-a-fork). This is the most secure because the PAT created only grants access to the machine account's fork, not the main repository. This method will trigger `on: pull_request` workflows to run. Workflows triggered `on: push` will not run because the push event is in the fork.
|
||||
- Use a [machine account that creates pull requests from its own fork](#push-pull-request-branches-to-a-fork). This is the most secure because the PAT created only has access to its own fork, not the main repository. This method will trigger `on: pull_request` workflows to run. Workflows triggered `on: push` will not run because the push event is in the fork.
|
||||
|
||||
### Security
|
||||
|
||||
@@ -206,7 +206,7 @@ It will use their own fork to push code and create the pull request.
|
||||
3. Create a [Personal Access Token (PAT)](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line).
|
||||
4. Logout and log back in to your main user account.
|
||||
5. Add a secret to your repository containing the above PAT.
|
||||
6. As shown in the following example workflow, switch the git remote to the fork's URL after checkout and set the action input `request-to-parent` to `true`.
|
||||
6. As shown in the following example workflow, switch the git remote to the fork's URL after checkout and set the action input `request-on-parent` to `true`.
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v2
|
||||
@@ -221,7 +221,7 @@ It will use their own fork to push code and create the pull request.
|
||||
- uses: peter-evans/create-pull-request@v2
|
||||
with:
|
||||
token: ${{ secrets.MACHINE_USER_PAT }}
|
||||
request-to-parent: true
|
||||
request-on-parent: true
|
||||
```
|
||||
|
||||
### Running in a container
|
||||
|
||||
@@ -86,62 +86,32 @@ This pattern will work well for updating any kind of static content from an exte
|
||||
|
||||
### Update NPM dependencies
|
||||
|
||||
This workflow will create a pull request for npm dependencies.
|
||||
It works best in combination with a build workflow triggered on `push` and `pull_request`.
|
||||
A [Personal Access Token (PAT)](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) can be used in order for the creation of the pull request to trigger further workflows. See the [documentation here](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#triggering-further-workflow-runs) for further details.
|
||||
|
||||
```yml
|
||||
name: Update Dependencies
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * 1'
|
||||
jobs:
|
||||
update-dep:
|
||||
update-deps:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12.x'
|
||||
node-version: '10.x'
|
||||
- name: Update dependencies
|
||||
id: vars
|
||||
run: |
|
||||
npx -p npm-check-updates ncu -u
|
||||
npm install -g npm-check-updates
|
||||
ncu -u
|
||||
npm install
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v2
|
||||
with:
|
||||
token: ${{ secrets.PAT }}
|
||||
commit-message: Update dependencies
|
||||
title: Update dependencies
|
||||
body: |
|
||||
- Dependency updates
|
||||
|
||||
Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
branch: update-dependencies
|
||||
```
|
||||
|
||||
The above workflow works best in combination with a build workflow triggered on `push` and `pull_request`.
|
||||
|
||||
```yml
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12.x
|
||||
- run: npm ci
|
||||
- run: npm run test
|
||||
- run: npm run build
|
||||
commit-message: update dependencies
|
||||
title: Automated Dependency Updates
|
||||
body: This is an auto-generated PR with dependency updates.
|
||||
branch: dep-updates
|
||||
```
|
||||
|
||||
### Update SwaggerUI for GitHub Pages
|
||||
@@ -273,7 +243,7 @@ An `on: repository_dispatch` workflow can be triggered from another workflow wit
|
||||
|
||||
```yml
|
||||
- name: Repository Dispatch
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
uses: peter-evans/repository-dispatch@v1.0.0
|
||||
with:
|
||||
token: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
repository: username/my-repo
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.ts'],
|
||||
testRunner: 'jest-circus/runner',
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: true
|
||||
}
|
||||
process.env = Object.assign(process.env, {
|
||||
GITHUB_WORKSPACE: __dirname
|
||||
});
|
||||
|
||||
3177
package-lock.json
generated
3177
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
42
package.json
42
package.json
@@ -1,29 +1,21 @@
|
||||
{
|
||||
"name": "create-pull-request",
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"description": "Creates a pull request for changes to your repository in the actions workspace",
|
||||
"main": "lib/main.js",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist",
|
||||
"build": "tsc && ncc build",
|
||||
"format": "prettier --write '**/*.ts'",
|
||||
"format-check": "prettier --check '**/*.ts'",
|
||||
"lint": "eslint src/**/*.ts",
|
||||
"test": "jest --passWithNoTests",
|
||||
"pack-assets": "mkdir -p dist/cpr && cp -rv src/cpr/* dist/cpr",
|
||||
"lint": "eslint src/index.js",
|
||||
"test": "eslint src/index.js && jest",
|
||||
"build": "ncc build src/index.js -o dist",
|
||||
"vendor-deps": "pip download -r src/cpr/requirements.txt --no-binary=:all: -d dist/vendor",
|
||||
"package": "npm run build && npm run pack-assets && npm run vendor-deps"
|
||||
"package": "npm run build && npm run vendor-deps"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/peter-evans/create-pull-request.git"
|
||||
},
|
||||
"keywords": [
|
||||
"actions",
|
||||
"pull",
|
||||
"request"
|
||||
],
|
||||
"keywords": [],
|
||||
"author": "Peter Evans",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
@@ -31,24 +23,14 @@
|
||||
},
|
||||
"homepage": "https://github.com/peter-evans/create-pull-request",
|
||||
"dependencies": {
|
||||
"@actions/core": "1.2.4",
|
||||
"@actions/exec": "1.0.4",
|
||||
"@actions/tool-cache": "1.3.4",
|
||||
"is-docker": "2.0.0"
|
||||
"@actions/core": "^1.1.1",
|
||||
"@actions/exec": "^1.0.1",
|
||||
"@actions/tool-cache": "^1.1.2",
|
||||
"is-docker": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "25.2.2",
|
||||
"@types/node": "14.0.1",
|
||||
"@typescript-eslint/parser": "2.33.0",
|
||||
"@zeit/ncc": "0.22.1",
|
||||
"eslint": "7.0.0",
|
||||
"eslint-plugin-github": "3.4.1",
|
||||
"eslint-plugin-jest": "23.11.0",
|
||||
"jest": "26.0.1",
|
||||
"jest-circus": "26.0.1",
|
||||
"js-yaml": "3.13.1",
|
||||
"prettier": "2.0.5",
|
||||
"ts-jest": "25.5.1",
|
||||
"typescript": "3.9.2"
|
||||
"eslint": "6.8.0",
|
||||
"jest": "25.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"enabledManagers": ["pip_requirements"],
|
||||
"ignorePaths": [
|
||||
"**/dist/**"
|
||||
]
|
||||
}
|
||||
|
||||
1
report.txt
Normal file
1
report.txt
Normal file
@@ -0,0 +1 @@
|
||||
1586506368
|
||||
@@ -113,8 +113,6 @@ def create_or_update_pull_request(
|
||||
|
||||
# Set the output variables
|
||||
os.system(f"echo ::set-env name=PULL_REQUEST_NUMBER::{pull_request.number}")
|
||||
os.system(f"echo ::set-output name=pull-request-number::{pull_request.number}")
|
||||
# 'pr_number' is deprecated
|
||||
os.system(f"echo ::set-output name=pr_number::{pull_request.number}")
|
||||
|
||||
# Set labels, assignees and milestone
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
setuptools==46.2.0
|
||||
wheel==0.34.2
|
||||
GitPython==3.1.2
|
||||
PyGithub==1.51
|
||||
GitPython==3.1.0
|
||||
PyGithub==1.47
|
||||
|
||||
97
src/git.js
Normal file
97
src/git.js
Normal file
@@ -0,0 +1,97 @@
|
||||
const core = require("@actions/core");
|
||||
const exec = require("@actions/exec");
|
||||
const path = require("path");
|
||||
|
||||
function getRepoPath(relativePath) {
|
||||
let githubWorkspacePath = process.env["GITHUB_WORKSPACE"];
|
||||
if (!githubWorkspacePath) {
|
||||
throw new Error("GITHUB_WORKSPACE not defined");
|
||||
}
|
||||
githubWorkspacePath = path.resolve(githubWorkspacePath);
|
||||
core.debug(`githubWorkspacePath: ${githubWorkspacePath}`);
|
||||
|
||||
repoPath = githubWorkspacePath;
|
||||
if (relativePath) repoPath = path.resolve(repoPath, relativePath);
|
||||
|
||||
core.debug(`repoPath: ${repoPath}`);
|
||||
return repoPath;
|
||||
}
|
||||
|
||||
async function execGit(repoPath, args, ignoreReturnCode = false) {
|
||||
const stdout = [];
|
||||
const options = {
|
||||
cwd: repoPath,
|
||||
ignoreReturnCode: ignoreReturnCode,
|
||||
listeners: {
|
||||
stdout: data => {
|
||||
stdout.push(data.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var result = {};
|
||||
result.exitCode = await exec.exec("git", args, options);
|
||||
result.stdout = stdout.join("");
|
||||
return result;
|
||||
}
|
||||
|
||||
async function addConfigOption(repoPath, name, value) {
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
["config", "--local", "--add", name, value],
|
||||
true
|
||||
);
|
||||
return result.exitCode === 0;
|
||||
}
|
||||
|
||||
async function unsetConfigOption(repoPath, name, valueRegex=".") {
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
["config", "--local", "--unset", name, valueRegex],
|
||||
true
|
||||
);
|
||||
return result.exitCode === 0;
|
||||
}
|
||||
|
||||
async function configOptionExists(repoPath, name, valueRegex=".") {
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
["config", "--local", "--name-only", "--get-regexp", name, valueRegex],
|
||||
true
|
||||
);
|
||||
return result.exitCode === 0;
|
||||
}
|
||||
|
||||
async function getConfigOption(repoPath, name, valueRegex=".") {
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
["config", "--local", "--get-regexp", name, valueRegex],
|
||||
true
|
||||
);
|
||||
const option = result.stdout.trim().split(`${name} `);
|
||||
return {
|
||||
name: name,
|
||||
value: option[1]
|
||||
}
|
||||
}
|
||||
|
||||
async function getAndUnsetConfigOption(repoPath, name, valueRegex=".") {
|
||||
if (await configOptionExists(repoPath, name, valueRegex)) {
|
||||
const option = await getConfigOption(repoPath, name, valueRegex);
|
||||
if (await unsetConfigOption(repoPath, name, valueRegex)) {
|
||||
core.debug(`Unset config option '${name}'`);
|
||||
return option;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getRepoPath,
|
||||
execGit,
|
||||
addConfigOption,
|
||||
unsetConfigOption,
|
||||
configOptionExists,
|
||||
getConfigOption,
|
||||
getAndUnsetConfigOption
|
||||
};
|
||||
98
src/git.test.js
Normal file
98
src/git.test.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const path = require("path");
|
||||
const {
|
||||
getRepoPath,
|
||||
execGit,
|
||||
addConfigOption,
|
||||
unsetConfigOption,
|
||||
configOptionExists,
|
||||
getConfigOption,
|
||||
getAndUnsetConfigOption
|
||||
} = require("./git");
|
||||
|
||||
test("getRepoPath", async () => {
|
||||
expect(getRepoPath()).toEqual(process.env["GITHUB_WORKSPACE"]);
|
||||
expect(getRepoPath("foo")).toEqual(
|
||||
path.resolve(process.env["GITHUB_WORKSPACE"], "foo")
|
||||
);
|
||||
});
|
||||
|
||||
test("execGit", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
["config", "--local", "--name-only", "--get-regexp", "remote.origin.url"],
|
||||
true
|
||||
);
|
||||
expect(result.exitCode).toEqual(0);
|
||||
expect(result.stdout.trim()).toEqual("remote.origin.url");
|
||||
});
|
||||
|
||||
test("add and unset config option", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const add = await addConfigOption(repoPath, "test.add.and.unset.config.option", "foo");
|
||||
expect(add).toBeTruthy();
|
||||
const unset = await unsetConfigOption(repoPath, "test.add.and.unset.config.option");
|
||||
expect(unset).toBeTruthy();
|
||||
});
|
||||
|
||||
test("add and unset config option with value regex", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const add = await addConfigOption(repoPath, "test.add.and.unset.config.option", "foo bar");
|
||||
expect(add).toBeTruthy();
|
||||
const unset = await unsetConfigOption(repoPath, "test.add.and.unset.config.option", "^foo");
|
||||
expect(unset).toBeTruthy();
|
||||
});
|
||||
|
||||
test("configOptionExists returns true", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const result = await configOptionExists(repoPath, "remote.origin.url");
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
test("configOptionExists returns false", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const result = await configOptionExists(repoPath, "this.key.does.not.exist");
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
test("get config option", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const add = await addConfigOption(repoPath, "test.get.config.option", "foo");
|
||||
expect(add).toBeTruthy();
|
||||
const option = await getConfigOption(repoPath, "test.get.config.option");
|
||||
expect(option.value).toEqual("foo");
|
||||
const unset = await unsetConfigOption(repoPath, "test.get.config.option");
|
||||
expect(unset).toBeTruthy();
|
||||
});
|
||||
|
||||
test("get config option with value regex", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const add = await addConfigOption(repoPath, "test.get.config.option", "foo bar");
|
||||
expect(add).toBeTruthy();
|
||||
const option = await getConfigOption(repoPath, "test.get.config.option", "^foo");
|
||||
expect(option.value).toEqual("foo bar");
|
||||
const unset = await unsetConfigOption(repoPath, "test.get.config.option", "^foo");
|
||||
expect(unset).toBeTruthy();
|
||||
});
|
||||
|
||||
test("get and unset config option is successful", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const add = await addConfigOption(repoPath, "test.get.and.unset.config.option", "foo");
|
||||
expect(add).toBeTruthy();
|
||||
const getAndUnset = await getAndUnsetConfigOption(repoPath, "test.get.and.unset.config.option");
|
||||
expect(getAndUnset.value).toEqual("foo");
|
||||
});
|
||||
|
||||
test("get and unset config option is successful with value regex", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const add = await addConfigOption(repoPath, "test.get.and.unset.config.option", "foo bar");
|
||||
expect(add).toBeTruthy();
|
||||
const getAndUnset = await getAndUnsetConfigOption(repoPath, "test.get.and.unset.config.option", "^foo");
|
||||
expect(getAndUnset.value).toEqual("foo bar");
|
||||
});
|
||||
|
||||
test("get and unset config option is unsuccessful", async () => {
|
||||
const repoPath = getRepoPath();
|
||||
const getAndUnset = await getAndUnsetConfigOption(repoPath, "this.key.does.not.exist");
|
||||
expect(getAndUnset).toBeNull();
|
||||
});
|
||||
117
src/git.ts
117
src/git.ts
@@ -1,117 +0,0 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as path from 'path'
|
||||
|
||||
class GitOutput {
|
||||
stdout = ''
|
||||
exitCode = 0
|
||||
}
|
||||
|
||||
export class ConfigOption {
|
||||
name = ''
|
||||
value = ''
|
||||
}
|
||||
|
||||
export function getRepoPath(relativePath?: string): string {
|
||||
let githubWorkspacePath = process.env['GITHUB_WORKSPACE']
|
||||
if (!githubWorkspacePath) {
|
||||
throw new Error('GITHUB_WORKSPACE not defined')
|
||||
}
|
||||
githubWorkspacePath = path.resolve(githubWorkspacePath)
|
||||
core.debug(`githubWorkspacePath: ${githubWorkspacePath}`)
|
||||
|
||||
let repoPath = githubWorkspacePath
|
||||
if (relativePath) repoPath = path.resolve(repoPath, relativePath)
|
||||
|
||||
core.debug(`repoPath: ${repoPath}`)
|
||||
return repoPath
|
||||
}
|
||||
|
||||
export async function execGit(
|
||||
repoPath: string,
|
||||
args: string[],
|
||||
ignoreReturnCode = false
|
||||
): Promise<GitOutput> {
|
||||
const result = new GitOutput()
|
||||
|
||||
const stdout: string[] = []
|
||||
const options = {
|
||||
cwd: repoPath,
|
||||
ignoreReturnCode: ignoreReturnCode,
|
||||
listeners: {
|
||||
stdout: (data: Buffer): void => {
|
||||
stdout.push(data.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.exitCode = await exec.exec('git', args, options)
|
||||
result.stdout = stdout.join('')
|
||||
return result
|
||||
}
|
||||
|
||||
export async function addConfigOption(repoPath, name, value): Promise<boolean> {
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
['config', '--local', '--add', name, value],
|
||||
true
|
||||
)
|
||||
return result.exitCode === 0
|
||||
}
|
||||
|
||||
export async function unsetConfigOption(
|
||||
repoPath,
|
||||
name,
|
||||
valueRegex = '.'
|
||||
): Promise<boolean> {
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
['config', '--local', '--unset', name, valueRegex],
|
||||
true
|
||||
)
|
||||
return result.exitCode === 0
|
||||
}
|
||||
|
||||
export async function configOptionExists(
|
||||
repoPath,
|
||||
name,
|
||||
valueRegex = '.'
|
||||
): Promise<boolean> {
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
['config', '--local', '--name-only', '--get-regexp', name, valueRegex],
|
||||
true
|
||||
)
|
||||
return result.exitCode === 0
|
||||
}
|
||||
|
||||
export async function getConfigOption(
|
||||
repoPath,
|
||||
name,
|
||||
valueRegex = '.'
|
||||
): Promise<ConfigOption> {
|
||||
const option = new ConfigOption()
|
||||
const result = await execGit(
|
||||
repoPath,
|
||||
['config', '--local', '--get-regexp', name, valueRegex],
|
||||
true
|
||||
)
|
||||
option.name = name
|
||||
option.value = result.stdout.trim().split(`${name} `)[1]
|
||||
return option
|
||||
}
|
||||
|
||||
export async function getAndUnsetConfigOption(
|
||||
repoPath,
|
||||
name,
|
||||
valueRegex = '.'
|
||||
): Promise<ConfigOption> {
|
||||
if (await configOptionExists(repoPath, name, valueRegex)) {
|
||||
const option = await getConfigOption(repoPath, name, valueRegex)
|
||||
if (await unsetConfigOption(repoPath, name, valueRegex)) {
|
||||
core.debug(`Unset config option '${name}'`)
|
||||
return option
|
||||
}
|
||||
}
|
||||
return new ConfigOption()
|
||||
}
|
||||
122
src/index.js
Normal file
122
src/index.js
Normal file
@@ -0,0 +1,122 @@
|
||||
const { inspect } = require("util");
|
||||
const isDocker = require("is-docker");
|
||||
const core = require("@actions/core");
|
||||
const exec = require("@actions/exec");
|
||||
const setupPython = require("./setup-python");
|
||||
const {
|
||||
getRepoPath,
|
||||
getAndUnsetConfigOption,
|
||||
addConfigOption
|
||||
} = require("./git");
|
||||
|
||||
const EXTRAHEADER_OPTION = "http.https://github.com/.extraheader";
|
||||
const EXTRAHEADER_VALUE_REGEX = "^AUTHORIZATION:";
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
// Allows ncc to find assets to be included in the distribution
|
||||
const cpr = __dirname + "/cpr";
|
||||
core.debug(`cpr: ${cpr}`);
|
||||
|
||||
// Determine how to access python and pip
|
||||
const { pip, python } = (function() {
|
||||
if (isDocker()) {
|
||||
core.info("Running inside a Docker container");
|
||||
// Python 3 assumed to be installed and on the PATH
|
||||
return {
|
||||
pip: "pip3",
|
||||
python: "python3"
|
||||
};
|
||||
} else {
|
||||
// Setup Python from the tool cache
|
||||
setupPython("3.x", "x64");
|
||||
return {
|
||||
pip: "pip",
|
||||
python: "python"
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
// Install requirements
|
||||
await exec.exec(pip, [
|
||||
"install",
|
||||
"--requirement",
|
||||
`${cpr}/requirements.txt`,
|
||||
"--no-index",
|
||||
`--find-links=${__dirname}/vendor`
|
||||
]);
|
||||
|
||||
// Fetch action inputs
|
||||
const inputs = {
|
||||
token: core.getInput("token"),
|
||||
path: core.getInput("path"),
|
||||
commitMessage: core.getInput("commit-message"),
|
||||
committer: core.getInput("committer"),
|
||||
author: core.getInput("author"),
|
||||
title: core.getInput("title"),
|
||||
body: core.getInput("body"),
|
||||
labels: core.getInput("labels"),
|
||||
assignees: core.getInput("assignees"),
|
||||
reviewers: core.getInput("reviewers"),
|
||||
teamReviewers: core.getInput("team-reviewers"),
|
||||
milestone: core.getInput("milestone"),
|
||||
project: core.getInput("project"),
|
||||
projectColumn: core.getInput("project-column"),
|
||||
draft: core.getInput("draft"),
|
||||
branch: core.getInput("branch"),
|
||||
request_to_parent: core.getInput("request-to-parent"),
|
||||
base: core.getInput("base"),
|
||||
branchSuffix: core.getInput("branch-suffix")
|
||||
};
|
||||
core.debug(`Inputs: ${inspect(inputs)}`);
|
||||
|
||||
// Set environment variables from inputs.
|
||||
if (inputs.token) process.env.GITHUB_TOKEN = inputs.token;
|
||||
if (inputs.path) process.env.CPR_PATH = inputs.path;
|
||||
if (inputs.commitMessage) process.env.CPR_COMMIT_MESSAGE = inputs.commitMessage;
|
||||
if (inputs.committer) process.env.CPR_COMMITTER = inputs.committer;
|
||||
if (inputs.author) process.env.CPR_AUTHOR = inputs.author;
|
||||
if (inputs.title) process.env.CPR_TITLE = inputs.title;
|
||||
if (inputs.body) process.env.CPR_BODY = inputs.body;
|
||||
if (inputs.labels) process.env.CPR_LABELS = inputs.labels;
|
||||
if (inputs.assignees) process.env.CPR_ASSIGNEES = inputs.assignees;
|
||||
if (inputs.reviewers) process.env.CPR_REVIEWERS = inputs.reviewers;
|
||||
if (inputs.teamReviewers) process.env.CPR_TEAM_REVIEWERS = inputs.teamReviewers;
|
||||
if (inputs.milestone) process.env.CPR_MILESTONE = inputs.milestone;
|
||||
if (inputs.project) process.env.CPR_PROJECT_NAME = inputs.project;
|
||||
if (inputs.projectColumn) process.env.CPR_PROJECT_COLUMN_NAME = inputs.projectColumn;
|
||||
if (inputs.draft) process.env.CPR_DRAFT = inputs.draft;
|
||||
if (inputs.branch) process.env.CPR_BRANCH = inputs.branch;
|
||||
if (inputs.request_to_parent) process.env.CPR_REQUEST_TO_PARENT = inputs.request_to_parent;
|
||||
if (inputs.base) process.env.CPR_BASE = inputs.base;
|
||||
if (inputs.branchSuffix) process.env.CPR_BRANCH_SUFFIX = inputs.branchSuffix;
|
||||
|
||||
// Get the repository path
|
||||
var repoPath = getRepoPath(inputs.path);
|
||||
// Get the extraheader config option if it exists
|
||||
var extraHeaderOption = await getAndUnsetConfigOption(
|
||||
repoPath,
|
||||
EXTRAHEADER_OPTION,
|
||||
EXTRAHEADER_VALUE_REGEX
|
||||
);
|
||||
|
||||
// Execute create pull request
|
||||
await exec.exec(python, [`${cpr}/create_pull_request.py`]);
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
} finally {
|
||||
// Restore the extraheader config option
|
||||
if (extraHeaderOption) {
|
||||
if (
|
||||
await addConfigOption(
|
||||
repoPath,
|
||||
EXTRAHEADER_OPTION,
|
||||
extraHeaderOption.value
|
||||
)
|
||||
)
|
||||
core.debug(`Restored config option '${EXTRAHEADER_OPTION}'`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -1,22 +0,0 @@
|
||||
import * as fs from 'fs'
|
||||
|
||||
function hasDockerEnv(): boolean {
|
||||
try {
|
||||
fs.statSync('/.dockerenv')
|
||||
return true
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function hasDockerCGroup(): boolean {
|
||||
try {
|
||||
return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker')
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function isDocker(): boolean {
|
||||
return hasDockerEnv() || hasDockerCGroup()
|
||||
}
|
||||
129
src/main.ts
129
src/main.ts
@@ -1,129 +0,0 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import {isDocker} from './isDocker'
|
||||
import {setupPython} from './setupPython'
|
||||
import {
|
||||
ConfigOption,
|
||||
getRepoPath,
|
||||
getAndUnsetConfigOption,
|
||||
addConfigOption
|
||||
} from './git'
|
||||
import {inspect} from 'util'
|
||||
|
||||
const EXTRAHEADER_OPTION = 'http.https://github.com/.extraheader'
|
||||
const EXTRAHEADER_VALUE_REGEX = '^AUTHORIZATION:'
|
||||
|
||||
async function run(): Promise<void> {
|
||||
let repoPath
|
||||
let extraHeaderOption = new ConfigOption()
|
||||
try {
|
||||
// Python assets
|
||||
const cpr = `${__dirname}/cpr`
|
||||
core.debug(`cpr: ${cpr}`)
|
||||
|
||||
// Determine how to access python and pip
|
||||
const {pip, python} = (function (): {pip: string; python: string} {
|
||||
if (isDocker()) {
|
||||
core.info('Running inside a Docker container')
|
||||
// Python 3 assumed to be installed and on the PATH
|
||||
return {
|
||||
pip: 'pip3',
|
||||
python: 'python3'
|
||||
}
|
||||
} else {
|
||||
// Setup Python from the tool cache
|
||||
setupPython('3.x', 'x64')
|
||||
return {
|
||||
pip: 'pip',
|
||||
python: 'python'
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
// Install requirements
|
||||
await exec.exec(pip, [
|
||||
'install',
|
||||
'--requirement',
|
||||
`${cpr}/requirements.txt`,
|
||||
'--no-index',
|
||||
`--find-links=${__dirname}/vendor`
|
||||
])
|
||||
|
||||
// Fetch action inputs
|
||||
const inputs = {
|
||||
token: core.getInput('token'),
|
||||
path: core.getInput('path'),
|
||||
commitMessage: core.getInput('commit-message'),
|
||||
committer: core.getInput('committer'),
|
||||
author: core.getInput('author'),
|
||||
title: core.getInput('title'),
|
||||
body: core.getInput('body'),
|
||||
labels: core.getInput('labels'),
|
||||
assignees: core.getInput('assignees'),
|
||||
reviewers: core.getInput('reviewers'),
|
||||
teamReviewers: core.getInput('team-reviewers'),
|
||||
milestone: core.getInput('milestone'),
|
||||
project: core.getInput('project'),
|
||||
projectColumn: core.getInput('project-column'),
|
||||
draft: core.getInput('draft'),
|
||||
branch: core.getInput('branch'),
|
||||
requestToParent: core.getInput('request-to-parent'),
|
||||
base: core.getInput('base'),
|
||||
branchSuffix: core.getInput('branch-suffix')
|
||||
}
|
||||
core.debug(`Inputs: ${inspect(inputs)}`)
|
||||
|
||||
// Set environment variables from inputs.
|
||||
if (inputs.token) process.env.GITHUB_TOKEN = inputs.token
|
||||
if (inputs.path) process.env.CPR_PATH = inputs.path
|
||||
if (inputs.commitMessage)
|
||||
process.env.CPR_COMMIT_MESSAGE = inputs.commitMessage
|
||||
if (inputs.committer) process.env.CPR_COMMITTER = inputs.committer
|
||||
if (inputs.author) process.env.CPR_AUTHOR = inputs.author
|
||||
if (inputs.title) process.env.CPR_TITLE = inputs.title
|
||||
if (inputs.body) process.env.CPR_BODY = inputs.body
|
||||
if (inputs.labels) process.env.CPR_LABELS = inputs.labels
|
||||
if (inputs.assignees) process.env.CPR_ASSIGNEES = inputs.assignees
|
||||
if (inputs.reviewers) process.env.CPR_REVIEWERS = inputs.reviewers
|
||||
if (inputs.teamReviewers)
|
||||
process.env.CPR_TEAM_REVIEWERS = inputs.teamReviewers
|
||||
if (inputs.milestone) process.env.CPR_MILESTONE = inputs.milestone
|
||||
if (inputs.project) process.env.CPR_PROJECT_NAME = inputs.project
|
||||
if (inputs.projectColumn)
|
||||
process.env.CPR_PROJECT_COLUMN_NAME = inputs.projectColumn
|
||||
if (inputs.draft) process.env.CPR_DRAFT = inputs.draft
|
||||
if (inputs.branch) process.env.CPR_BRANCH = inputs.branch
|
||||
if (inputs.requestToParent)
|
||||
process.env.CPR_REQUEST_TO_PARENT = inputs.requestToParent
|
||||
if (inputs.base) process.env.CPR_BASE = inputs.base
|
||||
if (inputs.branchSuffix) process.env.CPR_BRANCH_SUFFIX = inputs.branchSuffix
|
||||
|
||||
// Get the repository path
|
||||
repoPath = getRepoPath(inputs.path)
|
||||
// Get the extraheader config option if it exists
|
||||
extraHeaderOption = await getAndUnsetConfigOption(
|
||||
repoPath,
|
||||
EXTRAHEADER_OPTION,
|
||||
EXTRAHEADER_VALUE_REGEX
|
||||
)
|
||||
|
||||
// Execute create pull request
|
||||
await exec.exec(python, [`${cpr}/create_pull_request.py`])
|
||||
} catch (error) {
|
||||
core.setFailed(error.message)
|
||||
} finally {
|
||||
// Restore the extraheader config option
|
||||
if (extraHeaderOption.value != '') {
|
||||
if (
|
||||
await addConfigOption(
|
||||
repoPath,
|
||||
EXTRAHEADER_OPTION,
|
||||
extraHeaderOption.value
|
||||
)
|
||||
)
|
||||
core.debug(`Restored config option '${EXTRAHEADER_OPTION}'`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run()
|
||||
52
src/setup-python.js
Normal file
52
src/setup-python.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const core = require("@actions/core");
|
||||
const tc = require("@actions/tool-cache");
|
||||
const path = require("path");
|
||||
const semver = require("semver");
|
||||
|
||||
/**
|
||||
* Setup for Python from the GitHub Actions tool cache
|
||||
* Converted from https://github.com/actions/setup-python
|
||||
*
|
||||
* @param {string} versionSpec version of Python
|
||||
* @param {string} arch architecture (x64|x32)
|
||||
*/
|
||||
let setupPython = function(versionSpec, arch) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
|
||||
// Find the version of Python we want in the tool cache
|
||||
const installDir = tc.find("Python", versionSpec, arch);
|
||||
core.debug(`installDir: ${installDir}`);
|
||||
|
||||
// Set paths
|
||||
core.exportVariable("pythonLocation", installDir);
|
||||
core.addPath(installDir);
|
||||
if (IS_WINDOWS) {
|
||||
core.addPath(path.join(installDir, "Scripts"));
|
||||
} else {
|
||||
core.addPath(path.join(installDir, "bin"));
|
||||
}
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
// Add --user directory
|
||||
// `installDir` from tool cache should look like $AGENT_TOOLSDIRECTORY/Python/<semantic version>/x64/
|
||||
// So if `findLocalTool` succeeded above, we must have a conformant `installDir`
|
||||
const version = path.basename(path.dirname(installDir));
|
||||
const major = semver.major(version);
|
||||
const minor = semver.minor(version);
|
||||
|
||||
const userScriptsDir = path.join(
|
||||
process.env["APPDATA"] || "",
|
||||
"Python",
|
||||
`Python${major}${minor}`,
|
||||
"Scripts"
|
||||
);
|
||||
core.addPath(userScriptsDir);
|
||||
}
|
||||
// On Linux and macOS, pip will create the --user directory and add it to PATH as needed.
|
||||
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = setupPython;
|
||||
@@ -1,50 +0,0 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as tc from '@actions/tool-cache'
|
||||
import * as path from 'path'
|
||||
import * as semver from 'semver'
|
||||
|
||||
/**
|
||||
* Setup for Python from the GitHub Actions tool cache
|
||||
* Converted from https://github.com/actions/setup-python
|
||||
*
|
||||
* @param {string} versionSpec version of Python
|
||||
* @param {string} arch architecture (x64|x32)
|
||||
*/
|
||||
export function setupPython(versionSpec, arch): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
const IS_WINDOWS = process.platform === 'win32'
|
||||
|
||||
// Find the version of Python we want in the tool cache
|
||||
const installDir = tc.find('Python', versionSpec, arch)
|
||||
core.debug(`installDir: ${installDir}`)
|
||||
|
||||
// Set paths
|
||||
core.exportVariable('pythonLocation', installDir)
|
||||
core.addPath(installDir)
|
||||
if (IS_WINDOWS) {
|
||||
core.addPath(path.join(installDir, 'Scripts'))
|
||||
} else {
|
||||
core.addPath(path.join(installDir, 'bin'))
|
||||
}
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
// Add --user directory
|
||||
// `installDir` from tool cache should look like $AGENT_TOOLSDIRECTORY/Python/<semantic version>/x64/
|
||||
// So if `findLocalTool` succeeded above, we must have a conformant `installDir`
|
||||
const version = path.basename(path.dirname(installDir))
|
||||
const major = semver.major(version)
|
||||
const minor = semver.minor(version)
|
||||
|
||||
const userScriptsDir = path.join(
|
||||
process.env['APPDATA'] || '',
|
||||
'Python',
|
||||
`Python${major}${minor}`,
|
||||
'Scripts'
|
||||
)
|
||||
core.addPath(userScriptsDir)
|
||||
}
|
||||
// On Linux and macOS, pip will create the --user directory and add it to PATH as needed.
|
||||
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"outDir": "./lib",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": false,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"exclude": ["__test__", "lib", "node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user