Add ability to sign commits through Import GPG GitHub Action
Add author input Fix default committer and author for GitHub Actions bot Replace GITHUB_PAT env var with GH_PAT (#53) Replace committer_name and committer_email inputs with committer
This commit is contained in:
parent
f1d4f1ae95
commit
077e8dcf81
44
README.md
44
README.md
|
@ -12,8 +12,21 @@ If you are interested, [check out](https://git.io/Je09Y) my other :octocat: GitH
|
|||
|
||||

|
||||
|
||||
___
|
||||
|
||||
* [Usage](#usage)
|
||||
* [Workflow](#workflow)
|
||||
* [Sign commits](#sign-commits)
|
||||
* [Customizing](#customizing)
|
||||
* [inputs](#inputs)
|
||||
* [environment variables](#environment-variables)
|
||||
* [How can I help?](#how-can-i-help)
|
||||
* [License](#license)
|
||||
|
||||
## Usage
|
||||
|
||||
### Workflow
|
||||
|
||||
Below is a simple snippet to deploy to GitHub Pages with a dummy HTML page.
|
||||
|
||||
A [workflow](https://github.com/crazy-max/ghaction-github-pages/actions?query=workflow%3Aci) is also available for this repository and deploys [everyday to GitHub pages](https://crazy-max.github.io/ghaction-github-pages/).
|
||||
|
@ -56,6 +69,31 @@ jobs:
|
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
### Sign commits
|
||||
|
||||
You can use the [Import GPG](https://github.com/crazy-max/ghaction-import-gpg) GitHub Action along with this one to sign commits:
|
||||
|
||||
```yaml
|
||||
-
|
||||
name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v1
|
||||
with:
|
||||
git_user_signingkey: true
|
||||
git_commit_gpgsign: true
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
PASSPHRASE: ${{ secrets.PASSPHRASE }}
|
||||
-
|
||||
name: Deploy to GitHub Pages
|
||||
if: success()
|
||||
uses: crazy-max/ghaction-github-pages@v1
|
||||
with:
|
||||
target_branch: gh-pages
|
||||
build_dir: public
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
## Customizing
|
||||
|
||||
### inputs
|
||||
|
@ -69,8 +107,8 @@ Following inputs can be used as `step.with` keys
|
|||
| `keep_history` | Bool | Create incremental commit instead of doing push force (default `false`) |
|
||||
| `allow_empty_commit` | Bool | Allow an empty commit to be created (default `true`) |
|
||||
| `build_dir` | String | Build directory to deploy (**required**) |
|
||||
| `committer_name` | String | Commit author's name (default [GITHUB_ACTOR](https://help.github.com/en/github/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables) or `github-actions`) |
|
||||
| `committer_email` | String | Commit author's email (default `<committer_name>@users.noreply.github.com`) |
|
||||
| `committer` | String | Committer name and email address as `Display Name <joe@foo.bar>` (defaults to the GitHub Actions bot user) |
|
||||
| `author` | String | Author name and email address as `Display Name <joe@foo.bar>` (defaults to the GitHub Actions bot user) |
|
||||
| `commit_message` | String | Commit message (default `Deploy to GitHub pages`) |
|
||||
| `fqdn` | String | Write the given domain name to the CNAME file |
|
||||
|
||||
|
@ -81,7 +119,7 @@ Following environment variables can be used as `step.env` keys
|
|||
| Name | Description |
|
||||
|----------------|---------------------------------------|
|
||||
| `GITHUB_TOKEN` | [GITHUB_TOKEN](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token) as provided by `secrets` |
|
||||
| `GITHUB_PAT` | Use a [Personal Access Token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) if you want to deploy to another repo |
|
||||
| `GH_PAT` | Use a [Personal Access Token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) if you want to deploy to another repo |
|
||||
|
||||
## How can I help?
|
||||
|
||||
|
|
|
@ -25,11 +25,11 @@ inputs:
|
|||
build_dir:
|
||||
description: 'Build directory to deploy'
|
||||
required: true
|
||||
committer_name:
|
||||
description: 'Commit author''s name'
|
||||
committer:
|
||||
description: 'The committer name and email address'
|
||||
required: false
|
||||
committer_email:
|
||||
description: 'Commit author''s email'
|
||||
author:
|
||||
description: 'The author name and email address'
|
||||
required: false
|
||||
commit_message:
|
||||
description: 'Commit message'
|
||||
|
|
594
dist/index.js
generated
vendored
594
dist/index.js
generated
vendored
|
@ -1752,6 +1752,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
|
@ -1760,98 +1763,99 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const child_process = __importStar(__webpack_require__(129));
|
||||
const core = __importStar(__webpack_require__(470));
|
||||
const exec = __importStar(__webpack_require__(986));
|
||||
const addressparser_1 = __importDefault(__webpack_require__(977));
|
||||
const fs_extra_1 = __webpack_require__(226);
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const path = __importStar(__webpack_require__(622));
|
||||
const core = __importStar(__webpack_require__(470));
|
||||
const git = __importStar(__webpack_require__(453));
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const repo = core.getInput('repo') || process.env['GITHUB_REPOSITORY'] || '';
|
||||
const target_branch = core.getInput('target_branch') || 'gh-pages';
|
||||
const keep_history = /true/i.test(core.getInput('keep_history'));
|
||||
const allow_empty_commit = /true/i.test(core.getInput('allow_empty_commit'));
|
||||
const build_dir = core.getInput('build_dir', { required: true });
|
||||
const committer_name = core.getInput('committer_name') || process.env['GITHUB_ACTOR'] || 'github-actions';
|
||||
const committer_email = core.getInput('committer_email') || `${committer_name}@users.noreply.github.com`;
|
||||
const commit_message = core.getInput('commit_message') || 'Deploy to GitHub pages';
|
||||
const targetBranch = core.getInput('target_branch') || git.defaults.targetBranch;
|
||||
const keepHistory = /true/i.test(core.getInput('keep_history'));
|
||||
const allowEmptyCommit = /true/i.test(core.getInput('allow_empty_commit'));
|
||||
const buildDir = core.getInput('build_dir', { required: true });
|
||||
const committer = core.getInput('committer') || git.defaults.committer;
|
||||
const author = core.getInput('author') || git.defaults.author;
|
||||
const commitMessage = core.getInput('commit_message') || git.defaults.message;
|
||||
const fqdn = core.getInput('fqdn');
|
||||
if (!fs.existsSync(build_dir)) {
|
||||
core.setFailed('⛔️ Build dir does not exist');
|
||||
if (!fs.existsSync(buildDir)) {
|
||||
core.setFailed('Build dir does not exist');
|
||||
return;
|
||||
}
|
||||
let remote_url = String('https://');
|
||||
if (process.env['GITHUB_PAT']) {
|
||||
core.info(`✅ Use GITHUB_PAT`);
|
||||
remote_url = remote_url.concat(process.env['GITHUB_PAT'].trim());
|
||||
let remoteURL = String('https://');
|
||||
if (process.env['GH_PAT']) {
|
||||
core.info(`✅ Use GH_PAT`);
|
||||
remoteURL = remoteURL.concat(process.env['GH_PAT'].trim());
|
||||
}
|
||||
else if (process.env['GITHUB_TOKEN']) {
|
||||
core.info(`✅ Use GITHUB_TOKEN`);
|
||||
remote_url = remote_url.concat('x-access-token:', process.env['GITHUB_TOKEN'].trim());
|
||||
remoteURL = remoteURL.concat('x-access-token:', process.env['GITHUB_TOKEN'].trim());
|
||||
}
|
||||
else {
|
||||
core.setFailed('❌️ You have to provide a GITHUB_TOKEN or GITHUB_PAT');
|
||||
core.setFailed('You have to provide a GITHUB_TOKEN or GH_PAT');
|
||||
return;
|
||||
}
|
||||
remote_url = remote_url.concat('@github.com/', repo, '.git');
|
||||
remoteURL = remoteURL.concat('@github.com/', repo, '.git');
|
||||
core.debug(`remoteURL=${remoteURL}`);
|
||||
const remoteBranchExists = yield git.remoteBranchExists(remoteURL, targetBranch);
|
||||
core.debug(`remoteBranchExists=${remoteBranchExists}`);
|
||||
const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'github-pages-'));
|
||||
core.debug(`tmpdir=${tmpdir}`);
|
||||
const currentdir = path.resolve('.');
|
||||
core.debug(`currentdir=${currentdir}`);
|
||||
process.chdir(tmpdir);
|
||||
const remote_branch_exists = child_process.execSync(`git ls-remote --heads ${remote_url} ${target_branch}`, { encoding: 'utf8' }).trim().length >
|
||||
0;
|
||||
if (keep_history && remote_branch_exists) {
|
||||
yield exec.exec('git', ['clone', '--quiet', '--branch', target_branch, '--depth', '1', remote_url, '.']);
|
||||
if (keepHistory && remoteBranchExists) {
|
||||
core.info('🌀 Cloning ${repo}');
|
||||
yield git.clone(remoteURL, targetBranch, '.');
|
||||
}
|
||||
else {
|
||||
core.info(`🏃 Initializing local git repo`);
|
||||
yield exec.exec('git', ['init', '.']);
|
||||
yield exec.exec('git', ['checkout', '--orphan', target_branch]);
|
||||
core.info(`✨ Initializing local git repo`);
|
||||
yield git.init('.');
|
||||
yield git.checkout(targetBranch);
|
||||
}
|
||||
core.info(`🏃 Copying ${path.join(currentdir, build_dir)} contents to ${tmpdir}`);
|
||||
fs_extra_1.copySync(path.join(currentdir, build_dir), tmpdir);
|
||||
core.info(`🏃 Copying ${path.join(currentdir, buildDir)} contents to ${tmpdir}`);
|
||||
yield fs_extra_1.copySync(path.join(currentdir, buildDir), tmpdir);
|
||||
if (fqdn) {
|
||||
core.info(`✍️ Writing ${fqdn} domain name to ${path.join(tmpdir, 'CNAME')}`);
|
||||
fs.writeFileSync(path.join(tmpdir, 'CNAME'), fqdn.trim());
|
||||
yield fs.writeFileSync(path.join(tmpdir, 'CNAME'), fqdn.trim());
|
||||
}
|
||||
const dirty = child_process.execSync(`git status --short`, { encoding: 'utf8' }).trim().length > 0;
|
||||
if (keep_history && remote_branch_exists && !dirty) {
|
||||
core.info('⚠️ There are no changes to commit, stopping.');
|
||||
const isDirty = yield git.isDirty();
|
||||
core.debug(`isDirty=${isDirty}`);
|
||||
if (keepHistory && remoteBranchExists && !isDirty) {
|
||||
core.info('⚠️ No changes to commit');
|
||||
return;
|
||||
}
|
||||
core.info(`🔨 Configuring git committer to be ${committer_name} <${committer_email}>`);
|
||||
yield exec.exec('git', ['config', 'user.name', committer_name]);
|
||||
yield exec.exec('git', ['config', 'user.email', committer_email]);
|
||||
try {
|
||||
child_process.execSync('git status --porcelain').toString();
|
||||
}
|
||||
catch (err) {
|
||||
const committerPrs = addressparser_1.default(committer)[0];
|
||||
core.info(`🔨 Configuring git committer as ${committerPrs.name} <${committerPrs.address}>`);
|
||||
yield git.setConfig('user.name', committerPrs.name);
|
||||
yield git.setConfig('user.email', committerPrs.address);
|
||||
if (!(yield git.hasChanges())) {
|
||||
core.info('⚠️ Nothing to deploy');
|
||||
return;
|
||||
}
|
||||
yield exec.exec('git', ['add', '--all', '.']);
|
||||
let gitCommitCmd = [];
|
||||
gitCommitCmd.push('commit');
|
||||
if (allow_empty_commit) {
|
||||
core.info(`📐 Updating index of working tree`);
|
||||
yield git.add('.');
|
||||
core.info(`📦 Committing changes`);
|
||||
if (allowEmptyCommit) {
|
||||
core.info(`✅ Allow empty commit`);
|
||||
gitCommitCmd.push('--allow-empty');
|
||||
}
|
||||
gitCommitCmd.push('-m', commit_message);
|
||||
yield exec.exec('git', gitCommitCmd);
|
||||
yield exec.exec('git', ['show', '--stat-count=10', 'HEAD']);
|
||||
let gitPushCmd = [];
|
||||
gitPushCmd.push('push', '--quiet');
|
||||
if (!keep_history) {
|
||||
const authorPrs = addressparser_1.default(author)[0];
|
||||
core.info(`🔨 Configuring git author as ${authorPrs.name} <${authorPrs.address}>`);
|
||||
yield git.commit(allowEmptyCommit, `${authorPrs.name} <${authorPrs.address}>`, commitMessage);
|
||||
yield git.showStat(10).then(output => {
|
||||
core.info(output);
|
||||
});
|
||||
core.info(`🏃 Pushing ${buildDir} directory to ${targetBranch} branch on ${repo} repo`);
|
||||
if (!keepHistory) {
|
||||
core.info(`✅ Force push`);
|
||||
gitPushCmd.push('--force');
|
||||
}
|
||||
gitPushCmd.push(remote_url, target_branch);
|
||||
core.info(`🏃 Deploying ${build_dir} directory to ${target_branch} branch on ${repo} repo`);
|
||||
yield exec.exec('git', gitPushCmd);
|
||||
yield git.push(remoteURL, targetBranch, !keepHistory);
|
||||
process.chdir(currentdir);
|
||||
core.info(`🎉 Content of ${build_dir} has been deployed to GitHub Pages.`);
|
||||
core.info(`🎉 Content of ${buildDir} has been deployed to GitHub Pages.`);
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
|
@ -1859,7 +1863,7 @@ function run() {
|
|||
});
|
||||
}
|
||||
run();
|
||||
|
||||
//# sourceMappingURL=main.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
|
@ -2416,6 +2420,136 @@ function escapeProperty(s) {
|
|||
|
||||
/***/ }),
|
||||
|
||||
/***/ 453:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const exec = __importStar(__webpack_require__(807));
|
||||
exports.defaults = {
|
||||
targetBranch: 'gh-pages',
|
||||
committer: 'GitHub <noreply@github.com>',
|
||||
author: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>',
|
||||
message: 'Deploy to GitHub pages'
|
||||
};
|
||||
const git = (args = []) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
return yield exec.exec(`git`, args, true).then(res => {
|
||||
if (res.stderr != '' && !res.success) {
|
||||
throw new Error(res.stderr);
|
||||
}
|
||||
return res.stdout.trim();
|
||||
});
|
||||
});
|
||||
function remoteBranchExists(remoteURL, branch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return yield git(['ls-remote', '--heads', remoteURL, branch]).then(output => {
|
||||
return output.trim().length > 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.remoteBranchExists = remoteBranchExists;
|
||||
function clone(remoteURL, branch, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield git(['clone', '--quiet', '--branch', branch, '--depth', '1', remoteURL, dest]);
|
||||
});
|
||||
}
|
||||
exports.clone = clone;
|
||||
function init(dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield git(['init', dest]);
|
||||
});
|
||||
}
|
||||
exports.init = init;
|
||||
function checkout(branch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield git(['checkout', '--orphan', branch]);
|
||||
});
|
||||
}
|
||||
exports.checkout = checkout;
|
||||
function isDirty() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return yield git(['status', '--short']).then(output => {
|
||||
return output.trim().length > 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.isDirty = isDirty;
|
||||
function hasChanges() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return yield git(['status', '--porcelain']).then(output => {
|
||||
return output.trim().length > 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.hasChanges = hasChanges;
|
||||
function setConfig(key, value) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield git(['config', key, value]);
|
||||
});
|
||||
}
|
||||
exports.setConfig = setConfig;
|
||||
function add(pattern) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield git(['add', '--all', pattern]);
|
||||
});
|
||||
}
|
||||
exports.add = add;
|
||||
function commit(allowEmptyCommit, author, message) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let args = [];
|
||||
args.push('commit');
|
||||
if (allowEmptyCommit) {
|
||||
args.push('--allow-empty');
|
||||
}
|
||||
if (author !== '') {
|
||||
args.push('--author', author);
|
||||
}
|
||||
args.push('--message', message);
|
||||
yield git(args);
|
||||
});
|
||||
}
|
||||
exports.commit = commit;
|
||||
function showStat(count) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return yield git(['show', `--stat-count=${count}`, 'HEAD']).then(output => {
|
||||
return output;
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.showStat = showStat;
|
||||
function push(remoteURL, branch, force) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let args = [];
|
||||
args.push('push', '--quiet');
|
||||
if (force) {
|
||||
args.push('--force');
|
||||
}
|
||||
args.push(remoteURL, branch);
|
||||
yield git(args);
|
||||
});
|
||||
}
|
||||
exports.push = push;
|
||||
//# sourceMappingURL=git.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 469:
|
||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||
|
||||
|
@ -4268,6 +4402,55 @@ module.exports = {
|
|||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 807:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const actionsExec = __importStar(__webpack_require__(986));
|
||||
exports.exec = (command, args = [], silent) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
const options = {
|
||||
silent: silent,
|
||||
ignoreReturnCode: true
|
||||
};
|
||||
options.listeners = {
|
||||
stdout: (data) => {
|
||||
stdout += data.toString();
|
||||
},
|
||||
stderr: (data) => {
|
||||
stderr += data.toString();
|
||||
}
|
||||
};
|
||||
const returnCode = yield actionsExec.exec(command, args, options);
|
||||
return {
|
||||
success: returnCode === 0,
|
||||
stdout: stdout.trim(),
|
||||
stderr: stderr.trim()
|
||||
};
|
||||
});
|
||||
//# sourceMappingURL=exec.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 849:
|
||||
|
@ -4737,6 +4920,305 @@ module.exports = {
|
|||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 977:
|
||||
/***/ (function(module) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
// expose to the world
|
||||
module.exports = addressparser;
|
||||
|
||||
/**
|
||||
* Parses structured e-mail addresses from an address field
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* 'Name <address@domain>'
|
||||
*
|
||||
* will be converted to
|
||||
*
|
||||
* [{name: 'Name', address: 'address@domain'}]
|
||||
*
|
||||
* @param {String} str Address field
|
||||
* @return {Array} An array of address objects
|
||||
*/
|
||||
function addressparser(str) {
|
||||
var tokenizer = new Tokenizer(str);
|
||||
var tokens = tokenizer.tokenize();
|
||||
|
||||
var addresses = [];
|
||||
var address = [];
|
||||
var parsedAddresses = [];
|
||||
|
||||
tokens.forEach(function (token) {
|
||||
if (token.type === 'operator' && (token.value === ',' || token.value === ';')) {
|
||||
if (address.length) {
|
||||
addresses.push(address);
|
||||
}
|
||||
address = [];
|
||||
} else {
|
||||
address.push(token);
|
||||
}
|
||||
});
|
||||
|
||||
if (address.length) {
|
||||
addresses.push(address);
|
||||
}
|
||||
|
||||
addresses.forEach(function (address) {
|
||||
address = _handleAddress(address);
|
||||
if (address.length) {
|
||||
parsedAddresses = parsedAddresses.concat(address);
|
||||
}
|
||||
});
|
||||
|
||||
return parsedAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts tokens for a single address into an address object
|
||||
*
|
||||
* @param {Array} tokens Tokens object
|
||||
* @return {Object} Address object
|
||||
*/
|
||||
function _handleAddress(tokens) {
|
||||
var token;
|
||||
var isGroup = false;
|
||||
var state = 'text';
|
||||
var address;
|
||||
var addresses = [];
|
||||
var data = {
|
||||
address: [],
|
||||
comment: [],
|
||||
group: [],
|
||||
text: []
|
||||
};
|
||||
var i;
|
||||
var len;
|
||||
|
||||
// Filter out <addresses>, (comments) and regular text
|
||||
for (i = 0, len = tokens.length; i < len; i++) {
|
||||
token = tokens[i];
|
||||
if (token.type === 'operator') {
|
||||
switch (token.value) {
|
||||
case '<':
|
||||
state = 'address';
|
||||
break;
|
||||
case '(':
|
||||
state = 'comment';
|
||||
break;
|
||||
case ':':
|
||||
state = 'group';
|
||||
isGroup = true;
|
||||
break;
|
||||
default:
|
||||
state = 'text';
|
||||
}
|
||||
} else if (token.value) {
|
||||
if (state === 'address') {
|
||||
// handle use case where unquoted name includes a "<"
|
||||
// Apple Mail truncates everything between an unexpected < and an address
|
||||
// and so will we
|
||||
token.value = token.value.replace(/^[^<]*<\s*/, '');
|
||||
}
|
||||
data[state].push(token.value);
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no text but a comment, replace the two
|
||||
if (!data.text.length && data.comment.length) {
|
||||
data.text = data.comment;
|
||||
data.comment = [];
|
||||
}
|
||||
|
||||
if (isGroup) {
|
||||
// http://tools.ietf.org/html/rfc2822#appendix-A.1.3
|
||||
data.text = data.text.join(' ');
|
||||
addresses.push({
|
||||
name: data.text || (address && address.name),
|
||||
group: data.group.length ? addressparser(data.group.join(',')) : []
|
||||
});
|
||||
} else {
|
||||
// If no address was found, try to detect one from regular text
|
||||
if (!data.address.length && data.text.length) {
|
||||
for (i = data.text.length - 1; i >= 0; i--) {
|
||||
if (data.text[i].match(/^[^@\s]+@[^@\s]+$/)) {
|
||||
data.address = data.text.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var _regexHandler = function (address) {
|
||||
if (!data.address.length) {
|
||||
data.address = [address.trim()];
|
||||
return ' ';
|
||||
} else {
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
// still no address
|
||||
if (!data.address.length) {
|
||||
for (i = data.text.length - 1; i >= 0; i--) {
|
||||
// fixed the regex to parse email address correctly when email address has more than one @
|
||||
data.text[i] = data.text[i].replace(/\s*\b[^@\s]+@[^\s]+\b\s*/, _regexHandler).trim();
|
||||
if (data.address.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's still is no text but a comment exixts, replace the two
|
||||
if (!data.text.length && data.comment.length) {
|
||||
data.text = data.comment;
|
||||
data.comment = [];
|
||||
}
|
||||
|
||||
// Keep only the first address occurence, push others to regular text
|
||||
if (data.address.length > 1) {
|
||||
data.text = data.text.concat(data.address.splice(1));
|
||||
}
|
||||
|
||||
// Join values with spaces
|
||||
data.text = data.text.join(' ');
|
||||
data.address = data.address.join(' ');
|
||||
|
||||
if (!data.address && isGroup) {
|
||||
return [];
|
||||
} else {
|
||||
address = {
|
||||
address: data.address || data.text || '',
|
||||
name: data.text || data.address || ''
|
||||
};
|
||||
|
||||
if (address.address === address.name) {
|
||||
if ((address.address || '').match(/@/)) {
|
||||
address.name = '';
|
||||
} else {
|
||||
address.address = '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addresses.push(address);
|
||||
}
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Tokenizer object for tokenizing address field strings
|
||||
*
|
||||
* @constructor
|
||||
* @param {String} str Address field string
|
||||
*/
|
||||
function Tokenizer(str) {
|
||||
this.str = (str || '').toString();
|
||||
this.operatorCurrent = '';
|
||||
this.operatorExpecting = '';
|
||||
this.node = null;
|
||||
this.escaped = false;
|
||||
|
||||
this.list = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator tokens and which tokens are expected to end the sequence
|
||||
*/
|
||||
Tokenizer.prototype.operators = {
|
||||
'"': '"',
|
||||
'(': ')',
|
||||
'<': '>',
|
||||
',': '',
|
||||
':': ';',
|
||||
// Semicolons are not a legal delimiter per the RFC2822 grammar other
|
||||
// than for terminating a group, but they are also not valid for any
|
||||
// other use in this context. Given that some mail clients have
|
||||
// historically allowed the semicolon as a delimiter equivalent to the
|
||||
// comma in their UI, it makes sense to treat them the same as a comma
|
||||
// when used outside of a group.
|
||||
';': ''
|
||||
};
|
||||
|
||||
/**
|
||||
* Tokenizes the original input string
|
||||
*
|
||||
* @return {Array} An array of operator|text tokens
|
||||
*/
|
||||
Tokenizer.prototype.tokenize = function () {
|
||||
var chr, list = [];
|
||||
for (var i = 0, len = this.str.length; i < len; i++) {
|
||||
chr = this.str.charAt(i);
|
||||
this.checkChar(chr);
|
||||
}
|
||||
|
||||
this.list.forEach(function (node) {
|
||||
node.value = (node.value || '').toString().trim();
|
||||
if (node.value) {
|
||||
list.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a character is an operator or text and acts accordingly
|
||||
*
|
||||
* @param {String} chr Character from the address field
|
||||
*/
|
||||
Tokenizer.prototype.checkChar = function (chr) {
|
||||
if ((chr in this.operators || chr === '\\') && this.escaped) {
|
||||
this.escaped = false;
|
||||
} else if (this.operatorExpecting && chr === this.operatorExpecting) {
|
||||
this.node = {
|
||||
type: 'operator',
|
||||
value: chr
|
||||
};
|
||||
this.list.push(this.node);
|
||||
this.node = null;
|
||||
this.operatorExpecting = '';
|
||||
this.escaped = false;
|
||||
return;
|
||||
} else if (!this.operatorExpecting && chr in this.operators) {
|
||||
this.node = {
|
||||
type: 'operator',
|
||||
value: chr
|
||||
};
|
||||
this.list.push(this.node);
|
||||
this.node = null;
|
||||
this.operatorExpecting = this.operators[chr];
|
||||
this.escaped = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.escaped && chr === '\\') {
|
||||
this.escaped = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.node) {
|
||||
this.node = {
|
||||
type: 'text',
|
||||
value: ''
|
||||
};
|
||||
this.list.push(this.node);
|
||||
}
|
||||
|
||||
if (this.escaped && chr !== '\\') {
|
||||
this.node.value += '\\';
|
||||
}
|
||||
|
||||
this.node.value += chr;
|
||||
this.escaped = false;
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 986:
|
||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -42,6 +42,11 @@
|
|||
"integrity": "sha512-Qq3bMuonkcnV/96jhy9SQYdh39NXHxNMJ1O31ZFzWG9n52fR2DLtgrNzhj/ahlEjnBziMLGVWDbaS9sf03/fEw==",
|
||||
"dev": true
|
||||
},
|
||||
"addressparser": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
|
||||
"integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y="
|
||||
},
|
||||
"at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/crazy-max/ghaction-docker-buildx.git"
|
||||
"url": "git+https://github.com/crazy-max/ghaction-github-pages.git"
|
||||
},
|
||||
"keywords": [
|
||||
"actions",
|
||||
|
@ -24,6 +24,7 @@
|
|||
"dependencies": {
|
||||
"@actions/core": "^1.2.4",
|
||||
"@actions/exec": "^1.0.4",
|
||||
"addressparser": "^1.0.1",
|
||||
"fs-extra": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -36,4 +37,4 @@
|
|||
"typescript": "^3.8.3",
|
||||
"typescript-formatter": "^7.2.2"
|
||||
}
|
||||
}
|
||||
}
|
24
src/addressparser.d.ts
vendored
Normal file
24
src/addressparser.d.ts
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
declare namespace addressparser {
|
||||
interface Address {
|
||||
name: string;
|
||||
address: string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses structured e-mail addresses from an address field
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* 'Name <address@domain>'
|
||||
*
|
||||
* will be converted to
|
||||
*
|
||||
* [{name: 'Name', address: 'address@domain'}]
|
||||
*
|
||||
* @param str Address field
|
||||
* @return An array of address objects
|
||||
*/
|
||||
declare function addressparser(address: string): addressparser.Address[];
|
||||
|
||||
export = addressparser;
|
34
src/exec.ts
Normal file
34
src/exec.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import * as actionsExec from '@actions/exec';
|
||||
import {ExecOptions} from '@actions/exec';
|
||||
|
||||
export interface ExecResult {
|
||||
success: boolean;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
}
|
||||
|
||||
export const exec = async (command: string, args: string[] = [], silent: boolean): Promise<ExecResult> => {
|
||||
let stdout: string = '';
|
||||
let stderr: string = '';
|
||||
|
||||
const options: ExecOptions = {
|
||||
silent: silent,
|
||||
ignoreReturnCode: true
|
||||
};
|
||||
options.listeners = {
|
||||
stdout: (data: Buffer) => {
|
||||
stdout += data.toString();
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
stderr += data.toString();
|
||||
}
|
||||
};
|
||||
|
||||
const returnCode: number = await actionsExec.exec(command, args, options);
|
||||
|
||||
return {
|
||||
success: returnCode === 0,
|
||||
stdout: stdout.trim(),
|
||||
stderr: stderr.trim()
|
||||
};
|
||||
};
|
84
src/git.ts
Normal file
84
src/git.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import * as exec from './exec';
|
||||
|
||||
export const defaults = {
|
||||
targetBranch: 'gh-pages',
|
||||
committer: 'GitHub <noreply@github.com>',
|
||||
author: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>',
|
||||
message: 'Deploy to GitHub pages'
|
||||
};
|
||||
|
||||
const git = async (args: string[] = []): Promise<string> => {
|
||||
return await exec.exec(`git`, args, true).then(res => {
|
||||
if (res.stderr != '' && !res.success) {
|
||||
throw new Error(res.stderr);
|
||||
}
|
||||
return res.stdout.trim();
|
||||
});
|
||||
};
|
||||
|
||||
export async function remoteBranchExists(remoteURL: string, branch: string): Promise<boolean> {
|
||||
return await git(['ls-remote', '--heads', remoteURL, branch]).then(output => {
|
||||
return output.trim().length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
export async function clone(remoteURL: string, branch: string, dest: string): Promise<void> {
|
||||
await git(['clone', '--quiet', '--branch', branch, '--depth', '1', remoteURL, dest]);
|
||||
}
|
||||
|
||||
export async function init(dest: string): Promise<void> {
|
||||
await git(['init', dest]);
|
||||
}
|
||||
|
||||
export async function checkout(branch: string): Promise<void> {
|
||||
await git(['checkout', '--orphan', branch]);
|
||||
}
|
||||
|
||||
export async function isDirty(): Promise<boolean> {
|
||||
return await git(['status', '--short']).then(output => {
|
||||
return output.trim().length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
export async function hasChanges(): Promise<boolean> {
|
||||
return await git(['status', '--porcelain']).then(output => {
|
||||
return output.trim().length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
export async function setConfig(key: string, value: string): Promise<void> {
|
||||
await git(['config', key, value]);
|
||||
}
|
||||
|
||||
export async function add(pattern: string): Promise<void> {
|
||||
await git(['add', '--all', pattern]);
|
||||
}
|
||||
|
||||
export async function commit(allowEmptyCommit: boolean, author: string, message: string): Promise<void> {
|
||||
let args: Array<string> = [];
|
||||
args.push('commit');
|
||||
if (allowEmptyCommit) {
|
||||
args.push('--allow-empty');
|
||||
}
|
||||
if (author !== '') {
|
||||
args.push('--author', author);
|
||||
}
|
||||
args.push('--message', message);
|
||||
await git(args);
|
||||
}
|
||||
|
||||
export async function showStat(count: number): Promise<string> {
|
||||
return await git(['show', `--stat-count=${count}`, 'HEAD']).then(output => {
|
||||
return output;
|
||||
});
|
||||
}
|
||||
|
||||
export async function push(remoteURL: string, branch: string, force: boolean): Promise<void> {
|
||||
let args: Array<string> = [];
|
||||
args.push('push', '--quiet');
|
||||
if (force) {
|
||||
args.push('--force');
|
||||
}
|
||||
args.push(remoteURL, branch);
|
||||
await git(args);
|
||||
}
|
114
src/main.ts
114
src/main.ts
|
@ -1,107 +1,107 @@
|
|||
import * as child_process from 'child_process';
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import addressparser from 'addressparser';
|
||||
import {copySync} from 'fs-extra';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as git from './git';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const repo: string = core.getInput('repo') || process.env['GITHUB_REPOSITORY'] || '';
|
||||
const target_branch: string = core.getInput('target_branch') || 'gh-pages';
|
||||
const keep_history: boolean = /true/i.test(core.getInput('keep_history'));
|
||||
const allow_empty_commit: boolean = /true/i.test(core.getInput('allow_empty_commit'));
|
||||
const build_dir: string = core.getInput('build_dir', {required: true});
|
||||
const committer_name: string = core.getInput('committer_name') || process.env['GITHUB_ACTOR'] || 'github-actions';
|
||||
const committer_email: string = core.getInput('committer_email') || `${committer_name}@users.noreply.github.com`;
|
||||
const commit_message: string = core.getInput('commit_message') || 'Deploy to GitHub pages';
|
||||
const targetBranch: string = core.getInput('target_branch') || git.defaults.targetBranch;
|
||||
const keepHistory: boolean = /true/i.test(core.getInput('keep_history'));
|
||||
const allowEmptyCommit: boolean = /true/i.test(core.getInput('allow_empty_commit'));
|
||||
const buildDir: string = core.getInput('build_dir', {required: true});
|
||||
const committer: string = core.getInput('committer') || git.defaults.committer;
|
||||
const author: string = core.getInput('author') || git.defaults.author;
|
||||
const commitMessage: string = core.getInput('commit_message') || git.defaults.message;
|
||||
const fqdn: string = core.getInput('fqdn');
|
||||
|
||||
if (!fs.existsSync(build_dir)) {
|
||||
core.setFailed('⛔️ Build dir does not exist');
|
||||
if (!fs.existsSync(buildDir)) {
|
||||
core.setFailed('Build dir does not exist');
|
||||
return;
|
||||
}
|
||||
|
||||
let remote_url = String('https://');
|
||||
if (process.env['GITHUB_PAT']) {
|
||||
core.info(`✅ Use GITHUB_PAT`);
|
||||
remote_url = remote_url.concat(process.env['GITHUB_PAT'].trim());
|
||||
let remoteURL = String('https://');
|
||||
if (process.env['GH_PAT']) {
|
||||
core.info(`✅ Use GH_PAT`);
|
||||
remoteURL = remoteURL.concat(process.env['GH_PAT'].trim());
|
||||
} else if (process.env['GITHUB_TOKEN']) {
|
||||
core.info(`✅ Use GITHUB_TOKEN`);
|
||||
remote_url = remote_url.concat('x-access-token:', process.env['GITHUB_TOKEN'].trim());
|
||||
remoteURL = remoteURL.concat('x-access-token:', process.env['GITHUB_TOKEN'].trim());
|
||||
} else {
|
||||
core.setFailed('❌️ You have to provide a GITHUB_TOKEN or GITHUB_PAT');
|
||||
core.setFailed('You have to provide a GITHUB_TOKEN or GH_PAT');
|
||||
return;
|
||||
}
|
||||
remote_url = remote_url.concat('@github.com/', repo, '.git');
|
||||
remoteURL = remoteURL.concat('@github.com/', repo, '.git');
|
||||
core.debug(`remoteURL=${remoteURL}`);
|
||||
|
||||
const remoteBranchExists: boolean = await git.remoteBranchExists(remoteURL, targetBranch);
|
||||
core.debug(`remoteBranchExists=${remoteBranchExists}`);
|
||||
const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'github-pages-'));
|
||||
core.debug(`tmpdir=${tmpdir}`);
|
||||
const currentdir = path.resolve('.');
|
||||
core.debug(`currentdir=${currentdir}`);
|
||||
|
||||
process.chdir(tmpdir);
|
||||
|
||||
const remote_branch_exists =
|
||||
child_process.execSync(`git ls-remote --heads ${remote_url} ${target_branch}`, {encoding: 'utf8'}).trim().length >
|
||||
0;
|
||||
if (keep_history && remote_branch_exists) {
|
||||
await exec.exec('git', ['clone', '--quiet', '--branch', target_branch, '--depth', '1', remote_url, '.']);
|
||||
if (keepHistory && remoteBranchExists) {
|
||||
core.info('🌀 Cloning ${repo}');
|
||||
await git.clone(remoteURL, targetBranch, '.');
|
||||
} else {
|
||||
core.info(`🏃 Initializing local git repo`);
|
||||
await exec.exec('git', ['init', '.']);
|
||||
await exec.exec('git', ['checkout', '--orphan', target_branch]);
|
||||
core.info(`✨ Initializing local git repo`);
|
||||
await git.init('.');
|
||||
await git.checkout(targetBranch);
|
||||
}
|
||||
|
||||
core.info(`🏃 Copying ${path.join(currentdir, build_dir)} contents to ${tmpdir}`);
|
||||
copySync(path.join(currentdir, build_dir), tmpdir);
|
||||
core.info(`🏃 Copying ${path.join(currentdir, buildDir)} contents to ${tmpdir}`);
|
||||
await copySync(path.join(currentdir, buildDir), tmpdir);
|
||||
|
||||
if (fqdn) {
|
||||
core.info(`✍️ Writing ${fqdn} domain name to ${path.join(tmpdir, 'CNAME')}`);
|
||||
fs.writeFileSync(path.join(tmpdir, 'CNAME'), fqdn.trim());
|
||||
await fs.writeFileSync(path.join(tmpdir, 'CNAME'), fqdn.trim());
|
||||
}
|
||||
|
||||
const dirty = child_process.execSync(`git status --short`, {encoding: 'utf8'}).trim().length > 0;
|
||||
if (keep_history && remote_branch_exists && !dirty) {
|
||||
core.info('⚠️ There are no changes to commit, stopping.');
|
||||
const isDirty: boolean = await git.isDirty();
|
||||
core.debug(`isDirty=${isDirty}`);
|
||||
if (keepHistory && remoteBranchExists && !isDirty) {
|
||||
core.info('⚠️ No changes to commit');
|
||||
return;
|
||||
}
|
||||
|
||||
core.info(`🔨 Configuring git committer to be ${committer_name} <${committer_email}>`);
|
||||
await exec.exec('git', ['config', 'user.name', committer_name]);
|
||||
await exec.exec('git', ['config', 'user.email', committer_email]);
|
||||
const committerPrs: addressparser.Address = addressparser(committer)[0];
|
||||
core.info(`🔨 Configuring git committer as ${committerPrs.name} <${committerPrs.address}>`);
|
||||
await git.setConfig('user.name', committerPrs.name);
|
||||
await git.setConfig('user.email', committerPrs.address);
|
||||
|
||||
try {
|
||||
child_process.execSync('git status --porcelain').toString();
|
||||
} catch (err) {
|
||||
if (!(await git.hasChanges())) {
|
||||
core.info('⚠️ Nothing to deploy');
|
||||
return;
|
||||
}
|
||||
|
||||
await exec.exec('git', ['add', '--all', '.']);
|
||||
core.info(`📐 Updating index of working tree`);
|
||||
await git.add('.');
|
||||
|
||||
let gitCommitCmd: Array<string> = [];
|
||||
gitCommitCmd.push('commit');
|
||||
if (allow_empty_commit) {
|
||||
core.info(`📦 Committing changes`);
|
||||
if (allowEmptyCommit) {
|
||||
core.info(`✅ Allow empty commit`);
|
||||
gitCommitCmd.push('--allow-empty');
|
||||
}
|
||||
gitCommitCmd.push('-m', commit_message);
|
||||
await exec.exec('git', gitCommitCmd);
|
||||
const authorPrs: addressparser.Address = addressparser(author)[0];
|
||||
core.info(`🔨 Configuring git author as ${authorPrs.name} <${authorPrs.address}>`);
|
||||
await git.commit(allowEmptyCommit, `${authorPrs.name} <${authorPrs.address}>`, commitMessage);
|
||||
await git.showStat(10).then(output => {
|
||||
core.info(output);
|
||||
});
|
||||
|
||||
await exec.exec('git', ['show', '--stat-count=10', 'HEAD']);
|
||||
|
||||
let gitPushCmd: Array<string> = [];
|
||||
gitPushCmd.push('push', '--quiet');
|
||||
if (!keep_history) {
|
||||
core.info(`🏃 Pushing ${buildDir} directory to ${targetBranch} branch on ${repo} repo`);
|
||||
if (!keepHistory) {
|
||||
core.info(`✅ Force push`);
|
||||
gitPushCmd.push('--force');
|
||||
}
|
||||
gitPushCmd.push(remote_url, target_branch);
|
||||
|
||||
core.info(`🏃 Deploying ${build_dir} directory to ${target_branch} branch on ${repo} repo`);
|
||||
await exec.exec('git', gitPushCmd);
|
||||
await git.push(remoteURL, targetBranch, !keepHistory);
|
||||
|
||||
process.chdir(currentdir);
|
||||
core.info(`🎉 Content of ${build_dir} has been deployed to GitHub Pages.`);
|
||||
core.info(`🎉 Content of ${buildDir} has been deployed to GitHub Pages.`);
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"noImplicitAny": false,
|
||||
"esModuleInterop": true
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
"exclude": ["node_modules", "**/*.test.ts"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user