Setting GitHub actions is a headache, and it takes time to run correctly. I’ll share what actions I daily use.
How to add github actions?
Add github actions on your branch
- .github/workflows/xxxx.yml

Trigger github action by leaving a comment on PR
Scenario 1: share new build to someone
You can define commands to run action
For example, If you want to share something to test, use this action.
- share is command
- test is userId
And you can leave a comment using github.issues.createComment
This action is very useful. You can integrate third-party services like Slack, WhatsApp, or Linear. Listening share command and trigger action whatever you want to share it.

name: Comment Action
on:
issue_comment:
types: [created]
jobs:
comment_job:
runs-on: ubuntu-latest
steps:
- name: Check Comment Type
id: check_comment
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const comment = context.payload.comment.body.trim();
console.log(`Received comment: ${comment}`);
const issueOrPrNumber = context.payload.issue?.number || context.payload.pull_request?.number;
if (!issueOrPrNumber) {
throw new Error("Could not determine issue or PR number.");
}
let action = '';
if (comment.startsWith('share')) {
action = 'share';
}
core.setOutput('action', action);
core.setOutput('comment', comment);
core.setOutput('issue_or_pr_number', issueOrPrNumber);
- name: Handle Share Command
if: steps.check_comment.outputs.action == 'share'
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const comment = '${{ steps.check_comment.outputs.comment }}';
const issueOrPrNumber = '${{ steps.check_comment.outputs.issue_or_pr_number }}';
if (!issueOrPrNumber) {
throw new Error("Could not determine the issue or PR number.");
}
const splitComment = comment.split(' ');
if (splitComment.length < 2) {
throw new Error("Invalid 'share' command format. Expected: 'share <id>'");
}
const recipientId = splitComment[1]; // Extract ID after "share"
const commentBody = `Sharing this with: ${recipientId}`;
console.log(`Adding a share comment for ID: ${recipientId}`);
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueOrPrNumber,
body: commentBody
});
scenario 2: rebuild when the build failed
There are 2 yml files in workflows
When you get a build failed message, you can rebuild it by leaving a comment.


comment_action.yml
- Get PR Number using github.pulls.get
- Pass issue_or_pr_number as Inputs to build.yml
name: Comment Action
on:
issue_comment:
types: [created]
jobs:
comment_job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: GitHub CLI Login
run: |
gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}"
- name: Check Comment Type
id: check_comment
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const comment = context.payload.comment.body.trim();
console.log(`Received comment: ${comment}`);
const issueOrPrNumber = context.payload.issue?.number || context.payload.pull_request?.number;
const isPR = Boolean(context.payload.issue.pull_request);
if (!isPR) {
throw new Error("This comment is not associated with a pull request.");
}
const { data: pullRequest } = await github.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: issueOrPrNumber,
});
const sourceBranch = pullRequest.head.ref;
const targetBranch = pullRequest.base.ref;
console.log(`Source branch: ${sourceBranch}`);
console.log(`Target branch: ${targetBranch}`);
if (!issueOrPrNumber) {
throw new Error("Could not determine issue or PR number.");
}
let action = '';
if (comment === 'rebuild') {
action = 'rebuild';
}
core.setOutput('action', action);
core.setOutput('comment', comment);
core.setOutput('issue_or_pr_number', issueOrPrNumber);
core.setOutput('source_branch', sourceBranch);
core.setOutput('target_branch', targetBranch);
- name: Rebuild
run: |
echo "🟢 Issue or PR Number: ${{ steps.check_comment.outputs.issue_or_pr_number }}"
gh workflow run rebuild.yml --ref ${{ steps.check_comment.outputs.target_branch }} -f issue_or_pr_number=${{ steps.check_comment.outputs.issue_or_pr_number }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build.yml
- define workflow_dispatch and inputs
name: build
on:
workflow_dispatch:
inputs:
issue_or_pr_number:
description: "The issue or PR number to comment on"
required: true
jobs:
reusable_job:
runs-on: ubuntu-latest
steps:
- name: Build
run: echo "Running workflow"
- name: Rebuild triggered
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issueOrPrNumber = ${{ github.event.inputs.issue_or_pr_number }};
console.log(`🟢 Input issue_or_pr_number: ${issueOrPrNumber}`);
if (!issueOrPrNumber) {
throw new Error("Could not determine the issue or PR number.");
}
const commentBody = `Rebuild triggered`;
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueOrPrNumber,
body: commentBody
});
scenario 3: read latest build success message and share it to someone

build.yml
- Just leave a comment on PR
name: Build
on:
pull_request:
branches:
- master
types:
- opened
- synchronize
- reopened
- edited
jobs:
run_on_pr:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Comment on PR
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issueOrPrNumber = context.payload.pull_request.number;
console.log(issueOrPrNumber);
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueOrPrNumber,
body: "iOS v12.0(1022)"
});
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueOrPrNumber,
body: "Android 15.0(1022)"
});

comment_action.yml
- await github.issues.listComments
- default page_num is 30. If your PR have many comments, I suggest you set page_num 100
name: Comment Action
on:
issue_comment:
types: [created]
jobs:
comment_job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: GitHub CLI Login
run: |
gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}"
- name: Check Comment Type
id: check_comment
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const comment = context.payload.comment.body.trim();
console.log(`Received comment: ${comment}`);
const issueOrPrNumber = context.payload.issue?.number || context.payload.pull_request?.number;
const isPR = Boolean(context.payload.issue.pull_request);
if (!isPR) {
throw new Error("This comment is not associated with a pull request.");
}
const { data: pullRequest } = await github.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: issueOrPrNumber
});
const sourceBranch = pullRequest.head.ref;
const targetBranch = pullRequest.base.ref;
console.log(`Source branch: ${sourceBranch}`);
console.log(`Target branch: ${targetBranch}`);
core.setOutput('source_branch', sourceBranch);
core.setOutput('target_branch', targetBranch);
if (!issueOrPrNumber) {
throw new Error("Could not determine issue or PR number.");
}
let action = '';
if (comment.startsWith('share')) {
action = 'share';
}
core.setOutput('action', action);
core.setOutput('comment', comment);
core.setOutput('issue_or_pr_number', issueOrPrNumber);
- name: Get Latest Build Comments
if: steps.check_comment.outputs.action == 'share'
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issueNumber = ${{ steps.check_comment.outputs.issue_or_pr_number }};
const comment = '${{ steps.check_comment.outputs.comment }}';
if (!issueNumber) {
throw new Error("Could not determine the issue or PR number.");
}
const splitComment = comment.split(' ');
if (splitComment.length < 2) {
throw new Error("Invalid 'share' command format. Expected: 'share <id>'");
}
const recipientId = splitComment[1]; // Extract ID after "share"
// Fetch all comments on the PR
const comments = await github.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
per_page: 100,
});
console.log("✅ All Comments")
comments.data.forEach(comment => console.log(`- ${comment.body}`));
// Filter and find the most recent iOS-related comment
const latestIOS = comments.data
.filter(comment => comment.body.startsWith('iOS'))
.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at))[0];
// Filter and find the most recent Android-related comment
const latestAndroid = comments.data
.filter(comment => comment.body.startsWith('Android'))
.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at))[0];
if (latestIOS) {
console.log(`Latest iOS Comment: ${latestIOS.body}`);
core.setOutput('latest_ios_comment', latestIOS.body);
} else {
console.log('No iOS-related comments found.');
}
if (latestAndroid) {
console.log(`Latest Android Comment: ${latestAndroid.body}`);
core.setOutput('latest_android_comment', latestAndroid.body);
} else {
console.log('No Android-related comments found.');
}
const commentBody = `Sharing this with: ${recipientId}\nReady for Testing\n${latestIOS.body}\n${latestAndroid.body}`;
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: commentBody
});

Leave a comment