#!/usr/bin/env bash # sign-xpi.sh — sign Firefox extension via AMO API directly # Usage: ./scripts/sign-xpi.sh [version] set -euo pipefail cd "$(dirname "$0")/.." # Load .env set -a; source .env; set -a SOURCE_DIR="${WEB_EXT_SOURCE_DIR:-extension-firefox}" ARTIFACTS_DIR="${WEB_EXT_ARTIFACTS_DIR:-web-ext-artifacts}" CHANNEL="${WEB_EXT_CHANNEL:-unlisted}" VERSION="${1:-$(node -e "console.log(require('./$SOURCE_DIR/manifest.json').version)")}" ADDON_ID="verstak-bridge@verstak.app" echo "=== Signing Firefox extension v$VERSION ===" echo "Source: $SOURCE_DIR" echo "Channel: $CHANNEL" echo "" # Step 1: Create JWT token JWT=$(node -e " const jwt = require('jsonwebtoken'); const payload = { iss: '$WEB_EXT_API_KEY', jti: Math.random().toString(36).slice(2), iat: Math.floor(Date.now()/1000), exp: Math.floor(Date.now()/1000) + 300 }; console.log(jwt.sign(payload, '$WEB_EXT_API_SECRET')); ") API_BASE="https://addons.mozilla.org/api/v5" PROXY="$WEB_EXT_API_PROXY" # Step 2: Check if version already exists echo "==> Checking if version $VERSION exists..." EXISTING=$(curl -s --proxy "$PROXY" \ "$API_BASE/addons/$ADDON_ID/versions/$VERSION/" \ -H "Authorization: JWT $JWT" \ -o /dev/null -w "%{http_code}") if [[ "$EXISTING" == "200" ]]; then echo " Version $VERSION already exists, uploading new file..." # Upload to existing version UPLOAD_URL="$API_BASE/addons/$ADDON_ID/versions/$VERSION/" else echo " Creating new version $VERSION..." # Create new version UPLOAD_URL="$API_BASE/addons/$ADDON_ID/versions/" fi # Step 3: Build the XPI (zip) echo "==> Building XPI..." mkdir -p "$ARTIFACTS_DIR" XPI_FILE="$ARTIFACTS_DIR/verstak-bridge-$VERSION.xpi" cd "$SOURCE_DIR" zip -r "../$XPI_FILE" \ manifest.json background.js popup/ icons/ \ -x "*/.DS_Store" "*/Thumbs.db" "*/node_modules/*" "*/.git/*" cd .. echo " XPI: $XPI_FILE ($(du -h "$XPI_FILE" | cut -f1))" # Step 4: Upload XPI to AMO echo "==> Uploading to AMO..." if [[ "$EXISTING" == "200" ]]; then # Upload file to existing version RESPONSE=$(curl -s --proxy "$PROXY" \ -X POST \ "$API_BASE/addons/$ADDON_ID/versions/$VERSION/" \ -H "Authorization: JWT $JWT" \ -F "upload=@$XPI_FILE" \ -F "channel=$CHANNEL") else # Create new version with file RESPONSE=$(curl -s --proxy "$PROXY" \ -X POST \ "$API_BASE/addons/$ADDON_ID/versions/" \ -H "Authorization: JWT $JWT" \ -F "upload=@$XPI_FILE" \ -F "version=$VERSION" \ -F "channel=$CHANNEL") fi echo " Response: $RESPONSE" | head -5 # Step 5: Check status echo "==> Checking upload status..." VERSION_ID=$(echo "$RESPONSE" | node -e " const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(d.id || d.version || 'unknown'); " 2>/dev/null || echo "unknown") echo " Version ID: $VERSION_ID" echo "" echo "=== Done ===" echo "Check status at: https://addons.mozilla.org/en-US/developers/addon/$ADDON_ID/versions/"