GitHub Actionsでプルリクのコメントに複数行テキストを投稿する
GitHub Actionsで複数行テキストの取り扱いに苦戦したので、検証結果を残しておく。
目的
GitHub Actionsから、トリガー元のプルリクエストに対して複数行テキストのコメント投稿を実証する。
想定は、CIの実行結果をプルリクエストにコメントで記載するようなユースケース。
検証コード
最初に、テキストを整形するためのfront_matter
とback_matter
を生成している。
その後は2回、set-outputで出力結果を渡すことでプルリクへの書き込みを試みる。
1回目はset-outputを行う前に改行文字をエンコードしていないため、後続処理には1行分のテキストしか渡すことができない。
2回目はset-outputを行う前に改行文字をエンコードしているため、後続処理に複数行のテキストを渡すことができる。
プルリクエストへコメントを投稿するActionsは幾つか存在するが、今回はPR Commentを使用した。
steps:
- uses: actions/checkout@v2
- name: Generate front_matter and back_matter
run: |
echo "# Comment by GitHub Actions
<pre><details>
<summary> post_comment_to_pr.yml </summary>
<code>" > front_matter
echo "</code></details></pre>" > back_matter
- name: No escape text
id: no_escape
run: |
text=`cat front_matter .github/workflows/post_comment_to_pr.yml back_matter`
echo "::set-output name=message_body::$text"
- uses: github-actions-up-and-running/pr-comment@v1.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
message: ${{ steps.no_escape.outputs.message_body }}
- name: Escape newline characters by URL encoding
id: multiline
run: |
text=`cat front_matter .github/workflows/post_comment_to_pr.yml back_matter`
text="${text//'%'/'%25'}"
text="${text//$'\n'/'%0A'}"
text="${text//$'\r'/'%0D'}"
echo "::set-output name=message_body::$text"
- uses: github-actions-up-and-running/pr-comment@v1.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
message: ${{ steps.multiline.outputs.message_body }}
ファイル全体はこちら(GitHub)を参照。
検証コードの実行結果
先に検証コードの実行結果から。
プルリクエストには2つのコメントが投稿される。
1つ目はset-outputを行う前に改行文字をエンコードしなかった場合であり、このときのコメントは一行目しか投稿されない。
2つ目はset-outputを行う前に改行文字をエンコードした場合であり、以下のようにコメントが正しく投稿される。
これは、クリックすることで複数行のテキスト部を展開して表示することができる。
検証コードでやっていること
set-outputで値を出力し、後続処理で読み出せるようにする
とある処理の実行結果を後続処理で使用したい場合、set-outputという仕組みが利用できる。
以下のコードでは、text
に代入した内容をset-outputでmessage_body
にセットしている。
- name: No escape text
id: no_escape
run: |
text=`cat .github/workflows/post_comment_to_pr.yml`
echo "::set-output name=message_body::$text"
こうすることで、後続処理ではtext
の内容を${{ steps.no_escape.outputs.message_body }}
として参照できるようになる。
改行文字列をURLエンコードする
set-outputでは1行のテキストしか代入できないが、改行文字列をURLエンコードすればこの制限を回避できるようだ。
これはGitHubのSupport Communityに記載されている情報。
検証コードでは以下の箇所が該当する。
text="${text//'%'/'%25'}"
text="${text//$'\n'/'%0A'}"
text="${text//$'\r'/'%0D'}"
detailsタグ等を使い、見やすくする
(これはGitHub ActionsというよりもMarkdownやHTMLの話であるが)
PRのコメントに書き込む内容が数十行に渡る場合、スクロールが大変になる。
特に、PRの対象ブランチへPushするたびにワークフローが実行される場合は顕著となる。
そのため、検証コードではdetailsタグ等を用いることで表示領域を小さく抑えている。
以下のようにMultiline Text
をfront_matter
とback_matter
で挟んでPRに投稿している。
# Comment by GitHub Actions
<pre><details>
<summary>post_comment_to_pr.yml</summary>
<code>Multiline
Text</code>
</details></pre>
注意
ここで書いた検証コードでは、タグのエスケープ処理を行っていない。
そのためfront_matter
とback_matter
の間のテキストにタグが含まれると、以下のように表示が崩れる要因となる。
CIなどで使う程度であれば実際には問題にならない場合が多いと思われるが、これは一種の脆弱性であるため要注意。
特に、信頼できない人による入力が想定される場合はエスケープ処理を行うこと。