Execute any comment from issues and pull requests on GitHub

栏目: IT技术 · 发布时间: 4年前

内容简介:Execute comment from issues and pull requestsYou can make GitHub Actions Bot to say "hello, world".Post comment below on your issue or pull request.

actions-comment-run

Execute comment from issues and pull requests

Say "hello, world"

You can make GitHub Actions Bot to say "hello, world".

Post comment below on your issue or pull request.

Execute any comment from issues and pull requests on GitHub

For shorter, you can use as follows.

@github-actions run

```js
(async () => {
  await postComment("hello, world`");
})();
```

Introduce this action

Put .github/workflows/comment-run.yml to introduce comment-run.

# .github/workflows/comment-run.yml
name: "Comment run"
on:
  issue_comment:
    types: [created, edited]

jobs:
  comment-run:
    runs-on: ubuntu-18.04
    steps:
    - uses: actions/checkout@v2
      with:
        # 0 indicates all history
        fetch-depth: 0
    - uses: nwtgck/actions-comment-run@v1.0
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        allowed-associations: '["OWNER"]'

You can introduce comment-run with the following command.

mkdir -p .github/workflows/ && cd .github/workflows/ && wget https://gist.githubusercontent.com/nwtgck/a9b291f6869db42ecc3d9e30d0a0494c/raw/comment-run.yml

After introducing this, create new issue or pull request and post @github-actions run comment.

Comment author who can run scripts

By default, only owner can execute the scripts. You can change allowed-associations: '["OWNER"]' in the yaml above.

Here are examples.

allowed-associations: '["OWNER"]'
allowed-associations: '["OWNER", "MEMBER"]'
allowed-associations: '["OWNER", "COLLABORATOR"]'

Learn more: CommentAuthorAssociation | GitHub Developer Guide

Useful examples

LGTM Image

Post random LGTM image with LGTM.in/g .

Execute any comment from issues and pull requests on GitHub

@github-actions run

<details>
<summary>LGTM :+1: </summary>

```js
(async () => {
  const res = await fetch("https://lgtm.in/g", {
    redirect: 'manual'
  });
  const webSiteUrl = res.headers.get('location');
  const picUrl = new URL(webSiteUrl);
  picUrl.pathname = picUrl.pathname.replace("/i/", "/p/");
  postComment(`![LGTM](${picUrl.href})`);
})();
```
</details>

Update all npm packages

Although Dependabot is useful, sometimes you might think bump all packages up. This comment allows you to do this.

Execute any comment from issues and pull requests on GitHub

@github-actions run

```js
function exec(cmd) {
  console.log(execSync(cmd).toString());
}

// Config
const gitUserEmail = "github-actions[bot]@users.noreply.github.com";
const gitUserName = "github-actions[bot]";
const prBranchName = "comment-run/npm-update";

const baseBranchName = context.payload.repository.default_branch";
exec(`git config --global user.email "${gitUserEmail}"`);
exec(`git config --global user.name "${gitUserName}"`);
exec(`git fetch --all`);
exec(`git checkout ${baseBranchName}`);
exec(`git checkout -b ${prBranchName}`);

const packageJson = JSON.parse(require('fs').readFileSync('package.json'));
const depStr = Object.keys(packageJson.dependencies || {}).join(' ');
const devDepStr = Object.keys(packageJson.devDependencies || {}).join(' ');
exec(`npm i ${depStr} ${devDepStr}`);

exec("git status");
exec("git add package*json");
exec(`git commit -m 'chore(deps): update npm dependencies'`);
exec(`git push -fu origin ${prBranchName}`);

(async () => {
  await githubClient.pulls.create({
    base: baseBranchName,
    head: prBranchName,
    owner: context.repo.owner,
    repo: context.repo.repo,
    title: "chore(deps): update npm dependencies",
    body: "update npm dependencies",
  });
})();
```

PR merge preview

GitHub Actions do not pass secrets to pull request from forked repositories. This security feature may restricts GitHub Actions usages. This comment is created to resolve the problem

Execute any comment from issues and pull requests on GitHub

@github-actions run

<details>
<summary>:rocket: Merge preview</summary>

```js
(async () => {
  // Get pull-req URL like "https://api.github.com/repos/nwtgck/actions-merge-preview/pulls/4"
  const pullReqUrl = context.payload.issue.pull_request.url;
  const githubUser = context.payload.repository.owner.login;
  const res = await fetch(pullReqUrl, {
    headers: [
      ['Authorization', `Basic ${Buffer.from(`${githubUser}:${githubToken}`).toString('base64')}`]
    ]
  });
  const resJson = await res.json();
  const prUserName = resJson.head.user.login;
  const baseBranchName = resJson.base.ref;
  const branchName = resJson.head.ref;
  const fullRepoName = resJson.head.repo.full_name;
  const previewBranchName = `actions-merge-preview/${prUserName}-${branchName}`;
  execSync(`git config --global user.email "github-actions[bot]@users.noreply.github.com"`);
  execSync(`git config --global user.name "github-actions[bot]"`);
  // (from: https://stackoverflow.com/a/23987039/2885946)
  execSync(`git fetch --all`);
  console.log(execSync(`git checkout ${baseBranchName}`).toString());
  console.log(execSync(`git checkout -b ${previewBranchName} ${baseBranchName}`).toString());
  console.log(execSync(`git pull https://github.com/${fullRepoName}.git ${branchName}`).toString());
  // Push preview branch
  // NOTE: Force push (should be safe because preview branch always start with "actions-merge-preview/")
  execSync(`git push -fu origin ${previewBranchName}`);
  const baseRepoFullName = context.payload.repository.full_name;
  // Create GitHub client
  const githubClient = new GitHub(githubToken);
  // Comment body
  const commentBody = `:rocket: Preview branch:  \n<https://github.com/${baseRepoFullName}/tree/${previewBranchName}>`;
  // Comment the deploy URL
  await postComment(commentBody);
})();
```
</details>

SSH in GitHub Actions over Piping Server

This comment allows you to go inside of GitHub Actions environment.

Execute any comment from issues and pull requests on GitHub

Execute any comment from issues and pull requests on GitHub

@github-actions run

<details>
<summary>:globe_with_meridians: SSH debug over Piping Server</summary>

```js
(async () => {
  const pathLen = 64;
  const aPath = randomString(pathLen);
  const bPath = randomString(pathLen);

  console.log(execSync(`
chmod 755 "$HOME"
ls -lA /home
authorized_keys_file="$(sshd -T 2>/dev/null | grep -E '^authorizedkeysfile ' | cut -d ' ' -f 2)"
authorized_keys_file="$(cd && realpath -m "$authorized_keys_file")"
sshd_config_dir="$(dirname "$authorized_keys_file")"
(umask 0077 && mkdir "$sshd_config_dir")
echo $authorized_keys_file;

# (from: https://qiita.com/zackey2/items/429c77e5780ba8bc1bf9#authorized_keys%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
(echo; curl https://github.com/nwtgck.keys; echo) >> ~/.ssh/authorized_keys

sudo apt install -y socat;
`).toString());

    // Comment new session
    const commentBody = `\
## :globe_with_meridians: New SSH session
Run the commands below in different terminals.

\`\`\`bash
socat TCP-LISTEN:31376 'EXEC:curl -NsS https\\://ppng.io/${bPath}!!EXEC:curl -NsST - https\\://ppng.io/${aPath}'
\`\`\`

\`\`\`bash
ssh-keygen -R '[localhost]:31376'
ssh -p 31376 runner@localhost
\`\`\`

`;
  await githubClient.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: commentBody
  });

  execSync(`socat 'EXEC:curl -NsS https\\://ppng.io/${aPath}!!EXEC:curl -NsST - https\\://ppng.io/${bPath}' TCP:127.0.0.1:22`);
})();

// (from: https://stackoverflow.com/a/1349426/2885946)
function randomString(length) {
  let result           = '';
  const characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const charactersLength = characters.length;
  for ( var i = 0; i < length; i++ ) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}
```

## References
* <https://github.com/Cryolite/gha-sandbox/blob/789130f01504a372775be9a2fe4d8df6c4e0ce5c/.github/workflows/ssh.yaml>)
* <https://qiita.com/Cryolite/items/ed8fa237dd8eab54ef2f>

Thanks Cryolite!

</details>

TIPS: Saved replies

"Saved replies" fits this action very much.

Execute any comment from issues and pull requests on GitHub

You can save "Saved replies" as follows.

Avatar icon > Settings > Saved replies

TIPS: Run other languages

This action supports shebang ( #! ), so you can run shell and Python as follows.

@github-actions run

```sh
#! /bin/sh
pip install numpy
```

```py
#! /usr/bin/python
import numpy as np

print(np.array([1, 2, 3]))
```

Here are examples.

TIPS: Use existing package, TypeScript and manage on GitHub

When your comment-run scripts are matured, you might want to use TypeScript for maintainability. The following repository uses existing npm packages and TypeScript.

https://github.com/nwtgck/comment-run-scripts

Built bundle .js files are hosted on GitHub Pages. So, your comment will be as follows.

@github-actions run

```js
(async () => {
  const url = "https://nwtgck.github.io/comment-run-scripts/hello-world-comment.js";
  const js = await (await fetch(url)).text();
  eval(js);
})();
```

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员之禅

程序员之禅

[德] Christian Grobmeier / 荣耀、朱艳 / 人民邮电出版社 / 2015-8 / 39.00元

禅是一种生活态度和生活方式。程序员是一份特别辛苦的职业,也是一个承受各种压力的群体。在物欲横流的今天,禅对于程序员有着特殊的意义和价值。 本书的作者是一名德国程序员老兵,深谙程序员的喜怒哀乐。他曾经发表了一篇题为“程序员之禅的十条法则”的博客文章,引发众多程序员热烈的讨论和强烈的共鸣。本书共10章,结合程序员日常生活和工作的方方面面,作者通过对禅的知识、理解、体验、思考和感悟,提出很多中肯的......一起来看看 《程序员之禅》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具