【GitHub Actions】step・jobをまたぐデータの受け渡しまとめ

## 概要
一念発起してGitHub Actionsの[ドキュメント](https://docs.github.com/en/actions)を全部読んだので、忘れてしまいそうなことをメモしておく。

#### 書くこと
* 前段のstep・jobで発生したデータを、後段のstep・jobから参照する方法
* それぞれの方法をyamlとして記述する例（いずれも`foobarbaz`というテキストデータをやりとりする単純なもの）

#### 書かないこと
* データの受け渡しに関するベストプラクティス（どちらかというと様々な方法を紹介することにフォーカスする）
* GitHub Actionsにおけるstep・jobといった概念の説明（これについて知りたい場合は[こちら](https://qiita.com/Yuuki557/items/5ea3d46b8f6251805c4e)の記事が参考になりそう）

## stepをまたぐデータの受け渡し
#### outputとして渡す（[ドキュメント](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter)）
workflow commandを使ってoutputを設定する方法。jobをまたぐデータの受け渡しも、同じworkflow commandを使ったりする（後述）

```yaml:.github/workflows/sample.yaml
on: [push]
jobs:
  sample-job:
    runs-on: ubuntu-latest
    steps:
      - id: first
        run: echo '::set-output name=VALUE::foobarbaz'
      - id: second
        run: echo ${{ steps.first.outputs.VALUE }}
```

#### ファイルとして渡す（[ドキュメント](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions#jobs)）
同じjob内のstepは、同じrunner上で順番に実行される。そのため以下のように、前段で作成したファイルを後段で参照することができる。

```yaml:.github/workflows/sample.yaml
on: [push]
jobs:
  sample-job:
    runs-on: ubuntu-latest
    steps:
      - run: echo "foobarbaz" > ./output
      - run: cat ./output
```

#### 環境変数として渡す（[ドキュメント](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable)）
以下のように`$GITHUB_ENV`が示すファイルに環境変数を追記すると、次のstepからその環境変数を参照できる。

```yaml:.github/workflows/sample.yaml
on: [push]
jobs:
  sample-job:
    runs-on: ubuntu-latest
    steps:
      - run: echo "VALUE=foobarbaz" >> $GITHUB_ENV
      - run: echo $VALUE
```


#### serviceを利用して渡す（[ドキュメント](https://docs.github.com/en/actions/using-containerized-services/about-service-containers)）
サービスコンテナとしてDBを起動すれば、それ経由でデータの受け渡しが可能。このような使い方を意図したものではないかもしれないが、できるものはできる。サービスコンテナはjobが完了した時点で消える。

```yaml:.github/workflows/sample.yaml
on: [push]
jobs:
  sample-job:
    runs-on: ubuntu-latest
    services:
      redis:
        image: redis
    steps:
      - uses: docker://redis:latest
        with:
          entrypoint: redis-cli
          args: -h redis set value foobarbar
      - uses: docker://redis:latest
        with:
          entrypoint: redis-cli
          args: -h redis get value
```

## jobをまたぐデータの受け渡し
### outputとして渡す（[ドキュメント](https://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs)）
`$${{ steps.stepid.outputs.value }}`を前段のjobのoutputとして、後段のjobからそれを参照している。`needs`を忘れないように注意！

```yaml:.github/workflows/sample.yaml
on: [push]
jobs:
  first-job:
    runs-on: ubuntu-latest
    outputs:
      value: ${{ steps.stepid.outputs.value }}
    steps:
      - id: stepid
        run: echo "::set-output name=value::foobarbaz"
  second-job:
    runs-on: ubuntu-latest
    needs: first-job
    steps:
      - run: echo ${{ needs.first-job.outputs.value }}
```

### artifactとして渡す（[ドキュメント](https://docs.github.com/ja/actions/using-workflows/storing-workflow-data-as-artifacts)）
ファイルとして受け渡す。workflow終了後、手元にダウンロードして確認できるというメリットもある。

```yaml:.github/workflows/sample.yaml
on: [push]
jobs:
  first-job:
    runs-on: ubuntu-latest
    steps:
      - run: echo 'foobarbaz' > ./value.txt
      - uses: actions/upload-artifact@v3
        with:
          name: sample-artifact
          path: value.txt
  second-job:
    runs-on: ubuntu-latest
    needs: first-job
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: sample-artifact
      - run: cat ./value.txt
```

以上！！公式ドキュメントだと一か所にまとめて記載されているわけでないので、記事としてまとめたことには意味があるはず...