Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 11 additions & 83 deletions .github/workflows/Automation-PullRequest.yml
Original file line number Diff line number Diff line change
@@ -1,74 +1,41 @@
# Workflow(Action) 名稱
name: Pull Reqeust Automation
name: Pull Request Automation

# Actions Log 的標題名稱
run-name: "[Pull Reqeust Automation] ${{ github.event.pull_request.title || github.ref }}"

# 觸發事件
on:
# PR 事件
pull_request:
# PR - 開啟、重開、有新 Push Commit 時
types: [opened, synchronize, reopened]

# 同個 Concurrency Group 如果有新的 Job 會取消正在跑的
# 例如 Push Commit 觸發的任務還沒執行就又 Push Commit 時,會取消前一個任務
# 添加权限设置
permissions:
pull-requests: write
issues: write
contents: read
repository-projects: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true

# Job 工作項目
# Job 會並發執行
jobs:
# Job ID
label-pr-by-file-count:
# Job 名稱 (可省略,有設定在 Log 顯示比較好讀)
name: Label PR by changes file count

# 如果這個 Job 失敗,不影響整個 Workflow,繼續其他 Job
continue-on-error: true

# 設定最長 Timeout 時間,防止異常情況發生時無止盡的等待
timeout-minutes: 10

# Runner Label - 使用 GitHub Hosted Runner ubuntu-latest 來執行工作
# 如果是 Private Repo 會計算用量,超過可能會產生費用
# 但這種自動化小工作不太容易用過量
runs-on: ubuntu-latest

# 工作步驟
# 工作步驟會照順序執行
steps:
# 步驟名稱
- name: Get changed file count and apply label
# 步驟 ID (可省略,後續若沒有 Step 要引用 Output 輸出則不需設定)
id: get-changed-files-count-by-gh
# 注入外部環境參數到執行階段
env:
# secrets.GITHUB_TOKEN 是 GitHub Actions 執行時自動產生的 Token,不需自行在 Secrets 設定,擁有一些 GitHub Repo API Scopes 權限
# https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows
# gh(GitHub) cli 需要注入 GH_TOKEN 到 ENV,gh 才有權限操作
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Shell script
# GitHub Hosted Runner 內建都有安裝好 gh cli,不需要安裝 Job 就能直接使用
run: |
# ${{ github.xxx }} 是 GitHub Actions Context 表達式
# 不是 Shell 變數,而是 YAML 解析階段由 GitHub Actions 替換成對應值
# 其他參數:https://docs.github.com/en/actions/learn-github-actions/contexts#github-context

# 取得 PR 編號:
PR_NUMBER=${{ github.event.pull_request.number }}

# 取得 Repo:
REPO=${{ github.repository }}

# 使用 GitHub API (gh cli) 取得 File changed 數量
FILE_COUNT=$(gh pr view $PR_NUMBER --repo $REPO --json files --jq '.files | length')

# Print Log
echo "Changed file count: $FILE_COUNT"

# Label 邏輯
if [ "$FILE_COUNT" -lt 5 ]; then
LABEL="XS"
elif [ "$FILE_COUNT" -lt 10 ]; then
Expand All @@ -83,7 +50,6 @@ jobs:
LABEL="XXL"
fi

# 使用 GitHub API (gh cli) 移除目前的 Size Label
EXISTING_LABELS=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json labels --jq '.labels[].name')
for EXISTING in $EXISTING_LABELS; do
case "$EXISTING" in
Expand All @@ -94,95 +60,57 @@ jobs:
esac
done

# (可選)如果 Label 不存在則建立
if ! gh label list --repo "$REPO" | grep -q "^$LABEL"; then
echo "🆕 Creating missing label: $LABEL"
gh label create "$LABEL" --repo "$REPO" --description "Size label: $LABEL" --color "ededed"
else
echo "✅ Label '$LABEL' already exists"
fi

# 使用 GitHub API (gh cli) 標記上 Label
gh pr edit $PR_NUMBER --repo $REPO --add-label "$LABEL"
# ---------

assign-self-if-no-assignee:
name: Automatically assign to self if no assignee is specified
# 因為是共用觸發事件,所以在 Job 上自己判斷,當是 Pull Request Opened(首次建立) 時才執行 Job 否則會 Skipped
if: github.event_name == 'pull_request' && github.event.action == 'opened'

# 如果這個 Job 失敗,不影響整個 Workflow,繼續其他 Job
continue-on-error: true

# 設定最長 Timeout 時間,防止異常情況發生時無止盡的等待
timeout-minutes: 10

# Runner Label - 使用 GitHub Hosted Runner ubuntu-latest 來執行工作
# 如果是 Private Repo 會計算用量,超過可能會產生費用
# 但這種自動化小工作不太容易用過量
runs-on: ubuntu-latest

steps:
- name: Assign self if No Assignee
# 使用 GitHub Script (JavaScript) 撰寫腳本 (Node.js 環境)
# 相較上面直接用 Shell Script 寫起來更方便漂亮
# 也不需要自行注入環境變數、GITHUB_TOKEN
uses: actions/github-script@v7
with:
script: |
// github-script 中會自動注入到 context 變數供 javascript 直接引用
// https://docs.github.com/en/actions/learn-github-actions/contexts#github-context

const issue = context.payload.pull_request; // 如果要連 Issue 一起支援可寫成 context.payload.issue || context.payload.pull_request
const issue = context.payload.pull_request;
const assignees = issue.assignees || [];
const me = context.actor;

if (assignees.length === 0) {
// github-script 中的 github 物件是 Octokit REST API 實例
// 用來操作 github api 使用

// Assignee 設成自己
await github.rest.issues.addAssignees({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
assignees: [me]
});

// 留言通知
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `🔧 No assignee was set, so I have assigned this to myself (@${me}).`
});
}
# ---------

append-author-to-pr-description:
name: Append author to PR description
# 因為是共用觸發事件,所以在 Job 上自己判斷,當是 Pull Request Opened(首次建立) 時才執行 Job 否則會 Skipped
if: github.event_name == 'pull_request' && github.event.action == 'opened'

# 如果這個 Job 失敗,不影響整個 Workflow,繼續其他 Job
continue-on-error: true

# 設定最長 Timeout 時間,防止異常情況發生時無止盡的等待
timeout-minutes: 10

# Runner Label - 使用 GitHub Hosted Runner ubuntu-latest 來執行工作
# 如果是 Private Repo 會計算用量,超過可能會產生費用
# 但這種自動化小工作不太容易用過量
runs-on: ubuntu-latest
steps:
- name: Append author to PR description
env:
# secrets.GITHUB_TOKEN 是 GitHub Actions 執行時自動產生的 Token,不需自行在 Secrets 設定,擁有一些 GitHub Repo API Scopes 權限
# gh(GitHub) cli 需要注入 GH_TOKEN 到 ENV,gh 才有權限操作
# https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# ${{ github.xxx }} 是 GitHub Actions Context 表達式
# 不是 Shell 變數,而是 YAML 解析階段由 GitHub Actions 替換成對應值
# 其他參數:https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
PR_NUMBER: ${{ github.event.pull_request.number }}
AUTHOR_TAG: '@${{ github.event.pull_request.user.login }}'
run: |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@testable import app_ci_cd_github_actions_demo
import XCTest

//第一个PR,测试,第二次测试
class UserManagerTests: XCTestCase {
var userManager: UserManager!
override func setUp() {
Expand Down