release #31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: release | |
| # d-party モノレポ root の release ワークフローから統一バージョンを受け取って起動される。 | |
| # 旧 bump_type 方式は廃止し、version を外部入力で受け取る。 | |
| # build + Chrome Web Store への公開は従来どおりここで行う。 | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Release version (X.Y.Z)" | |
| required: true | |
| type: string | |
| release_note: | |
| description: "Release notes (optional)" | |
| required: false | |
| type: string | |
| publish: | |
| description: "Publish to Chrome Web Store (false = upload only; publish manually in the dashboard)" | |
| required: false | |
| type: boolean | |
| default: false | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: main | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Set version | |
| id: version | |
| env: | |
| VERSION_NUM: ${{ inputs.version }} | |
| run: | | |
| echo "new_version=v${VERSION_NUM}" >> "$GITHUB_OUTPUT" | |
| echo "version_num=${VERSION_NUM}" >> "$GITHUB_OUTPUT" | |
| node -e "const fs=require('fs');const p=JSON.parse(fs.readFileSync('package.json','utf8'));p.version=process.env.VERSION_NUM;fs.writeFileSync('package.json',JSON.stringify(p,null,2)+'\n');" | |
| node -e "const fs=require('fs');const m=JSON.parse(fs.readFileSync('public/manifest.json','utf8'));m.version=process.env.VERSION_NUM;fs.writeFileSync('public/manifest.json',JSON.stringify(m,null,2)+'\n');" | |
| - name: Commit and push version bump | |
| run: | | |
| set -euo pipefail | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add package.json public/manifest.json | |
| if git diff --cached --quiet; then | |
| echo "version files already at ${{ steps.version.outputs.new_version }}; skipping bump commit" | |
| else | |
| git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }} [skip ci]" | |
| git push origin HEAD:main | |
| fi | |
| - name: Force-update release tag | |
| run: | | |
| set -euo pipefail | |
| git tag -f "${{ steps.version.outputs.new_version }}" | |
| git push origin "refs/tags/${{ steps.version.outputs.new_version }}" --force | |
| - name: Generate API client | |
| run: pnpm api:generate | |
| - name: Build extension | |
| run: pnpm build:prod | |
| - name: Package extension | |
| run: | | |
| cd dist | |
| zip -r "../d-party_${{ steps.version.outputs.new_version }}.zip" . | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.new_version }} | |
| name: Release ${{ steps.version.outputs.new_version }} | |
| body: ${{ inputs.release_note }} | |
| files: d-party_${{ steps.version.outputs.new_version }}.zip | |
| generate_release_notes: true | |
| target_commitish: main | |
| # Chrome Web Store API を curl で直接叩く。 | |
| # 以前は mnao305/chrome-extension-upload を使っていたが、API のレスポンスボディを | |
| # 一切ログに出さない仕様のため 400 等の障害切り分けが不可能だった | |
| # (`itemError[].error_code` / `uploadState` / `statusDetail` が見えない)。 | |
| # ここでは OAuth2 token exchange → upload(PUT) → publish(POST) を順に実行し、 | |
| # 各レスポンスを JSON のまま GitHub Actions ログへ出力する。 | |
| # 参考: https://developer.chrome.com/docs/webstore/using-api | |
| - name: Upload to Chrome Web Store | |
| env: | |
| EXTENSION_ID: ${{ secrets.EXTENSION_ID }} | |
| CLIENT_ID: ${{ secrets.CLIENT_ID }} | |
| CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }} | |
| REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }} | |
| PUBLISH: ${{ inputs.publish }} | |
| ZIP: d-party_${{ steps.version.outputs.new_version }}.zip | |
| run: | | |
| set -euo pipefail | |
| # 1) refresh token -> access token | |
| echo "::group::Exchange refresh_token for access_token" | |
| token_resp=$(curl -sS -X POST https://oauth2.googleapis.com/token \ | |
| --data-urlencode "client_id=${CLIENT_ID}" \ | |
| --data-urlencode "client_secret=${CLIENT_SECRET}" \ | |
| --data-urlencode "refresh_token=${REFRESH_TOKEN}" \ | |
| --data-urlencode "grant_type=refresh_token") | |
| # access_token / id_token はログに出さない | |
| echo "${token_resp}" | jq 'del(.access_token, .id_token)' | |
| echo "::endgroup::" | |
| access_token=$(echo "${token_resp}" | jq -r '.access_token // empty') | |
| if [ -z "${access_token}" ]; then | |
| echo "::error::failed to obtain access_token (see token response above)" | |
| exit 1 | |
| fi | |
| # 2) Upload zip (PUT). 既存ドラフトを上書きする。 | |
| echo "::group::Upload ${ZIP} to item ${EXTENSION_ID}" | |
| upload_resp=$(curl -sS -X PUT \ | |
| -H "Authorization: Bearer ${access_token}" \ | |
| -H "x-goog-api-version: 2" \ | |
| -T "${ZIP}" \ | |
| "https://www.googleapis.com/upload/chromewebstore/v1.1/items/${EXTENSION_ID}") | |
| echo "${upload_resp}" | jq . | |
| echo "::endgroup::" | |
| upload_state=$(echo "${upload_resp}" | jq -r '.uploadState // empty') | |
| if [ "${upload_state}" != "SUCCESS" ]; then | |
| echo "::error::CWS upload failed (uploadState=${upload_state:-<none>})" | |
| exit 1 | |
| fi | |
| # 3) Publish (任意)。既定はアップロードのみ。 | |
| if [ "${PUBLISH}" = "true" ]; then | |
| echo "::group::Publish item ${EXTENSION_ID}" | |
| publish_resp=$(curl -sS -X POST \ | |
| -H "Authorization: Bearer ${access_token}" \ | |
| -H "x-goog-api-version: 2" \ | |
| -H "Content-Length: 0" \ | |
| "https://www.googleapis.com/chromewebstore/v1.1/items/${EXTENSION_ID}/publish") | |
| echo "${publish_resp}" | jq . | |
| echo "::endgroup::" | |
| status=$(echo "${publish_resp}" | jq -r '.status[0] // empty') | |
| case "${status}" in | |
| OK|ITEM_PENDING_REVIEW) ;; | |
| *) | |
| echo "::error::CWS publish failed (status=${status:-<none>})" | |
| exit 1 | |
| ;; | |
| esac | |
| else | |
| echo "publish=false: アップロードのみ完了。公開は Developer Dashboard から手動で行ってください。" | |
| fi |