Convert to typescript
This commit is contained in:
parent
0f423da02c
commit
f8274253bd
19 changed files with 2157 additions and 488 deletions
3
.eslintignore
Normal file
3
.eslintignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
dist/
|
||||
lib/
|
||||
node_modules/
|
|
@ -1,17 +1,19 @@
|
|||
{
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"rules": {
|
||||
}
|
||||
}
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
@ -23,6 +23,9 @@ jobs:
|
|||
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
|
||||
|
@ -103,6 +106,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: rm -rf dist
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: dist
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
__pycache__
|
||||
.python-version
|
||||
|
||||
node_modules
|
||||
lib/
|
||||
node_modules/
|
||||
|
||||
.DS_Store
|
||||
|
|
3
.prettierignore
Normal file
3
.prettierignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
dist/
|
||||
lib/
|
||||
node_modules/
|
11
.prettierrc.json
Normal file
11
.prettierrc.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "avoid",
|
||||
"parser": "typescript"
|
||||
}
|
162
__test__/git.test.ts
Normal file
162
__test__/git.test.ts
Normal file
|
@ -0,0 +1,162 @@
|
|||
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('')
|
||||
})
|
||||
})
|
|
@ -1,3 +1,11 @@
|
|||
process.env = Object.assign(process.env, {
|
||||
GITHUB_WORKSPACE: __dirname
|
||||
});
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.ts'],
|
||||
testRunner: 'jest-circus/runner',
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: true
|
||||
}
|
||||
|
|
1674
package-lock.json
generated
1674
package-lock.json
generated
File diff suppressed because it is too large
Load diff
34
package.json
34
package.json
|
@ -1,21 +1,29 @@
|
|||
{
|
||||
"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": "index.js",
|
||||
"main": "lib/main.js",
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "eslint src/index.js",
|
||||
"test": "eslint src/index.js && jest",
|
||||
"build": "ncc build src/index.js -o 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",
|
||||
"vendor-deps": "pip download -r src/cpr/requirements.txt --no-binary=:all: -d dist/vendor",
|
||||
"package": "npm run build && npm run vendor-deps"
|
||||
"package": "npm run build && npm run pack-assets && npm run vendor-deps"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/peter-evans/create-pull-request.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"keywords": [
|
||||
"actions",
|
||||
"pull",
|
||||
"request"
|
||||
],
|
||||
"author": "Peter Evans",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
|
@ -29,8 +37,18 @@
|
|||
"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": "6.8.0",
|
||||
"jest": "26.0.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"
|
||||
}
|
||||
}
|
||||
|
|
97
src/git.js
97
src/git.js
|
@ -1,97 +0,0 @@
|
|||
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
|
||||
};
|
|
@ -1,98 +0,0 @@
|
|||
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
Normal file
117
src/git.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
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
122
src/index.js
|
@ -1,122 +0,0 @@
|
|||
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"),
|
||||
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
|
||||
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();
|
22
src/isDocker.ts
Normal file
22
src/isDocker.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
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
Normal file
129
src/main.ts
Normal file
|
@ -0,0 +1,129 @@
|
|||
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()
|
|
@ -1,52 +0,0 @@
|
|||
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;
|
50
src/setupPython.ts
Normal file
50
src/setupPython.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
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()
|
||||
})
|
||||
}
|
16
tsconfig.json
Normal file
16
tsconfig.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"outDir": "./lib",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": false,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"exclude": ["__test__", "lib", "node_modules"]
|
||||
}
|
Loading…
Reference in a new issue