---
# System prepended metadata

title: Git筆記--GitLab Runner
tags: [runner, GitLab, Git, .gitlab-ci.yml]

---

<h1>Git筆記--GitLab Runner</h1>

在 <code>.gitlab-ci.yml</code> 裡，<code>Runner</code> 是 <code>GitLab CI/CD</code> 真正執行工作的「工人」，是實體存在的機器/伺服器，它負責把你在 <code>YAML</code> 裡定義的 <code>Job</code> 變成實際操作。可以把 <code>Runner</code> 想像成「工廠裡的機器人」，你的 <code>.gitlab-ci.yml</code> 就是流程表，<code>Runner</code> 依照表上指示去完成每個任務。

  
---
運作流程
---
假設在專案中有一個 <code>.gitlab-ci.yml</code>，裡面定義了 <code>Stage</code> 與 <code>Job</code>：
```yaml=
stages:
  - build
  - test

# Build Job，需要 Docker 環境
build_job:
  stage: build
  tags:
    - docker      # 指定只有有 docker 標籤的 Runner 可以執行
    - linux       # 指定 Runner 必須是 Linux 環境
  script:
    - echo "Building project..."

# Test Job，也在 Docker + Linux 環境執行
test_job:
  stage: test
  tags:
    - docker      # 只派給有 docker 標籤的 Runner
    - linux       # 只派給 Linux Runner
  script:
    - echo "Running tests..."
```
<details><summary>步驟 1：<code>Pipeline</code> 觸發</summary>
<div>

---
- 當 <code>push commit</code>、<code>merge request</code> 或手動觸發 <code>pipeline</code> 時，<code>GitLab</code> 會解析 <code>.gitlab-ci.yml</code>。
- <code>GitLab</code> 會生成一個 <code>pipeline</code>，裡面包含依照 <code>stages</code> 排序的 <code>Job</code>。
- 每個 <code>Job</code> 是一個待執行的任務清單。

</div>
</details>
<details><summary>步驟 2：<code>Job</code> 分配給 <code>Runner</code></summary>
<div>

---
- GitLab 將 <code>pipeline</code> 裡的 <code>Job</code> 分配給可用的 <code>Runner</code>。
- <code>Runner</code> 分為：
  - <code>Shared Runner</code>：所有專案都可用
  - <code>Specific Runner</code>：專屬於某個專案或群組
- GitLab 根據 <code>Runner</code> 標籤（tags）選擇適合執行該 <code>Job</code> 的 <code>Runner</code>。
  - <code>tags</code> 會讓 GitLab 只派 <code>Job</code> 給符合條件的 <code>Runner</code>
  - 如果有多個 <code>Runner</code> 都符合標籤，GitLab 會自動選擇空閒的 <code>Runner</code>
  - 沒有符合標籤的 <code>Runner</code>，<code>Job</code> 會一直排隊，直到有 <code>Runner</code> 可用

</div>
</details>
<details><summary>步驟 3：<code>Runner</code> 環境準備</summary>
<div>

---
- Runner 啟動時會依照 <code>Job</code> 設定準備執行環境：
  - 執行方式有多種：
    - <code>Docker</code>：每個 <code>Job</code> 在乾淨的容器中執行
    - <code>Shell</code>：直接在 <code>Runner</code> 主機上執行
    - <code>Kubernetes</code>：在 <code>Pod</code> 中執行
- <code>Runner</code> 會拉取專案程式碼到本地或容器內。

</div>
</details>
<details><summary>步驟 4：<code>Job</code> 執行</summary>
<div>

---
- Runner 依序執行 <code>Job</code> 中的 <code>script</code> 指令。
- 執行時可：
  - 產生 <code>Artifacts</code>（檔案、測試報告、build 成品）
  - 輸出 <code>log</code>（方便 GitLab UI 查看）

</div>
</details>
<details><summary>步驟 5：<code>Job</code> 結果回傳</summary>
<div>

---
- <code>Job</code> 執行完成後，<code>Runner</code> 將結果回傳給 GitLab：
  - 成功（green tick）
  - 失敗（red cross）
- GitLab 更新 <code>pipeline</code> 狀態，決定下一個 <code>stage</code> 的 <code>Job</code> 是否可以執行。

</div>
</details>
<details><summary>步驟 6：<code>Artifacts</code> 與 <code>Cache</code> 處理</summary>
<div>

---
- <code>Runner</code> 可以上傳產物（Artifacts）到 GitLab，供後續 <code>Job</code> 使用。
- 可以使用 <code>cache</code> 儲存中間結果，加快下次 <code>pipeline</code> 執行速度。

</div>
</details>

```markdown=
Push Commit → GitLab 解析 .gitlab-ci.yml → Pipeline 生成 → 
Job 分配給符合標籤的 Runner →
Runner 準備環境（依 Executor/標籤配置） → 
執行 Script → 上傳結果/Artifacts → 
GitLab 更新 Pipeline 狀態
```
備註: GitLab 預設會在有 <code>commit</code> <code>push</code> 上遠端時自動觸發 <code>pipeline</code>。