🚀

Chrome拡張の手動アップロードをやめた — release-please + GitHub Actionsで公開を完全自動化

に公開

アイキャッチ

はじめに

Chrome拡張機能のリリース作業は地味に手間がかかります。zipファイルを作って、Chrome Web Store Developer Dashboardを開いて、アップロードして、公開ボタンを押す。1回あたり数分の作業ですが、複数の拡張機能を管理していると、リリースのたびにこの手順を繰り返すのがじわじわとストレスになります。

この記事では release-pleaseGitHub Actions を組み合わせて、Conventional Commitsでコミットし、Release PRをマージするだけでChrome Web Storeへの公開まで完了する仕組みを紹介します。一度設定すれば、手動でのアップロード作業はゼロになります。

なぜrelease-pleaseなのか

リリース自動化ツールにはsemantic-releaseという選択肢もありますが、今回はrelease-pleaseを採用しました。

  • semantic-releaseはマージ即リリースですが、release-pleaseはRelease PRを挟むため、CHANGELOGやバージョン番号を確認してからリリースできる
  • Google製なのでChrome Web Store APIとの相性がよく、同じエコシステムで統一できる
  • extra-filesmanifest.jsonのバージョンも一緒に更新でき、Chrome拡張特有のバージョン管理に対応しやすい

全体の流れ

  1. fix:feat: プレフィックス付きでコミット
  2. release-pleaseがRelease PRを自動作成
  3. Release PRをマージするとリリースが作成される
  4. リリース作成をトリガーにChrome Web Storeへ自動アップロード

事前準備

Google Cloud ConsoleでOAuth認証情報を取得

Chrome Web Store APIを使うには、OAuth 2.0の認証情報が必要です。

  1. Google Cloud Consoleにアクセス
  2. プロジェクトを作成(または既存のものを選択)
  3. 「APIとサービス」→「ライブラリ」から Chrome Web Store API を有効化
  4. 「APIとサービス」→「認証情報」→「認証情報を作成」→「OAuthクライアントID」
  5. アプリケーションの種類は「デスクトップアプリ」を選択
  6. 作成後、クライアントIDクライアントシークレット をメモ

リフレッシュトークンの取得

リフレッシュトークンは手動で取得します。

# 変数を設定
CLIENT_ID="your-client-id"
CLIENT_SECRET="your-client-secret"

# 認証URLを開く(macOS)
open "https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https://www.googleapis.com/auth/chromewebstore&client_id=${CLIENT_ID}&redirect_uri=urn:ietf:wg:oauth:2.0:oob"

ブラウザで認証後、表示される認証コードを使ってリフレッシュトークンを取得:

AUTH_CODE="ブラウザに表示された認証コード"

curl -s -X POST https://oauth2.googleapis.com/token \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" \
  -d "code=${AUTH_CODE}" \
  -d "grant_type=authorization_code" \
  -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob"

レスポンスの refresh_token を保存します。

GitHub Secretsの設定

リポジトリの Settings → Secrets and variables → Actions で以下を設定:

Secret名
CHROME_EXTENSION_ID 拡張機能のID
CHROME_CLIENT_ID OAuthクライアントID
CHROME_CLIENT_SECRET OAuthクライアントシークレット
CHROME_REFRESH_TOKEN 取得したリフレッシュトークン
拡張機能IDの確認方法

Chrome Web Store Developer Dashboardで拡張機能を選択し、URLの末尾にあるIDをコピーします。
https://chrome.google.com/webstore/detail/[EXTENSION_ID]

CHROME_CLIENT_IDCHROME_CLIENT_SECRETCHROME_REFRESH_TOKEN は複数のリポジトリで共通で使えます。CHROME_EXTENSION_ID だけが拡張機能ごとに異なります。

リポジトリの権限設定

Settings → Actions → General で以下を設定します。

  • Workflow permissionsを「Read and write permissions」に変更
  • 「Allow GitHub Actions to create and approve pull requests」にチェック

ワークフローの設定

release-please-config.json

manifest.json のバージョンを自動更新するために extra-files を設定します。

release-please-config.json
{
  "packages": {
    ".": {
      "release-type": "node",
      "bump-minor-pre-major": true,
      "bump-patch-for-minor-pre-major": true,
      "extra-files": [
        {
          "type": "json",
          "path": "manifest.json",
          "jsonpath": "$.version"
        }
      ]
    }
  },
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}

.github/workflows/release-please.yml

.github/workflows/release-please.yml
name: Release Please

on:
  push:
    branches: [main]

permissions:
  contents: write
  pull-requests: write

jobs:
  release-please:
    runs-on: ubuntu-latest
    outputs:
      release_created: ${{ steps.release.outputs.release_created }}
      tag_name: ${{ steps.release.outputs.tag_name }}
    steps:
      - uses: googleapis/release-please-action@v4
        id: release
        with:
          release-type: node

  publish-to-chrome-web-store:
    needs: release-please
    if: ${{ needs.release-please.outputs.release_created }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Create zip file
        run: |
          zip -r extension.zip . \
            -x "*.git*" \
            -x "node_modules/*" \
            -x "*.md" \
            -x "package*.json" \
            -x ".github/*" \
            -x "tests/*"

      - name: Upload to Chrome Web Store
        uses: mnao305/chrome-extension-upload@v5.0.0
        with:
          file-path: extension.zip
          extension-id: ${{ secrets.CHROME_EXTENSION_ID }}
          client-id: ${{ secrets.CHROME_CLIENT_ID }}
          client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
          refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
          publish: true

このワークフローでは、release-please ジョブの outputs でリリース作成を検知し、publish-to-chrome-web-store ジョブは release_created が true の時だけ実行されます。zipファイル作成時には .gitnode_modules、ドキュメント類を除外しています。

手動公開用ワークフロー(オプション)

緊急時の手動公開用に workflow_dispatch も用意しておくと便利です。

.github/workflows/publish-chrome.yml
name: Publish to Chrome Web Store

on:
  workflow_dispatch:

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Create zip file
        run: |
          zip -r extension.zip . \
            -x "*.git*" \
            -x "node_modules/*" \
            -x "*.md" \
            -x "package*.json" \
            -x ".github/*"

      - name: Upload to Chrome Web Store
        uses: mnao305/chrome-extension-upload@v5.0.0
        with:
          file-path: extension.zip
          extension-id: ${{ secrets.CHROME_EXTENSION_ID }}
          client-id: ${{ secrets.CHROME_CLIENT_ID }}
          client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
          refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
          publish: true

よくあるエラーと対処法

Invalid version number in manifest

package.jsonmanifest.json のバージョンが一致していない場合に発生。

対処法: release-please-config.jsonextra-files を追加して manifest.json も自動更新されるようにする。

GitHub Actions is not permitted to create or approve pull requests

リポジトリの権限設定が不足しています。

対処法: Settings → Actions → General で「Allow GitHub Actions to create and approve pull requests」を有効にする。

403 access_denied

OAuth同意画面でテストユーザーに追加されていない。

対処法: Google Cloud Console → OAuth同意画面 → テストユーザーに自分のメールアドレスを追加。

審査中に新バージョンをアップロードした場合

Chrome Web Storeで審査中のバージョンがある状態で新しいバージョンをアップロードすると、審査中のバージョンは自動的にキャンセルされ、新しいバージョンが審査キューに入ります。

おわりに

この仕組みを導入してから、Chrome拡張機能のリリース作業が格段に楽になりました。Conventional Commitsでコミットして、Release PRをマージするだけで公開まで完了します。

複数のChrome拡張機能を管理している場合は、OAuth認証情報を共通で使えるので、最初の設定さえ済めば2つ目以降は CHROME_EXTENSION_ID を設定するだけです。

実際にこの仕組みで自動公開しているChrome拡張機能もあるので、よければ使ってみてください。

関連記事

Chrome拡張の開発記事をほかにも書いています。

参考リンク

Discussion