O hirunewani blog

PRが閉じられたら自動的にNetlifyのDeployを削除する

Created at

NetlifyにはDeployを自動的に削除する機能があるが、よりコントロールしたい場合にはNetlify APIが利用できる。この記事では、Github Actionsで自動的にNetlifyのDeployを削除する方法について紹介する。

Deployに紐づけられているブランチ名を確認する

デプロイ手法(公式のGitHub連携機能を利用するか、Netlify CLIやNetlify APIを利用するかなど)によって、Deployに紐づけられるブランチ名の形式が異なるため、まずはその確認を行う。

次のコマンドを実行すると、サイトに紐づけられた最新のDeploy最大100件を取得できる。

curl -s -X GET \
    -H "Authorization: Bearer $NETLIFY_TOKEN" \
    "https://api.netlify.com/api/v1/sites/$SITE_ID/deploys"

$NETLIFY_TOKENには、NetlifyのPersonal Access Tokenを指定する。

$SITE_IDには、NetlifyのサイトIDを指定する。Netlifyで対応したいサイトの「Site configuration」を開き、Site informationの中にある「Site ID」がそれに該当する。自身が定義したサイト名ではないので注意。

コマンドを実行すると、次のようなレスポンスが得られる。ここにあるbranchフィールドが、ブランチ名に相当するので形式を覚えておく。

[
  {
    "id": "6780b5257d6fc6786f803ba8",
    "site_id": "d098883f-e010-44ac-a441-00b7fc5b6bda",
    "build_id": null,
    "state": "ready",
    "name": "my-site",
    "url": "http://my-site.netlify.app",
    "ssl_url": "https://my-site.netlify.app",
    "admin_url": "https://app.netlify.com/sites/my-site",
    "deploy_url": "http://deploy-preview-1189--my-site.netlify.app",
    "deploy_ssl_url": "https://deploy-preview-1189--my-site.netlify.app",
    // ...
    "branch": "deploy-preview-1189",
    "links": {
      "permalink": "https://6780b5257d6fc6786f803ba8--my-site.netlify.app",
      "alias": "https://deploy-preview-1189--my-site.netlify.app",
      "branch": null
    }
    // ...
  }
  // ...
]

次のようにbranchクエリパラメータに、取得したブランチ名を指定すると、そのブランチに紐づけられたDeployのみを取得できる。

curl -s -X GET \
    -H "Authorization: Bearer $NETLIFY_TOKEN" \
    -d branch=$BRANCH_NAME \
    "https://api.netlify.com/api/v1/sites/$SITE_ID/deploys" |

Preview deployとAlias deploy

Pull Requestに紐づいたDeployには、少なくとも次の2種類がある。この分類は公式のドキュメントによるものではなく、Netlify Support Forumsの記述を元にしているため正確でない可能性がある。

  • Preview deploy
  • Alias deploy

それぞれ次のような形式になっている。Alias deployの形式は、Deploy手法によるが、特殊なことをしていなければPR毎に一意なURLが生成される。

  • Preview deploy:hash値--site-name.netlify.app
  • Alias deploy:deploy-preview-PR番号--site-name.netlify.app

Preview deployは、Pull RequestでpushなどでDeployが要求される度に新しいDeployが作成され、異なるURLが生成される。

Preview deployが行われる度に、Alias deployへのエイリアスが貼られる。

Alias deployを削除する

Netlify APIやNetlify CLIを見ても、Alias deployを削除するためのエンドポイントやコマンドは見当たらない。

Alias deployには、Pull Requestの全てのPreview deployがエイリアスとして紐づいているため、最新のPreview deployを削除しても、Alias deployは1つ前のPreview deployにフォールバックし存続する。

Alias deployを無効化するには、Pull Requestに紐づいた全てのPreview deployを削除する必要がある。

次のように、ブランチに紐づけられた全てのDeployを取得した後に、それぞれを削除することでAlias deployを無効化できる。

curl -s -X GET \
    -H "Authorization: Bearer $NETLIFY_TOKEN" \
    -d branch=$BRANCH_NAME \
    "https://api.netlify.com/api/v1/sites/$SITE_ID/deploys" | \
jq -r '.[].id' | \
while read -r deploy_id; do
    echo "Deleting deploy ID: $deploy_id"
    curl -s -X DELETE \
        -H "Authorization: Bearer $NETLIFY_TOKEN" \
        "https://api.netlify.com/api/v1/sites/$SITE_ID/deploys/$deploy_id"
done

これはブランチに紐づいたDeployが100件を超えることはないという前提で書いている。超えるケースを考慮するのであれば、ページネーションを考慮する必要がある。

ref: https://open-api.netlify.com/#tag/deploy/operation/listSiteDeploys

Pull Requestに紐づけられたNetlify Deployを削除するGitHub Actions

ここまでの内容をGitHub Actionsに組み込んで、Pull Requestが閉じられた際に自動的にNetlify Deployを削除するワークフローを次のように作成できる。

name: Delete Netlify Deploy Preview

on:
  pull_request:
    types:
      - closed

env:
  NETLIFY_TOKEN: ${{ secrets.NETLIFY_TOKEN }}
  # Netlify上のSite IDを記載する
  SITE_ID: ""

jobs:
  delete_netlify_deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Get branch name
        id: branch
        # ここのnameの形式は、NetlifyへのDeploy手法によって異なる可能性があるため、適宜変更する
        run: |
          echo "name=deploy-preview-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
      - name: Fetch and delete deploys from Netlify
        shell: bash
        env:
          BRANCH_NAME: ${{ steps.branch.outputs.name }}
        run: |
          curl -s -X GET \
              -H "Authorization: Bearer $NETLIFY_TOKEN" \
              -d branch=$BRANCH_NAME \
              "https://api.netlify.com/api/v1/sites/$SITE_ID/deploys" | \
          jq -r '.[].id' | \
          while read -r deploy_id; do
              echo "Deleting deploy ID: $deploy_id"
              curl -s -X DELETE \
                  -H "Authorization: Bearer $NETLIFY_TOKEN" \
                  "https://api.netlify.com/api/v1/sites/$SITE_ID/deploys/$deploy_id"
          done

GitHub Actionsではjqがプリインストールされているため、JSONの整形が非常に行いやすい。

Netlifyの機能で自動削除する。90日未満ではEnterpriseプラン以上が必要

Netlifyでは、そもそも90日以上経過したDeployを自動的に削除する機能が提供されている。

https://docs.netlify.com/site-deploys/manage-deploys/#automatic-deploy-deletion

ただし、この日数をコントロールしたい場合は、Enterpriseプラン以上が必要になる。