---
# System prepended metadata

title: '[CI/CD] Github Actions(未完)'
tags: [github, CI/CD, git, 轉職]

---

{%hackmd BJzAwtWvp %}

## 介紹

- Github Action 是 Github 提供的 CI/CD (continuous integratin and continuous delivery) 服務模板，可以讓我們達到自動建置、測試、部署等功能。
- 可以藉由建立 workflow 來定義當特定事件發生時，要執行的動作。
- 以下我們先練習一個簡單的 workflow 範例。

## 組成元件

- workflow：定義當特定事件發生時，要執行的動作。
- Event：觸發 workflow 的事件，例如 push、pull request、issue 等。
- Job：Job 是在同一個 runner 上執行的一系列步驟，可以是建置、測試、部署等。
- Step：Job 中的步驟，可以是多個。
- Runner：代理程式，負責執行自動化工作流程中的任務。運作在 Github 的虛擬機器上。

## 範例

1. 打開你的 github，建立一個名為 `github-action-practice` 的 repository。
2. github action 的 workflow 定義檔是放在 `.github/workflows` 資料夾下。有兩種方式可以建立 workflow 檔案：
   - 在 github repository 頁面上直接點選上面 tab 的 `Actions`，再點選 `set up a workflow yourself`。
   - 將專案 clone 下來，手動建立 `.github/workflows` 資料夾，再在裡面建立 workflow 檔案。
3. 在 `.github/workflows` 資料夾下建立一個名為 `github-action-demo.yaml` 的檔案，並輸入以下內容：

```yaml
name: GitHub Actions Demo # workflow 的名稱
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 # 定義每次運行此工作流程時的名稱，其中 ${{ github.actor }} 是 GitHub 提供的一個變數，表示觸發此工作流程的用戶名。
on: [push] # 在 [xxx] 事件發生時，觸發此 workflow，這裡可以定義行為或是分支名稱等。
jobs: # 定義工作流程中的工作，可以是循序的，也可以是平行的。
  Explore-GitHub-Actions: # 這個 job 的名稱
    runs-on: ubuntu-latest # github action 是在由 github 提供的 vm 上執行，這裡指定使用 ubuntu-latest 作業系統。
    steps: # 定義工作流程中的步驟
      - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
      - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
      - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
      - name: Check out repository code
        uses: actions/checkout@v4
      - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
      - run: echo "🖥️ The workflow is now ready to test your code on the runner."
      - name: List files in the repository
        run: |
          ls ${{ github.workspace }}
      - run: echo "🍏 This job's status is ${{ job.status }}."
```
4. 接著點選 `commit changes`，並且選擇`Create a new branch for this commit and start a pull request`，再點選 `propose changes`。
5. 接下來會出現一個ˊ`Create pull request` 的頁面，在這個練習中點不點選 `Create pull request` 都可以，不影響後續的練習。我們就先不點選，跳過它吧。
6. 回到 repository 頁面，點選 `Actions`，就可以看到剛剛建立的 workflow 了。
![alt text](image.png)
7. 點選進入看看，可以看到 workflow 的執行過程，以及每個步驟的執行結果。
![alt text](image-1.png)
![alt text](image-2.png)

接下來我們要練習不同主題的 workflow，包含 [build and test](https://docs.github.com/en/actions/automating-builds-and-tests), [build and publush](https://docs.github.com/en/actions/publishing-packages), [deploy to server](https://docs.github.com/en/actions/deployment), [manage issues and pull requests](https://docs.github.com/en/actions/managing-issues-and-pull-requests)。

> Action 的名稱格式相當重要，官方也建議在使用上指定版本(Git Ref, SHA, 或 Docker Tag)，確保使用正確的 Action，也不會因為發布者更新版本而導致 workflow 中斷。其格式如下：\
> {owner}/{repo}@{ref} \
> 範例如下 \
> actions/heroku@main

## Event

- 在 workflow 中，我們可以定義當特定事件發生在特定分支時，要執行的動作。
- 以下是一些常見的事件：
  - push：當有新的 commit 被 push 到 repository 時。
  - pull_request：當有新的 pull request 被建立時。
  - issue：當有新的 issue 被建立時。
  - release：當有新的 release 被建立時。
  - schedule：定期執行。
  - workflow_dispatch：手動觸發。
- 以下是一些常見的事件屬性：
    - branches：指定要觸發的分支。
    - paths：指定要觸發的檔案路徑。
    - tags：指定要觸發的 tag。
    - types：指定要觸發的事件類型。
- 以下是一些常見的事件範例：
```yaml
on: # 當以下事件發生時，觸發此 workflow
  push: # 當有新的 commit 被 push 到 repository 時
    branches: # 指定要觸發的分支
      - main # 當 main 分支有新的 commit 被 push 時，觸發此 workflow
  pull_request: # 當有新的 pull request 被建立時
    branches: # 指定要觸發的分支
      - main # 當 main 分支有新的 pull request 被建立時，觸發此 workflow
  issue: # 當有新的 issue 被建立時
    types: # 指定要觸發的事件類型
      - opened # 當有新的 issue 被建立時，觸發此 workflow
      - edited # 當有 issue 被編輯時，觸發此 workflow
  release: # 當有新的 release 被建立時
    types: # 指定要觸發的事件類型
      - published # 當有新的 release 被建立時，觸發此 workflow
  schedule: # 定期執行
    - cron: '0 0 * * 0' # '分 時 日(每月的幾號) 月 星期'，每週日的 00:00 執行
  workflow_dispatch:
```
> ![alt text](image-3.png)
- 也可以藉由 repository dispatch 事件，來觸發 workflow。這個事件是由 repository 的外部事件觸發，例如 webhook、API 等。範例如下：
```yaml
on:
  repository_dispatch:
    types: [my-event-type]
```

## Variables

- 變數可以直接寫在 workflow 檔案中，也可以寫在 repository 的 `Settings`中。
- 範例：
1. 到 repository 的 `Settings` > `Security` > `Secrets and variables` > `Actions` > `Variables` > `Repository variables`，新增一個變數 `First_Name`，值為 `Mona`。
```yaml
name: Greeting on variable day

on:
  workflow_dispatch # 手動觸發

env:
  DAY_OF_WEEK: Monday # 定義環境變數 DAY_OF_WEEK 為 Monday

jobs:
  greeting_job:
    runs-on: ubuntu-latest
    env:
      Greeting: Hello # 定義環境變數 Greeting 為 Hello
    steps:
      - name: "Say Hello Mona it's Monday"
        run: echo "$Greeting ${{ vars.First_Name }}. Today is $DAY_OF_WEEK!
        # env:
        #   First_Name: Mona # 這格變數我們把它新增在 repository 的變數中
```
![alt text](image-5.png)

## Condition

- 我們可以在 workflow 中使用 if 條件式，來判斷是否要執行某個步驟。
```yaml
name: condition workflow

on: workflow_dispatch

jobs:
  if-Windows-else:
    runs-on: macos-latest
    steps:
      - name: condition 1
        if: runner.os == 'Windows'
        run: echo "The operating system on the runner is $env:RUNNER_OS."
      - name: condition 2
        if: runner.os != 'Windows'
        run: echo "The operating system on the runner is not Windows, it's $RUNNER_OS."
```
![alt text](image-4.png)

## Environment

- 先跳過囉

## 使用 Github Action 把 Angular image 專案部署到 GCP

施工中
```yaml

name: Build Angular App # This is the name of the workflow. It will be displayed in the Actions tab of the repository.


on: # This is the event that triggers the workflow.
  push: # This workflow will be triggered when a push event occurs.
    branches: [ main ] # This workflow will be triggered only when the push event occurs in the main branch.
  pull_request: # This workflow will be triggered when a pull request event occurs.
    branches: [ main ]  # This workflow will be triggered only when the pull request event occurs in the main branch.

jobs:
  build-angular: # This is the name of the job.
    runs-on: ubuntu-latest # This is the runner that the job will run on. In this case, it is an Ubuntu runner.

    steps:
      # Search `setup node js` in the Marketplace and chose `Setup Node.js environment`.
      - uses: actions/checkout@v4

      - name: Setup Nodes JS
        uses: actions/setup-node@v4
        with:
          node-version: 18.x
      # This step is to install the dependencies of the project.
      - name: Install dependencies
        run : npm install # If there are multi line to do this step we can use  `|` to switch line.
      # This step is to build the project.
      - name: Build
        run: npm run build
```

## 使用 Github Action 把 Spring boot image 專案部署到 GCP

施工中