DirectCloud-BOXにファイルをアップロードするGitHub Actionを作ってみた

## はじめに

この記事は「[Qiita エンジニアフェスタ 2021](https://qiita.com/official-campaigns/engineer-festa/2021)」の参加記事です。

https://qiita.com/official-events/64ff6ba4e653a822fce9#%E6%A6%82%E8%A6%81

[DirectCloud-BOX](https://directcloud.jp/freeplan) は、[DropBox](https://www.dropbox.com/?landing=dbv2) や [Box](https://www.box.com/home) などのような、いわゆるクラウドストレージです (全部ﾅﾝﾄｶ Box ですね…)
上記ページの概要を見ればどのようなものかが掴めるかなと思います。

## 概要

DirectCloud-BOX の API を利用し、GitHub Actions のワークフロー内からファイルをアップロードする JavaScript Action を作ってみました。

https://github.com/marketplace/actions/upload-directcloud-box

ユースケースとしては、こんな感じでしょうか。

- パッケージリポジトリや public な成果物ストアには上げたくないが、社内で共有したい SDK やバイナリファイルをアップロードする
- デザインアセットを生成してアップロードする
- カバレッジレポートなどテスト成果物系をアップロードする

記載されているワークフローの YAML をコピペして GitHub Actions を設定し、必要な環境変数を取得・設定すれば以下のスクショのように動作します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/7a60ff94-33a2-6fa0-a96a-c2d23b4b26b9.png)
次の項では、もう少し詳細な設定手順を説明します。

## 利用手順

### DirectCloud-BOX API を使う

#### 利用申請

フリープランを申し込みます。その後メールでログイン情報が届きます。

https://directcloud.jp/apply/free

#### API を有効化する

[DirectCloud\-BOX の管理画面](https://boxmanager.directcloud.jp/setting/image)より API を有効化し、`Service` と `Service Key` を取得します。

### GitHub Actions を設定する

GitHub Actions について、詳しくは[GitHub Actions Documentation \- GitHub Docs](https://docs.github.com/en/actions)を参照してください。
ここでは、今回作成した Action を利用するまでの手順を簡単に説明します。

#### ワークフローを設定する

下記のページの Usage より、YAML をコピーしておきます。

https://github.com/marketplace/actions/upload-directcloud-box

Action を使いたいリポジトリの `Actions` タブから設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/515067d2-5065-1105-271e-c145c9901c72.png)
デフォルトの設定が予め入っていますが、先程コピーした YAML で全て置き換えます。特に支障がなければデフォルトブランチ (`main`) にコミットしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/32a047fb-8db1-ad65-630b-8424ae9226b9.png)
先程のコミットをトリガーにビルドが動き出しますが、必要な環境変数を設定していないため失敗します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/909e2f0f-0f5b-f48a-5496-403efe0a655b.png)

#### GitHub Encrypted Secrets を設定する

GitHub Actions の中で認証情報を利用できるようにします。

Encrypted Secrets について、詳しくは [Encrypted secrets \- GitHub Docs](https://docs.github.com/en/actions/reference/encrypted-secrets) を参照してください。

`Settings` -> `Secrets` を開き、 `New repository secret` を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/6d603e2d-80d6-a0ea-285a-c2e620b05df7.png)
Secrets 名 (スクショでは `DIRECTCLOUDBOX_SERVICE` ) と、それに応じた値を入力してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/a47be147-8fcc-f143-11fd-51f7cebc92a3.png)
5 つと少し多いですが、それぞれ対応する値を登録したら利用準備完了です。

| 環境変数                     | 説明                                                                                             |
| ---------------------------- | ------------------------------------------------------------------------------------------------ |
| `DIRECTCLOUDBOX_SERVICE`     | [管理画面](https://boxmanager.directcloud.jp/setting/image)より発行した API キーの `Service`     |
| `DIRECTCLOUDBOX_SERVICE_KEY` | [管理画面](https://boxmanager.directcloud.jp/setting/image)より発行した API キーの `Service Key` |
| `DIRECTCLOUDBOX_CODE`        | 会社 ID (登録時にメールで届くもの)                                                               |
| `DIRECTCLOUDBOX_ID`          | ユーザー ID                                                                                      |
| `DIRECTCLOUDBOX_PASSWORD`    | ユーザーパスワード                                                                               |

`Actions` タブから再度実行して下記のようなログが出れば成功です。
失敗する場合は Secrets の Key と Value 双方のコピペミスがないか確認してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/7a60ff94-33a2-6fa0-a96a-c2d23b4b26b9.png)
[DirectCloud\-BOXのWebアプリ](https://web.directcloud.jp/mybox/MQ==) からアップロードしたファイルを確認してみましょう。 (サンプルにしたけど md ファイルはWebアプリからはプレビューできなかったという :innocent:)

## ハマりポイント

### DirectCloud-BOX API 利用時のハマりポイント

#### Service, Service Key の発行が分かりにくい

2021/08/22 時点では、[DirectCloud\-BOX API リファレンス](https://directcloud.jp/api_reference/detail/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC/Auth#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E7%99%BA%E8%A1%8C)に以下のように記載があること、その他マニュアルにも記載がないように思えたため、問い合わせをして設定方法をご教示いただきました。

> service、service_key の発行につきましては、お問合せ窓口よりご連絡ください

実際は手順にも書いたとおり、管理画面から発行が可能でした。

#### POST リクエストは form-data の利用が必須

[DirectCloud\-BOX API を実行するまでにハマった事と感想 \- Qiita](https://qiita.com/mikkame/items/e47cdb2e6df35831bac7#jsonbody%E3%81%A7%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%99%E3%82%8B%E3%81%A8%E5%A4%B1%E6%95%97%E3%81%99%E3%82%8B) にも書いてくださっていますが、JSON body だと `There is no required input value` というエラーとともにリクエストが失敗します。

#### 突然の `node`

Folder, File を操作しようとして [API リファレンス](https://directcloud.jp/api_reference/detail/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC/Folder#%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AE%E7%85%A7%E4%BC%9A)を眺めると `node` というパラメータが必要になってきます。
おそらく DirectCloud-BOX 上で内部的にフォルダ管理に利用している値 (グラフ?) だと思うのですが、重要な割に取得方法が初見だと分からなかったです。。

以下の方法で取得できそうです。

- [フォルダリストの照会 API](https://directcloud.jp/api_reference/detail/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC/Folder#%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AE%E7%85%A7%E4%BC%9A) を `node` 無指定で実行すれば起点となる `My Box` と `Shared Box` の node 値を知れるので、そこから芋づる式に API を叩いていく
- [WebApp](https://web.directcloud.jp/home) の URL の末尾の Path (My Box なら `MQ==`)が node 値を Base64 エンコードしたものなので、デコードする

```bash
$ echo "MQ==" | base64 -d
1
```

### GitHub Actions 開発時のハマりポイント

いくつか小さくつまずいたので箇条書きで。

- JavaScript Action で利用できる最新の Node.js が node12
  - 手元では 14 を利用して書いてしまっており、微妙な記法の差異がありました。
- Fork したリポジトリでは Secrets 使えない制限が Repository Template 利用時も適用されている？

  - [今回作成した Actions のログ](https://github.com/tk3fftk/upload-DirectCloud-BOX-action/runs/3392546440?check_suite_focus=true)ですが、何かが設定されていれば `***` のようにマスクされた形で表示される変数が空になってしまっています。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23755/56cefc48-3e1a-c2d5-3762-2c3de070ce61.png)
  - ちょっと情報見つけられなかったので知ってる方いればご教示いただければと思います:pray:

- ワークフローの更新タイミング
  - 普段利用している CI ツール [^1] は PR 時にワークフローの変更が適用されるのですが、GitHub Actions はデフォルトではメインブランチにマージされるまで適用されなさそうでした

## おわりに

DirectCloud-BOX の API を利用し、GitHub Actions のワークフロー内からファイルをアップロードする JavaScript Action を作ってみました。
DirectCloud-BOX の利用登録と認証情報の取得、GitHub Actions の設定を行うだけで Actions 内から任意のファイルのアップロードが可能です。

https://github.com/marketplace/actions/upload-directcloud-box

また、DirectCloud-BOX の API 利用や GitHub Actions 開発のハマりポイントについてもいくつか触れました。

この記事は「[Qiita エンジニアフェスタ 2021](https://qiita.com/official-campaigns/engineer-festa/2021)」の参加記事です。

https://qiita.com/official-campaigns/engineer-festa/2021

https://qiita.com/official-events/64ff6ba4e653a822fce9

[^1]: [Screwdriver\.cd](https://screwdriver.cd/)という CI/CD ツールを利用しています (参考: [GKE で Screwdriver\.cd を動かしてみる)](https://qiita.com/tk3fftk/items/039ed90261f8aa853783)