aqua の local registry で fork したツールをインストールできるようにする

Qiita では、一部コマンドラインツールの管理に、 [aqua](https://aquaproj.github.io/) を利用しています。
インストール作業を簡略化出来たり、バージョンを固定できたり、チームで利用する際に非常に便利なツールです。

そんな中、 aqua で管理しているツールに対して、 fork して、patch を当てたい、本体に取り込んでもらうまでの間、一時的に fork している方を使いたい、ということがありました。 (具体的には [ecschedule](https://github.com/Songmu/ecschedule) というツールに以下の patch を当てていて、 merge されるまでは fork した方を使いたい、というものです。)

https://github.com/Songmu/ecschedule/pull/104

こうした場合も、 local registry を使うことで fork した場合 aqua で管理することが出来るので、今回の自分の例を元に、やり方を紹介します。

## 1. local registry を作る

aqua で普段インストールしているツール (package) は [aquaproj/aqua-registry: aqua's Standard Registry](https://github.com/aquaproj/aqua-registry) 内に package 定義があるのですが、 fork している場合は当然ここにはありません。

なので fork したツールの package 定義を書いたファイルを用意し、それを registry として参照する (local registry) ことをします。

### 1-1. registry ファイルの作成

registry の作り方ですが、以下のいずれかの方法で雛形を作成できます。(ここでは `registry.yaml` ファイルとして作成します。)

* Standard Registry 内の既存の registry の定義をコピーする
    * `https://github.com/aquaproj/aqua-registry/blob/main/pkgs/[package 名]/registry.yaml` に registry 定義があるのでそれをコピーする
* `aqua generate-registry` コマンドを使って
    * 詳しくは [Develop a Registry | aqua](https://aquaproj.github.io/docs/develop-registry/#scaffold-registry-configuration) を参照

今回だと、Standard Registry に既存の registry 定義があったので、これをコピーします。

<details><summary>既存の registry 定義</summary>

```registry.yaml
packages:
  - type: github_release
    repo_owner: Songmu
    repo_name: ecschedule
    description: ecschedule is a tool to manage ECS Scheduled Tasks
    asset: ecschedule_{{.Version}}_{{.OS}}_{{.Arch}}.{{.Format}}
    format: tar.gz
    supported_envs:
      - darwin
      - linux
    files:
      - name: ecschedule
        src: ecschedule_{{.Version}}_{{.OS}}_{{.Arch}}/ecschedule
    overrides:
      - goos: darwin
        format: zip
    checksum:
      type: github_release
      asset: SHA256SUMS
      algorithm: sha256
    version_constraint: semver(">= 0.7.0")
    version_overrides:
      # darwin/amd64 wasn't supported
      - version_constraint: semver("= 0.5.1")
        checksum:
          enabled: false
        supported_envs:
          - linux
          - darwin/arm64
      # checksum file not provided
      - version_constraint: semver(">= 0.3.2")
        checksum:
          enabled: false
      # arm64 wasn't supported
      - version_constraint: "true"
        supported_envs:
          - darwin
          - linux/amd64
        rosetta2: true
        checksum:
          enabled: false
```

> https://github.com/aquaproj/aqua-registry/blob/v4.200.0/pkgs/Songmu/ecschedule/registry.yaml より

</details>

また、コピーした registry 定義は、 fork した方を参照するように書き換えたり、 aqua が取得できる場所 (GitHub Release など) に package を配置する必要があります。

(※ 以下は GitHub Release を利用した package の場合のやり方を説明します。その他の package を利用する場合は、以下のリファレンスを参考にやってみてください。)

https://aquaproj.github.io/docs/reference/registry-config/

### 1-2. fork したリポジトリを参照するように registry を変更する

github_release package の場合、 `repo_owner`, `repo_name` が GitHub リポジトリを参照しているので、 fork したリポジトリを参照するように変更します。

```diff
--- aqua-registry.yml   2024-06-30 22:12:11
+++ aqua-registry.yml   2024-06-30 22:12:32
@@ -1,6 +1,6 @@
 packages:
   - type: github_release
-    repo_owner: Songmu
+    repo_owner: tomoasleep
     repo_name: ecschedule
     description: ecschedule is a tool to manage ECS Scheduled Tasks
     asset: ecschedule_{{.Version}}_{{.OS}}_{{.Arch}}.{{.Format}}
```

### 1-3. fork したリポジトリに GitHub Release を作る

aqua が参照できるように、 fork したリポジトリに、変更済みの内容を含む GitHub Release を作成し、オリジナルのリポジトリと同じように Assets としてツールが配置された状態にします。

https://github.com/tomoasleep/ecschedule/releases/tag/v0.100.0

ここのやり方は、リポジトリによってまちまちなのですが、最近では GitHub Actions で tag や release が作成されたら自動でビルド等が行われることが多いので、 `.github/` ディレクトリなどを見てリリースフローを把握すると良いでしょう。

## 2. `aqua.yaml` を local registry を参照するように設定する

以下の通りに aqua.yaml を書いて、 1 で作成した registry, GitHub Release を参照するようにします。

```aqua.yaml
registries:
# Standard registry の定義 (ここは元のままで OK)
- type: standard
  ref: v4.155.1  # renovate: depName=aquaproj/aqua-registry
# local registry を参照するようにする
- name: local
  type: local
  path: registry.yaml # 1 で作成した registry ファイルのパス

packages:
- name: tomoasleep/ecschedule@v0.100.0 # fork したリポジトリ名と、 1 で作成した release の version になるようにする
  registry: local
```

## 3. 作成した local registry を policy で許可する

aqua では、 standard registry 以外は Policy ファイルを作成し、各ユーザーがそのポリシーを明示的に許可をしない限り使うことが出来ません。

https://aquaproj.github.io/docs/guides/policy-as-code

### 3-1. Policy ファイルの作成

Policy ファイルは、どの registry, どの (種類の) packages を使うかを表現するファイルです。このファイルの条件を満たさない registry, package はインストールできません。

```console
aqua policy init
```

を実行し、 `aqua-policy.yaml` ファイルが以下の内容を含んでいることを確認します。

```aqua-policy.yaml
registries:
# 以下の registry のみ利用できる
- name: local
  type: local
  path: registry.yaml
- type: standard
  ref: semver(">= 3.0.0")

packages:
# local, standard registry の package のみ利用できる
- registry: local
- registry: standard
```

※ Policy ファイルの探索方法は以下の通りに、 `aqua-policy.yaml` など決められているので、その通りの場所に置くか、探索パスの設定を指定する必要があります。

https://aquaproj.github.io/docs/reference/security/policy-as-code/git-policy

### 3-2. Policy ファイルを allow する (各利用者が実行する必要がある)

3-1 で作成した Policy ファイルは、各利用者で許可する必要があります。(許可するまで、 local registry のツールはインストールできません)

以下のコマンドで許可します。

```console
aqua policy allow
```

CI でも Policy ファイルを許可する必要があります。 `aqua-installer` を利用している場合は、以下の方法で許可出来ます。

```yaml
- uses: aquaproj/aqua-installer@v3.0.1
  with:
    aqua_version: v2.28.0
    policy_allow: "true"
```

https://aquaproj.github.io/docs/guides/policy-as-code#aqua-installers-policy_allow-input