GitHub Actions 初級編

# 概要
GitHub Actions の[公式ドキュメント](https://docs.github.com/en/actions)で得た知見をまとめた記事になります。
# GitHub Actions とは？
GitHub Actions とは、[GitHub, Inc.](https://github.co.jp/about.html)が提供している CI/CDです。
CI/CDとはCI（Continuous Integration）、CD（Continuous Delivery）の略で継続的インテグレーション、継続的インテグレーションを意味しています。

ビルド、テスト、デプロイを自動化することができ、プロダクトの品質担保やリリース作業を素早くできるなどのメリットがあります。

## GitHub Actions のコンポーネント
基本的な流れとして、GitHub Actions `Workflow`を作成し、トリガーを`Event`で定義します。
`Workflow`の内に1つまたは複数の`Job`を定義し、`Job`の実行順序はシーケンシャルまたは、並列に実行する事が可能です。
virtual machine `Runner`または、コンテナ上で`Job`に定義した`Action`やスクリプトを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433451/d1357ae3-a30d-228c-bce2-f96aab85b536.png)

**具体的な例**
```
name: learn-github-actions
# Eventの定義（リポジトリにpushされた時にworkflowが実行）
on: [push]
# Jobの定義
jobs:
　# Job名 
  test:
    # Runnerの定義（この例では、virtual machineのUbuntu上で実行）
    runs-on: ubuntu-latest
    steps:
      # Runner(virtual machineのUbuntu)にgo 1.17を入れるAction
      - name: set up
        uses: actions/setup-go@v3
        with:
          go-version: ^1.17
      # Runner(virtual machineのUbuntu)にpushされたコードをcheckoutするAction
      - name: check out
        uses: actions/checkout@v3
      # Runner(virtual machineのUbuntu)でテストを実行する
      - name: test
        run: go test ./... -v
```

**各コンポーネントの詳細**
- Workflows（ワークフロー）
    - １つまたは複数の自動化したい`Job`を定義する
    - 対象リポジトリの `.github/workflows` 配下にYAMLファイルで定義する。用途別（ビルド、テスト、デプロイ用）に複数のファイルを作成する事も可能
- Events（イベント）
    - `Workflow`で定義した処理が実行される条件を定義する（対象のリポジトリにプルリクを作成時、issue作成時、commit時、毎日1時に実行する様なスケジュールも設定可能）
- Jobs（ジョブ）
    - `Job`とは`Workflow`内で実行される`Steps`の集合体
    - `Step`はshell、スクリプト、`Action`を定義する事で、`Runner`に指定した環境で実行される
    - 同一環境で`Job`が実行される為、`Step`間でデータの共有が行える（例：ビルドするステップ、ビルドしたリソースをテストするステップ）
    - 各`Job`の依存関係を設定する事も可能（デフォルトでは`Job`間での依存関係は無く、並列で実行される）

- Actions（アクション）
    - `Action`とはGitHub Actions上で実行できるカスタムアプリケーション
    - リポジトリのプル、ビルドなどが簡単に行える
    - `Action`の利用方法
        - [GitHub Marketplace](https://github.com/marketplace?type=actions)で公開されているもの（自作も可能）
        - 同一リポジトリから
          - `{owner}/{repo}@{ref}`または、`./path/to/dir`
        - 異なるリポジトリから
          - `{owner}/{repo}@{ref}`
        - Docker Hubのコンテナを参照
          - `docker://{image}:{tag} `
     - `Action`のバージョンの指定方法
        - tags
        - SHAs
        - branches

- Runners（ランナー）
    - `Runner`とは`Workflow`が実行されるサーバーを定義する
    - `Workflow`が実行される度に新しいサーバーを立ち上げる

# Expression

以下のリポジトリで一部挙動確認
- https://github.com/kenro17/learn-github-actions/pull/3/files

## Literals
| 型 | 値 |
|:-:|:-:|
| boolean | `true` または `false`  |
| null |  `null` |
| number | JSONがサポートしている数値表現  |
| string |  利用する際にはクオテーションは不要。 `${{ }}` を利用して定義する場合はシングルクオートで囲む必要がある |


```
env:
  myNull: ${{ null }}
  myBoolean: ${{ false }}
  myIntegerNumber: ${{ 711 }}
  myFloatNumber: ${{ -9.2 }}
  myHexNumber: ${{ 0xff }}
  myExponentialNumber: ${{ -2.99e-2 }}
  myString: Mona the Octocat
  myStringInBraces: ${{ 'It''s open source!' }}
```

## Operators
利用できる演算子の一覧
| 演算子 | 説明 |
|:-:|:-:|
| ( ) | Logical grouping |
| [ ] | Index |
| . | Property de-reference |
| ! | Not |
| < | Less than |
| <= | Less than or equal |
| >  | Greater than |
| >= | Greater than or equal |
| == | Equal |
| != | Not equal |
| && | And |
| \|\|| Or |

**注意点**
- 比較する際は等価演算子で比較される（==）
- `NaN`と`Nan`の比較結果は`false`
- String同士の比較は大文字・小文字を区別しない
- Object, Arrayの比較は同一インスタンスだった場合のみ`true`

## Functions
以下、ビルドインされている関数

- contains(search, item)
  - `search`が`array`の場合：`item`要素が存在する → `true`
  - `search`が`string`の場合：`item`文字列が含まれている → `true`
  - e.g. contains('Hello world', 'llo') → `true`

- startsWith(searchString, searchValue)
    - `searchString`が`searchValue`から始まる →　`true`
    - e.g. startsWith('Hello world', 'He') → `true`

- endsWith(searchString, searchValue)
    - `searchString`が`searchValue`で終わる →　`true`
    - e.g. endsWith('Hello world', 'ld') → `true`
- format(string, replaceValue0, replaceValue1, ..., replaceValueN)
    - 第一引数の`string`に第二引数〜第N引数の値を代入する
    - 第一引数の`string`に引数に指定した分、{0}, {1}, ..., {N}と含める必要がある
    - e.g. format('Hello {0} {1} {2}', 'Mona', 'the', 'Octocat') → `Hello Mona the Octocat`
- join(array, optionalSeparator)
    - 第一引数の`array`は`string`でも可能
    - `array`の値を`optionalSeparator`で指定した値を用いて、連結する
    - TODO: e.g.
- toJSON(value)
    - JsonのPretty-print形式でvalueを返却する
- fromJSON(value)
    - `value`に対するJSONオブジェクト、あるいはJSONデータ型を返します。
- hashFiles(path)
    - `path`パターンにマッチするファイル群から単一のハッシュを返す。

## Status Check functions
if文内に追記し、`step`のステータスを確認できる関数。
以下の関数を明示的に記載しない場合は、デフォルトで`success()`が適用されている
- success
    - 以前の`step`で`failed`, `canceled`状態でない場合、`true`
- always
    - 以前の`step`で`canceled`状態になった場合でも`true`
- cancelled
    - 以前の`step`で`canceled`状態になった場合、`true`
- failure
    - 以前の`step`で`failed`状態になった場合、`true`

## Object filters
`*` syntaxを利用する事で、対象の`array`, `object`からフィルターして値を取得する。
```e.g.
{
  "scallions":
  {
    "colors": ["green", "white", "red"],
    "ediblePortions": ["roots", "stalks"],
  },
  "beets":
  {
    "colors": ["purple", "red", "gold", "white", "pink"],
    "ediblePortions": ["roots", "stems", "leaves"],
  },
  "artichokes":
  {
    "colors": ["green", "purple", "red", "black"],
    "ediblePortions": ["hearts", "stems", "leaves"],
  },
}
```
`vegetables.*.ediblePortions` は以下の値を取得する
```
[
  ["roots", "stalks"],
  ["hearts", "stems", "leaves"],
  ["roots", "stems", "leaves"],
]
```

# Contexts
コンテキストは、ワークフローの実行、ランナーの環境、ジョブ、ステップに関する情報にアクセスする方法です。
ここでは、軽くどのようなコンテキストがあるのか一覧とその説明を一覧化します

| コンテキスト名 | 説明 |
|:-:|:-:|
| github | ワークフローの実行および、その実行をトリガーしたイベントの情報を含む |
| env | ワークフロー、ジョブ、ステップで設定された環境変数を含む |
| job | 現在実行中のジョブに関する情報を含む |
| steps | 現在実行中のステップに関する情報を含む |
| runner | 現在のジョブを実行しているランナーに関する情報を含む |
| secrets |　ワークフローの`secrets`の名前や値の情報を含む |
| strategy | 現在のジョブを実行しているマトリックスに関する情報を含む |
| matrix | ワークフロー内でmatrixに定義した情報を含む |
| needs | 現在のジョブの依存関係として定義されたすべてのジョブからの出力を含む |
| inputs | ワークフローを手動実行する際などに渡すプロパティの情報を含む |