Skip to content

updated signature code #26

updated signature code

updated signature code #26

Workflow file for this run

name: Build and Release Widget
on:
push:
tags:
- 'v*' # Trigger on version tags (e.g., v1.4.0)
permissions:
contents: write # Required to create GitHub releases
id-token: write # Required for Cloudflare authentication (if using OIDC)
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm install
# Note: Since this project has no dependencies, npm install just creates/updates package-lock.json
- name: Install Wrangler CLI
run: npm install -g wrangler
- name: Verify Wrangler and Cloudflare credentials
run: |
echo "=== Verifying Wrangler Installation ==="
wrangler --version
echo "=== Verifying Cloudflare Credentials ==="
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
echo "❌ CLOUDFLARE_API_TOKEN is not set"
exit 1
fi
if [ -z "$CLOUDFLARE_ACCOUNT_ID" ]; then
echo "❌ CLOUDFLARE_ACCOUNT_ID is not set"
exit 1
fi
if [ -z "$CLOUDFLARE_R2_BUCKET_NAME" ]; then
echo "❌ CLOUDFLARE_R2_BUCKET_NAME is not set"
exit 1
fi
echo "✅ All required secrets are set"
echo "Account ID: $CLOUDFLARE_ACCOUNT_ID"
echo "Bucket: $CLOUDFLARE_R2_BUCKET_NAME"
# Note: Authentication will be tested during the actual upload
# If credentials are wrong, the upload step will fail with a clear error
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_R2_BUCKET_NAME: ${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}
- name: Extract version from tag
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version extracted: $VERSION"
- name: Build widget
run: |
echo "Building widget from Git tag..."
npm run build:tag
echo "Build completed. Files in dist/:"
ls -lh dist/ || echo "dist/ directory not found"
- name: Verify build output
run: |
VERSION="${{ steps.get_version.outputs.version }}"
echo "=== Checking widget files ==="
for file in \
"dist/widget-${VERSION}.js" \
"dist/widget-${VERSION}.min.js" \
"dist/widget-${VERSION}.css" \
"dist/widget-${VERSION}.min.css" \
"dist/widget.js" \
"dist/widget.min.js" \
"dist/widget.css" \
"dist/widget.min.css"
do
if [ ! -f "$file" ]; then
echo "❌ Error: $file not found"
exit 1
fi
echo "✓ $file"
done
echo ""
echo "=== Checking ezform files ==="
for file in \
"dist/ezform-${VERSION}.js" \
"dist/ezform-${VERSION}.min.js" \
"dist/ezform.js" \
"dist/ezform.min.js"
do
if [ ! -f "$file" ]; then
echo "❌ Error: $file not found"
exit 1
fi
echo "✓ $file"
done
echo ""
echo "✅ Build verification passed"
echo ""
echo "=== File sizes ==="
ls -lh dist/
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
dist/widget-${{ steps.get_version.outputs.version }}.js
dist/widget-${{ steps.get_version.outputs.version }}.min.js
dist/widget-${{ steps.get_version.outputs.version }}.css
dist/widget-${{ steps.get_version.outputs.version }}.min.css
dist/widget.js
dist/widget.min.js
dist/widget.css
dist/widget.min.css
dist/ezform-${{ steps.get_version.outputs.version }}.js
dist/ezform-${{ steps.get_version.outputs.version }}.min.js
dist/ezform.js
dist/ezform.min.js
draft: false
prerelease: false
generate_release_notes: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to Cloudflare R2 (Versioned Files)
run: |
set -e # Exit on error
VERSION="${{ steps.get_version.outputs.version }}"
BUCKET="${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}"
echo "=== Upload Configuration ==="
echo "Version: $VERSION"
echo "Bucket: $BUCKET"
echo "Account ID: $CLOUDFLARE_ACCOUNT_ID"
echo "API Token: ${CLOUDFLARE_API_TOKEN:0:10}..." # Show first 10 chars only
if [ -z "$BUCKET" ]; then
echo "❌ Error: CLOUDFLARE_R2_BUCKET_NAME secret is not set"
exit 1
fi
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
echo "❌ Error: CLOUDFLARE_API_TOKEN secret is not set"
exit 1
fi
if [ -z "$CLOUDFLARE_ACCOUNT_ID" ]; then
echo "❌ Error: CLOUDFLARE_ACCOUNT_ID secret is not set"
exit 1
fi
# Verify files exist before uploading
if [ ! -f "dist/widget-${VERSION}.js" ]; then
echo "❌ Error: dist/widget-${VERSION}.js not found"
exit 1
fi
if [ ! -f "dist/widget-${VERSION}.css" ]; then
echo "❌ Error: dist/widget-${VERSION}.css not found"
exit 1
fi
if [ ! -f "dist/ezform-${VERSION}.js" ]; then
echo "❌ Error: dist/ezform-${VERSION}.js not found"
exit 1
fi
if [ ! -f "dist/widget-${VERSION}.min.js" ]; then
echo "❌ Error: dist/widget-${VERSION}.min.js not found"
exit 1
fi
if [ ! -f "dist/ezform-${VERSION}.min.js" ]; then
echo "❌ Error: dist/ezform-${VERSION}.min.js not found"
exit 1
fi
echo "=== Uploading versioned files ==="
# Upload versioned files with cache headers (--remote flag required!)
echo "Uploading widget-${VERSION}.js..."
wrangler r2 object put ${BUCKET}/widget-${VERSION}.js \
--file=dist/widget-${VERSION}.js \
--content-type="application/javascript" \
--cache-control="public, max-age=31536000, immutable" \
--remote || {
echo "❌ Failed to upload widget-${VERSION}.js"
exit 1
}
echo "Uploading widget-${VERSION}.css..."
wrangler r2 object put ${BUCKET}/widget-${VERSION}.css \
--file=dist/widget-${VERSION}.css \
--content-type="text/css" \
--cache-control="public, max-age=31536000, immutable" \
--remote || {
echo "❌ Failed to upload widget-${VERSION}.css"
exit 1
}
echo "Uploading ezform-${VERSION}.js..."
wrangler r2 object put ${BUCKET}/ezform-${VERSION}.js \
--file=dist/ezform-${VERSION}.js \
--content-type="application/javascript" \
--cache-control="public, max-age=31536000, immutable" \
--remote || {
echo "❌ Failed to upload ezform-${VERSION}.js"
exit 1
}
# Upload minified versioned files
echo "Uploading widget-${VERSION}.min.js..."
wrangler r2 object put ${BUCKET}/widget-${VERSION}.min.js \
--file=dist/widget-${VERSION}.min.js \
--content-type="application/javascript" \
--cache-control="public, max-age=31536000, immutable" \
--remote || {
echo "❌ Failed to upload widget-${VERSION}.min.js"
exit 1
}
echo "Uploading widget-${VERSION}.min.css..."
wrangler r2 object put ${BUCKET}/widget-${VERSION}.min.css \
--file=dist/widget-${VERSION}.min.css \
--content-type="text/css" \
--cache-control="public, max-age=31536000, immutable" \
--remote || {
echo "❌ Failed to upload widget-${VERSION}.min.css"
exit 1
}
echo "Uploading ezform-${VERSION}.min.js..."
wrangler r2 object put ${BUCKET}/ezform-${VERSION}.min.js \
--file=dist/ezform-${VERSION}.min.js \
--content-type="application/javascript" \
--cache-control="public, max-age=31536000, immutable" \
--remote || {
echo "❌ Failed to upload ezform-${VERSION}.min.js"
exit 1
}
echo "✅ Uploaded versioned files for v${VERSION}"
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- name: Upload to Cloudflare R2 (Latest Files)
run: |
set -e # Exit on error
BUCKET="${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}"
echo "=== Uploading latest files ==="
if [ -z "$BUCKET" ]; then
echo "❌ Error: CLOUDFLARE_R2_BUCKET_NAME secret is not set"
exit 1
fi
# Verify files exist before uploading
if [ ! -f "dist/widget.js" ]; then
echo "❌ Error: dist/widget.js not found"
exit 1
fi
if [ ! -f "dist/widget.css" ]; then
echo "❌ Error: dist/widget.css not found"
exit 1
fi
if [ ! -f "dist/ezform.js" ]; then
echo "❌ Error: dist/ezform.js not found"
exit 1
fi
if [ ! -f "dist/widget.min.js" ]; then
echo "❌ Error: dist/widget.min.js not found"
exit 1
fi
if [ ! -f "dist/ezform.min.js" ]; then
echo "❌ Error: dist/ezform.min.js not found"
exit 1
fi
# Upload latest files with shorter cache (--remote flag required!)
echo "Uploading widget.js..."
wrangler r2 object put ${BUCKET}/widget.js \
--file=dist/widget.js \
--content-type="application/javascript" \
--cache-control="public, max-age=3600" \
--remote || {
echo "❌ Failed to upload widget.js"
exit 1
}
echo "Uploading widget.css..."
wrangler r2 object put ${BUCKET}/widget.css \
--file=dist/widget.css \
--content-type="text/css" \
--cache-control="public, max-age=3600" \
--remote || {
echo "❌ Failed to upload widget.css"
exit 1
}
echo "Uploading ezform.js..."
wrangler r2 object put ${BUCKET}/ezform.js \
--file=dist/ezform.js \
--content-type="application/javascript" \
--cache-control="public, max-age=3600" \
--remote || {
echo "❌ Failed to upload ezform.js"
exit 1
}
# Upload minified latest files
echo "Uploading widget.min.js..."
wrangler r2 object put ${BUCKET}/widget.min.js \
--file=dist/widget.min.js \
--content-type="application/javascript" \
--cache-control="public, max-age=3600" \
--remote || {
echo "❌ Failed to upload widget.min.js"
exit 1
}
echo "Uploading widget.min.css..."
wrangler r2 object put ${BUCKET}/widget.min.css \
--file=dist/widget.min.css \
--content-type="text/css" \
--cache-control="public, max-age=3600" \
--remote || {
echo "❌ Failed to upload widget.min.css"
exit 1
}
echo "Uploading ezform.min.js..."
wrangler r2 object put ${BUCKET}/ezform.min.js \
--file=dist/ezform.min.js \
--content-type="application/javascript" \
--cache-control="public, max-age=3600" \
--remote || {
echo "❌ Failed to upload ezform.min.js"
exit 1
}
echo "✅ Uploaded latest files"
# Note: Verification skipped - upload success is confirmed by "Upload complete" message
# Files may take a moment to propagate, but upload was successful
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- name: Purge Cloudflare Cache
if: env.CLOUDFLARE_ZONE_ID != ''
run: |
VERSION="${{ steps.get_version.outputs.version }}"
ZONE_ID="${{ secrets.CLOUDFLARE_ZONE_ID }}"
CUSTOM_DOMAIN="${{ secrets.CLOUDFLARE_CUSTOM_DOMAIN || 'cdn.ezcontactform.com' }}"
curl -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type: application/json" \
--data "{
\"files\": [
\"https://${CUSTOM_DOMAIN}/widget-${VERSION}.js\",
\"https://${CUSTOM_DOMAIN}/widget-${VERSION}.min.js\",
\"https://${CUSTOM_DOMAIN}/widget-${VERSION}.css\",
\"https://${CUSTOM_DOMAIN}/widget-${VERSION}.min.css\",
\"https://${CUSTOM_DOMAIN}/widget.js\",
\"https://${CUSTOM_DOMAIN}/widget.min.js\",
\"https://${CUSTOM_DOMAIN}/widget.css\",
\"https://${CUSTOM_DOMAIN}/widget.min.css\",
\"https://${CUSTOM_DOMAIN}/ezform-${VERSION}.js\",
\"https://${CUSTOM_DOMAIN}/ezform-${VERSION}.min.js\",
\"https://${CUSTOM_DOMAIN}/ezform.js\",
\"https://${CUSTOM_DOMAIN}/ezform.min.js\"
]
}"
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }}
- name: Build Summary
run: |
VERSION="${{ steps.get_version.outputs.version }}"
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Version:** ${VERSION}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Widget Files" >> $GITHUB_STEP_SUMMARY
echo "| File | Size |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| widget-${VERSION}.js | $(du -h dist/widget-${VERSION}.js | cut -f1) |" >> $GITHUB_STEP_SUMMARY
echo "| widget-${VERSION}.min.js | $(du -h dist/widget-${VERSION}.min.js | cut -f1) |" >> $GITHUB_STEP_SUMMARY
echo "| widget-${VERSION}.css | $(du -h dist/widget-${VERSION}.css | cut -f1) |" >> $GITHUB_STEP_SUMMARY
echo "| widget-${VERSION}.min.css | $(du -h dist/widget-${VERSION}.min.css | cut -f1) |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### EZForm Files" >> $GITHUB_STEP_SUMMARY
echo "| File | Size |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| ezform-${VERSION}.js | $(du -h dist/ezform-${VERSION}.js | cut -f1) |" >> $GITHUB_STEP_SUMMARY
echo "| ezform-${VERSION}.min.js | $(du -h dist/ezform-${VERSION}.min.js | cut -f1) |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **R2 Upload:** ✅ Completed" >> $GITHUB_STEP_SUMMARY
if [ -n "${{ secrets.CLOUDFLARE_ZONE_ID }}" ]; then
echo "- **Cache Purge:** ✅ Completed" >> $GITHUB_STEP_SUMMARY
fi