Skip to content

Browser-showpiece hero, SEO, and design polish for reins.tech (#23) #23

Browser-showpiece hero, SEO, and design polish for reins.tech (#23)

Browser-showpiece hero, SEO, and design polish for reins.tech (#23) #23

Workflow file for this run

name: release
# Fully automated, changeset-driven — no manual tags (see docs/RELEASING.md).
#
# Push changesets to main → this opens a "Version Packages" PR. Merge that PR →
# this publishes @karnstack/reins to npm, tags + GitHub-releases it, and (once
# the Chrome Web Store secrets exist) uploads the extension zip to the store.
on:
push:
branches: [main]
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: write # create tags + GitHub releases
pull-requests: write # open the Version Packages PR
id-token: write # npm provenance
jobs:
release:
runs-on: ubuntu-latest
env:
# Web Store steps run only once these secrets are set (after the first
# manual store upload, which is what assigns the extension its ID).
HAS_CWS: ${{ secrets.CWS_REFRESH_TOKEN != '' && secrets.CWS_EXTENSION_ID != '' }}
steps:
- uses: actions/checkout@v7.0.0
- uses: jdx/mise-action@v4.2.0
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test
- run: pnpm build
- name: Version or publish (changesets)
id: changesets
uses: changesets/action@v1
with:
version: pnpm version-packages
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: "true"
- name: Package the extension
if: steps.changesets.outputs.published == 'true'
id: zip
run: |
pnpm zip
echo "path=$(ls packages/extension/release/*.zip)" >> "$GITHUB_OUTPUT"
# The extension is `linked` (not `fixed`) to the CLI, so CLI-only
# releases leave its version untouched. Re-uploading a version the store
# already has would fail the API call — and every upload triggers manual
# review (debugger permission), so skip when there is nothing new.
- name: Check whether the store needs this version
if: steps.changesets.outputs.published == 'true' && env.HAS_CWS == 'true'
id: store
env:
CWS_EXTENSION_ID: ${{ secrets.CWS_EXTENSION_ID }}
CWS_CLIENT_ID: ${{ secrets.CWS_CLIENT_ID }}
CWS_CLIENT_SECRET: ${{ secrets.CWS_CLIENT_SECRET }}
CWS_REFRESH_TOKEN: ${{ secrets.CWS_REFRESH_TOKEN }}
run: |
local=$(jq -r .version packages/extension/package.json)
token=$(curl -sf https://oauth2.googleapis.com/token \
-d "client_id=${CWS_CLIENT_ID}&client_secret=${CWS_CLIENT_SECRET}&refresh_token=${CWS_REFRESH_TOKEN}&grant_type=refresh_token" \
| jq -r .access_token)
store=$(curl -sf -H "Authorization: Bearer ${token}" \
"https://www.googleapis.com/chromewebstore/v1.1/items/${CWS_EXTENSION_ID}?projection=DRAFT" \
| jq -r .crxVersion)
echo "extension v${local} locally, v${store} on the store"
if [ "$local" = "$store" ]; then
echo "store is current — skipping upload"
echo "upload=false" >> "$GITHUB_OUTPUT"
else
echo "upload=true" >> "$GITHUB_OUTPUT"
fi
- name: Upload extension to the Chrome Web Store
if: steps.store.outputs.upload == 'true'
uses: mnao305/chrome-extension-upload@v5.0.0
with:
file-path: ${{ steps.zip.outputs.path }}
extension-id: ${{ secrets.CWS_EXTENSION_ID }}
client-id: ${{ secrets.CWS_CLIENT_ID }}
client-secret: ${{ secrets.CWS_CLIENT_SECRET }}
refresh-token: ${{ secrets.CWS_REFRESH_TOKEN }}
publish: true