0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Github ActionsをWIF経由でChrome拡張機能を自動リリースする

0
Posted at

Chrome拡張機能のリリースって面倒くさいですよね。Chrome Web Storeにアクセス → 拡張機能をzip化 → アップロードという作業を毎回行う必要があり、さらに以下も確認しなければなりません。

  • アップロードするファイルは最新か
  • manifest.json のバージョンを更新したか
  • 正しいzipファイルを選択しているか

アップロードしてから「バージョンが既に使用されています」と怒られ、manifest.json を修正して再度zip化するのもかなり面倒です。決まった手順は自動化してしまいましょう。今回は、GitHub ActionsからWorkload Identity Federation(WIF)経由でChrome Web Storeへ拡張機能をリリースする方法を紹介します。調べてもこの方法がネットで出てこなかったので執筆しました。同じ方法で考えていた方は参考になると思います。

なぜWIFを使うのか

一応モチベを共有します。WIF経由でリリースする方法は他の文献でかなり紹介されています。具体的にはGitHub ActionsからGoogle Cloudへ認証する方法として、Service Account KeyのJSONをGitHub Secretsに保存する方法です。
ただし、長期間利用できる秘密鍵をGitHub側で管理する必要があり、流出時のリスクもあります。あと、複数の場所にデータを点在させるのってなんかカッコよくないですよね。

こういった背景から原則、環境変数をGoogle CLoudのSecret Managerに集約させて運用する開発スタイルをとっています。

そこで今回は Workload Identity Federation(WIF) を利用します。WIFを利用すると、GitHub Actionsが発行するOIDCトークンを使ってGoogle CloudのService Accountとして認証できます。つまり、Service Account KeyをGitHubに保存せずGoogle Cloudへ認証できます。
今回はこの仕組みを利用してChrome Web Store APIを呼び出します。

全体の流れ

  1. Google CloudでService Accountを作成する
  2. WIFを設定する
  3. Chrome Web StoreにService Accountを登録する
  4. GitHub ActionsのSecretsを設定する
  5. GitHub Actionsからビルド・アップロード・公開する

1. Google CloudでService Accountを作成する

Chrome Web Storeへのリリースに使用するService Accountを作成します。

例えば以下のような名前にします。

chrome-web-store-deployer

このService Accountを、GitHub ActionsからWIF経由で利用します。好みのアカウント名にしてください。

2. Workload Identity Federationを設定する

GitHub ActionsからService Accountとして認証できるよう、Google Cloud側でWIFを設定します。

主に以下を作成します。

  • Workload Identity Pool
  • Workload Identity Provider
  • Service Accountとの紐付け

GitHub Actionsが発行したOIDCトークンをGoogle Cloud側で検証し、条件を満たしていればService Accountとして認証します。

3. Chrome Web StoreにService Accountを登録する

Webでサービスアカウントを登録する場所があるので作成したアカウントを登録しましょう。

4. GitHub ActionsのWorkflowを作成する

name: Deploy to Chrome Web Store

on:
  workflow_dispatch:

permissions:
  contents: read
  id-token: write

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v7

      - name: Setup pnpm
        uses: pnpm/action-setup@v6

      - name: Setup Node.js
        uses: actions/setup-node@v7
        with:
          node-version: 24
          cache: pnpm

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build extension
        run: pnpm zip

      - name: Authenticate to Google Cloud
        id: auth
        uses: google-github-actions/auth@v3
        with:
          workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/github-actions/providers/github
          service_account: chrome-web-store-deployer@example-project.iam.gserviceaccount.com
          token_format: access_token
          access_token_scopes: https://www.googleapis.com/auth/chromewebstore

      - name: Upload to Chrome Web Store
        run: |
          curl -f -X POST \
            -H "Authorization: Bearer ${{ steps.auth.outputs.access_token }}" \
            -T .output/*-chrome.zip \
            "https://chromewebstore.googleapis.com/upload/v2/publishers/PUBLISHER_ID/items/EXTENSION_ID:upload"

      - name: Publish to Chrome Web Store
        run: |
          curl -f -X POST \
            -H "Authorization: Bearer ${{ steps.auth.outputs.access_token }}" \
            "https://chromewebstore.googleapis.com/v2/publishers/PUBLISHER_ID/items/EXTENSION_ID:publish"

上記のワークフローはこんな感じの手順を踏んでいます。とても綺麗ですね。

GitHub Actions
      ↓
ソースコードのビルド
     ↓
WIF経由で認証
     ↓
Chrome Web Storeへアップロード
     ↓
    公開

補足: 拡張機能のバージョン更新も自動化する

Chrome Web Storeでは、前回と同じバージョンの拡張機能はアップロードできません。

そのため、リリース前に manifest.json 相当のバージョンを更新する必要があります。

今回はWXTを利用しているため、wxt.config.tsversion をGitHub Actionsから更新し、その変更をPull Requestとして作成します。

name: Bump Extension Version

on:
  workflow_dispatch:
    inputs:
      bump_type:
        description: "Version bump type"
        required: true
        type: choice
        options:
          - patch
          - minor
          - major

permissions:
  contents: write
  pull-requests: write

jobs:
  bump:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v7

      - name: Bump version
        id: bump
        env:
          BUMP_TYPE: ${{ inputs.bump_type }}
        run: |
          set -euo pipefail

          path="wxt.config.ts"

          current_version=$(grep -Eo \
            "version:[[:space:]]*['\"][0-9]+\.[0-9]+\.[0-9]+['\"]" \
            "$path" \
            | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")

          IFS='.' read -r major minor patch <<< "$current_version"

          case "$BUMP_TYPE" in
            major)
              major=$((major + 1))
              minor=0
              patch=0
              ;;
            minor)
              minor=$((minor + 1))
              patch=0
              ;;
            patch)
              patch=$((patch + 1))
              ;;
          esac

          new_version="${major}.${minor}.${patch}"

          sed -i -E \
            "s/version:[[:space:]]*['\"][0-9]+\.[0-9]+\.[0-9]+['\"]/version: '${new_version}'/" \
            "$path"

          echo "current_version=${current_version}" >> "$GITHUB_OUTPUT"
          echo "new_version=${new_version}" >> "$GITHUB_OUTPUT"
          echo "branch=ver/extension-${new_version}" >> "$GITHUB_OUTPUT"

      - name: Create Pull Request
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

          git checkout -b "${{ steps.bump.outputs.branch }}"
          git add wxt.config.ts
          git commit -m "chore: bump extension version to ${{ steps.bump.outputs.new_version }}"
          git push origin "${{ steps.bump.outputs.branch }}"

          gh pr create \
            --title "chore: bump extension version to ${{ steps.bump.outputs.new_version }}" \
            --body "Bump extension version from ${{ steps.bump.outputs.current_version }} to ${{ steps.bump.outputs.new_version }}." \
            --base main \
            --head "${{ steps.bump.outputs.branch }}"

Workflow実行時に patch / minor / major を選択すると、現在のバージョンから次のバージョンを計算します。

例えば、

1.2.3 + patch → 1.2.4
1.2.3 + minor → 1.3.0
1.2.3 + major → 2.0.0

となります。更新後は専用ブランチを作成し、バージョン変更のPull Requestまで自動で作成します。

バージョンを選択
    ↓
wxt.config.ts を更新
    ↓
commit / push
    ↓
Pull Request作成

PRをマージした後にChrome Web StoreへのデプロイWorkflowを実行することで、バージョン更新からリリースまでの手作業をかなり減らせます。今回はPRの作成までですが、プロダクトによってはpr作成後に自動でmerge+closeまでやっちゃっても良いかもしれないです。(これ相当便利ですね。なんだかんだこういう作業も2~3分かかるので)

おわりに

このワークフローを作成したことで、これまで煩わしかった手動アップロードから離れることが出来ました。古いソースコードをビルドして、リリースとかやらかしそうだったので初期段階で導入出来てよかったです。バージョンアップまで考えると、リリース毎に5分節約できるのと、ストレス軽減できます。是非参考にしてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?