public note

.gcloudignore をホワイトリスト方式で設定する

gcloud builds submit コマンドで、ビルドコンテキストをリポジトリのルートディレクトリにする機会がありました。

そのままではリポジトリ内にあるすべてのファイルが Cloud Build へ送信されてしまうので、.gcloudignore を使って特定のディレクトリ・ファイルのみをアップロードします。そのホワイトリスト方式の設定についてのメモです。

結論

  • .gitignore とだいたい同じ
  • アップロード対象の確認には gcloud meta list-files-for-upload コマンドが便利
  • ディレクトリを許可するにはその親ディレクトリが許可されている必要がある
  • 最初にすべてのディレクトリやファイルを ignore するには ** を使うのがよさそう

.gcloudignore

gcloud コマンドは、Google Cloud へアップロードする対象のファイルを選択できるように .gcloudignore ファイルに対応している。ドキュメントはこちら

cloud.google.com

.gitignore とだいたい同じらしいが、そもそも .gitignore でホワイトリスト方式はやったことがない。

下記のディレクトリ構成を例に、py ファイルをアップロード対象にすることを考える。話を単純にしたいので素朴な名称にしている

$ tree                             
.
├── README.md
├── a
│   ├── a.log
│   ├── a.py
│   └── ax
│       ├── ax.log
│       └── ax.py
├── b
│   ├── b.log
│   ├── b.py
│   └── by
│       ├── by.log
│       └── by.py
├── c
│   └── c.py
└── requirements.txt

最初に書いた書き方

$ cat .gcloudignore
*

!a/ax/*.py
!b/**/*.py

ドキュメントから、アップロード対象の確認には gcloud meta list-files-for-upload コマンドが便利という情報を得た

$ gcloud meta list-files-for-upload
$ 

すべて ignore されてしまった

許可するディレクトリを明示する

ドキュメントを読んだ結果、途中のディレクトリを許可すればよいらしい。このように変えてみる

$ cat .gcloudignore
*

!a/
!a/ax/
!a/ax/*.py
!b/**/
!b/**/*.py
$ gcloud meta list-files-for-upload
a/ax/ax.log
a/ax/ax.py
b/b.py
b/by/by.py
b/by/by.log

log ファイルが入るのが解せない

先頭の * 指定で起きていたこと

試行錯誤の末、先頭の * があやしいことがわかってきた。

こういうことだったらしい

$ cat .gcloudignore
# カレントディレクトリ内のファイルとディレクトリ(ディレクトリ直下のファイルを含む)を ignore
# -> a/ax や b/by などの孫以下のディレクトリの内容には影響しない
*

# a ディレクトリを許可
# -> a ディレクトリの中は ignore されている
!a/

# a/ax ディレクトリを許可
# -> a/ax ディレクトリの中は ignore されていないので、a/ax ディレクトリが許可されたことで ax.py や ax.log が対象に加わる
!a/ax/

# a/ax ディレクトリにある *.py を許可
# -> もともと ignore されていないけど明示的に許可
!a/ax/*.py

# b ディレクトリやその中のすべてのサブディレクトリを許可
# -> b ディレクトリの中は ignore されている
# -> b のサブディレクトリの内容は ignore されていないので、サブディレクトリが許可されたことで対象に加わる
!b/**/

# b ディレクトリやその中のすべてのサブディレクトリにある *.py を含める
# -> b/b.py はここで許可される
# -> b/by/by.py はもともと ignore されていないけど明示的に許可
!b/**/*.py
$ gcloud meta list-files-for-upload
a/ax/ax.log
a/ax/ax.py
b/b.py
b/by/by.py
b/by/by.log

** に変更

ディレクトリ以下もすべて ignore するためには、** にするのが正解ぽい

$ cat .gcloudignore
# カレントディレクトリにあるすべてのファイルとディレクトリを ignore
**

# a ディレクトリを許可
# -> a ディレクトリの内容は ignore されたまま
!a/

# a/ax ディレクトリを許可
# -> a/ax ディレクトリの内容は ignore されたまま
!a/ax/

# a/ax ディレクトリにある *.py を許可
!a/ax/*.py

# b ディレクトリや b のすべてのサブディレクトリを許可
# -> b のサブディレクトリの中は ignore されたまま
!b/**/

# b ディレクトリや b のすべてのサブディレクトリにある *.py を含める
!b/**/*.py
$ gcloud meta list-files-for-upload
a/ax/ax.py
b/b.py
b/by/by.py