Skip to content

fixed base host

fixed base host #17

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: |
if [ ! -f "dist/widget-${{ steps.get_version.outputs.version }}.js" ]; then
echo "Error: Versioned file not found"
exit 1
fi
if [ ! -f "dist/widget.js" ]; then
echo "Error: Latest file not found"
exit 1
fi
echo "Build verification passed"
- 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 }}.css
dist/widget.js
dist/widget.css
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
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 "✅ 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
# 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 "✅ 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}.css\",
\"https://${CUSTOM_DOMAIN}/widget.js\",
\"https://${CUSTOM_DOMAIN}/widget.css\"
]
}"
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }}
- name: Build Summary
run: |
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Version:** ${{ steps.get_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Files Built:**" >> $GITHUB_STEP_SUMMARY
echo " - widget-${{ steps.get_version.outputs.version }}.js" >> $GITHUB_STEP_SUMMARY
echo " - widget-${{ steps.get_version.outputs.version }}.css" >> $GITHUB_STEP_SUMMARY
echo " - widget.js (latest)" >> $GITHUB_STEP_SUMMARY
echo " - widget.css (latest)" >> $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