【GitHub Actions】GitHub Actionsでawscliとawsebcliをpipでインストールしたらエラーになったが回避方法を見つけた

AWS Elastic Beanstalkへデプロイする際に`awscli`と`awsebcli`を使用しているですが、今月になってから両コマンドのインストール時に依存関係の解決に失敗したり、コマンド実行時にエラーが出るようになりました。
いろいろ試行錯誤した結果エラーが解決できた(?)ので、GitHub Actionsで両コマンドを正常にインストールできる方法を紹介します。

# 発生したエラー

## 環境

- ubuntu 18.04 on GitHub Actions
- python 3.7.5
- awscli 1.16.*
- awsebcli 3.15.*

## エラー内容

`awscli`と`awsebcli`を両方とも`pip`を使用してインストールした時にエラーが発生しました。

```
$ pip install awscli awsebcli

# --- omit -----

ERROR: botocore 1.13.13 has requirement python-dateutil<2.8.1,>=2.1; python_version >= "2.7", but you'll have python-dateutil 2.8.1 which is incompatible.
ERROR: docker-compose 1.23.2 has requirement PyYAML<4,>=3.10, but you'll have pyyaml 5.1.2 which is incompatible.
ERROR: awsebcli 3.15.3 has requirement botocore<1.13,>=1.12.29, but you'll have botocore 1.13.13 which is incompatible.
ERROR: awsebcli 3.15.3 has requirement colorama<0.4.0,>=0.3.9, but you'll have colorama 0.4.1 which is incompatible.
ERROR: awsebcli 3.15.3 has requirement PyYAML<=3.13,>=3.10, but you'll have pyyaml 5.1.2 which is incompatible.

# --- omit -----

# Error Exit にならずインストールできてしまった...
Successfully installed PyYAML-5.1.2 awscli-1.16.277 awsebcli-3.15.3 blessed-1.16.1 botocore-1.13.13 cached-property-1.5.1 cement-2.8.2 certifi-2019.9.11 chardet-3.0.4 colorama-0.4.1 docker-3.7.3 docker-compose-1.23.2 docker-pycreds-0.4.0 dockerpty-0.4.1 docopt-0.6.2 docutils-0.15.2 future-0.16.0 idna-2.7 jmespath-0.9.4 jsonschema-2.6.0 pathspec-0.5.9 pyasn1-0.4.7 python-dateutil-2.8.1 requests-2.20.1 rsa-3.4.2 s3transfer-0.2.1 semantic-version-2.5.0 six-1.11.0 termcolor-1.1.0 texttable-0.9.1 urllib3-1.24.3 wcwidth-0.1.7 websocket-client-0.56.0
```

見事に依存関係の解決に失敗していますね。
インストール後に両コマンドを実行した時のログが↓になります。

```
$ aws --version

aws-cli/1.16.277 Python/3.7.5 Linux/5.0.0-1023-azure botocore/1.13.13

$ eb --version

Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 583, in _build_master
    ws.require(__requires__)
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 900, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 791, in resolve
    raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (PyYAML 5.1.2 (/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages), Requirement.parse('PyYAML<=3.13,>=3.10'), {'awsebcli'})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.7.5/x64/bin/eb", line 6, in <module>
    from pkg_resources import load_entry_point
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 3250, in <module>
    @_call_aside
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 3234, in _call_aside
    f(*args, **kwargs)
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 3263, in _initialize_master_working_set
    working_set = WorkingSet._build_master()
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 585, in _build_master
    return cls._build_from_requirements(__requires__)
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 598, in _build_from_requirements
    dists = ws.resolve(reqs, Environment())
  File "/opt/hostedtoolcache/Python/3.7.5/x64/lib/python3.7/site-packages/pkg_resources/__init__.py", line 786, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'PyYAML<=3.13,>=3.10' distribution was not found and is required by awsebcli
##[error]Process completed with exit code 1.
```

PyYAMLのバージョンがコンフリクトしていますね。
[Issue](https://github.com/aws/aws-cli/issues/3550)にも上がっているようにバージョン指定したり、依存パッケージを手動インストールしてみたりしましたが、うまくいきませんでした。
また、pipenvを使用して仮想環境で切り離してインストールしてみてもダメでした。

そこで検証用のリポジトリを作成して様々なパターンを試し成功するものがあるのか調べました。

# 成功パターン
こちらの[リポジトリ](https://github.com/homoluctus/github-actions-install-awsebcli/actions)で実験して成功したパターンがいくつかあったのですが、その中でも個人的にベストだと思うWorkflowを紹介します。

## 環境

- MacOS Catalina
- Python 3.7.5
- awscli 1.16.*
- awsebcli 3.15.*

2019/11/6にMacOSがCatalinaにアップデートしました :tada:
参考: [GitHub Actions – macOS virtual environment updated to Catalina](https://github.blog/changelog/2019-11-06-github-actions-macos-virtual-environment-updated-to-catalina/)

## GitHub Actions 例
`awscli`をbrewで、`awsebcli`をpipでインストールします。

```yaml
name: Install awscli and awsebcli on Mac

on: push

jobs:
 test:
    name: Install awscli and awsebcli
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@master

      - name: Install awscli
        run: |
          brew update
          brew install awscli
          brew upgrade

      - uses: actions/setup-python@master
        with:
          python-version: '3.7'

      - name: Install awsebcli
        run: pip install -U awsebcli

      - name: Check version
        run: |
          aws --version
          eb --version
```

`Check version`の実行ログ

```
$ aws --version
aws-cli/1.16.260 Python/3.7.5 Darwin/19.0.0 botocore/1.12.250

$ eb --version
EB CLI 3.15.3 (Python 3.7.5)
```

こんな感じの正常にインストールができ、ちゃんとコマンドが実行できています。
他にも成功パターンがあったのですが、ベースとなっているPythonのバージョンが2系になってしまいました。
なので↑がベストです :bangbang:

いろんなパターンは[こちら](https://github.com/homoluctus/github-actions-install-awsebcli)のリポジトリにあります。(突然消えるかもしれませんがご容赦を...)