Add Netlify deploy workflow and unify edge handler
Introduces a new GitHub Actions workflow for deploying to Netlify, updates the Vercel workflow name, and refactors the edge function handler to support both Netlify and Vercel platforms with runtime detection. Adds Netlify-specific configuration and redirect files to enable shared handler logic, reducing code duplication and simplifying multi-platform deployments.
This commit is contained in:
1 parent
18ec41125f
commit
0e7aad4755
3 files changed
+110
-33
No files matched your search
@@ -0,0 +1,41 @@
|
||||
name: Deploy to Netlify
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Sync to Pages and Functions"]
|
||||
types:
|
||||
- completed
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout functions branch
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: functions
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "npm"
|
||||
|
||||
- name: Install Netlify CLI
|
||||
run: npm install --global netlify-cli@latest
|
||||
|
||||
- name: Deploy to Netlify
|
||||
run: netlify deploy --prod --dir=. --auth=${{ secrets.NETLIFY_AUTH_TOKEN }} --site=${{ secrets.NETLIFY_SITE_ID }}
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Deploy to Vercel Functions
|
||||
name: Deploy to Vercel
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
|
||||
+68
-32
@@ -212,7 +212,7 @@ jobs:
|
||||
cp package-lock.json /tmp/functions-conversion/ 2>/dev/null || true
|
||||
cp LICENSE /tmp/functions-conversion/
|
||||
|
||||
- name: Create Vercel Edge Function handler
|
||||
- name: Create Edge Function handler
|
||||
run: |
|
||||
mkdir -p /tmp/functions-conversion/api
|
||||
cat > /tmp/functions-conversion/api/index.js << 'EOF'
|
||||
@@ -237,51 +237,56 @@ jobs:
|
||||
import { handleRequest } from '../src/index.js';
|
||||
|
||||
/**
|
||||
* Vercel Edge Function handler for all routes.
|
||||
* Edge Function handler.
|
||||
*
|
||||
* This adapter enables Xget to run on Vercel's Edge Runtime by mapping
|
||||
* Vercel's environment model to Cloudflare Workers' expected format.
|
||||
*
|
||||
* The Vercel Edge Runtime uses standard Web APIs (Request, Response, fetch),
|
||||
* making it compatible with the existing Cloudflare Workers code.
|
||||
*
|
||||
* @param {Request} request - Standard Web API Request
|
||||
* @param {Request} request - Standard Web API Request object
|
||||
* @param {Object} [context] - Platform-specific context (Netlify only)
|
||||
* @param {Object} [context.geo] - Geolocation data (Netlify)
|
||||
* @param {string} [context.ip] - Client IP address (Netlify)
|
||||
* @param {Object} [context.env] - Environment variables (Netlify)
|
||||
* @param {Function} [context.waitUntil] - Background task extension (Netlify)
|
||||
* @returns {Promise<Response>} Standard Web API Response
|
||||
*
|
||||
* @example
|
||||
* // This is called automatically by Vercel Edge Runtime
|
||||
* // Runtime invokes: handler(request)
|
||||
* // Returns: Response with proxied content
|
||||
* // Netlify invokes with context
|
||||
* handler(request, { geo: {...}, ip: '1.2.3.4', env: {...}, waitUntil: fn })
|
||||
*
|
||||
* @example
|
||||
* // Environment variables usage
|
||||
* // Vercel dashboard or vercel.json: TIMEOUT_SECONDS = "60"
|
||||
* // process.env contains: { TIMEOUT_SECONDS: "60" }
|
||||
* // Mapped to env object and passed to handleRequest
|
||||
* // Vercel invokes without context
|
||||
* handler(request)
|
||||
*/
|
||||
export default async function handler(request) {
|
||||
// Map process.env to Cloudflare Workers env format
|
||||
export default async function handler(request, context) {
|
||||
// Detect runtime environment
|
||||
const isNetlify = context && (context.geo !== undefined || context.ip !== undefined);
|
||||
|
||||
// Normalize environment variables
|
||||
const envSource = isNetlify && context.env ? context.env : process.env;
|
||||
const env = {
|
||||
TIMEOUT_SECONDS: process.env.TIMEOUT_SECONDS,
|
||||
MAX_RETRIES: process.env.MAX_RETRIES,
|
||||
RETRY_DELAY_MS: process.env.RETRY_DELAY_MS,
|
||||
CACHE_DURATION: process.env.CACHE_DURATION,
|
||||
ALLOWED_METHODS: process.env.ALLOWED_METHODS,
|
||||
ALLOWED_ORIGINS: process.env.ALLOWED_ORIGINS,
|
||||
MAX_PATH_LENGTH: process.env.MAX_PATH_LENGTH,
|
||||
TIMEOUT_SECONDS: envSource.TIMEOUT_SECONDS,
|
||||
MAX_RETRIES: envSource.MAX_RETRIES,
|
||||
RETRY_DELAY_MS: envSource.RETRY_DELAY_MS,
|
||||
CACHE_DURATION: envSource.CACHE_DURATION,
|
||||
ALLOWED_METHODS: envSource.ALLOWED_METHODS,
|
||||
ALLOWED_ORIGINS: envSource.ALLOWED_ORIGINS,
|
||||
MAX_PATH_LENGTH: envSource.MAX_PATH_LENGTH,
|
||||
};
|
||||
|
||||
// Create minimal execution context
|
||||
// Note: Vercel Edge Runtime doesn't support waitUntil or passThroughOnException
|
||||
// Create normalized execution context
|
||||
const ctx = {
|
||||
waitUntil: (promise) => {
|
||||
// No-op: Vercel doesn't support background tasks
|
||||
waitUntil: isNetlify && context.waitUntil
|
||||
? (promise) => context.waitUntil(promise)
|
||||
: (promise) => {
|
||||
// No-op on Vercel: background tasks not supported
|
||||
// Cache writes will run synchronously instead
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.warn('waitUntil is not supported in Vercel Edge Runtime');
|
||||
}
|
||||
},
|
||||
passThroughOnException: () => {
|
||||
// No-op: Vercel-specific error handling
|
||||
console.warn('passThroughOnException is not supported in Vercel Edge Runtime');
|
||||
// Not supported on either platform in this context
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.warn('passThroughOnException is not universally supported');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -289,7 +294,7 @@ jobs:
|
||||
return handleRequest(request, env, ctx);
|
||||
}
|
||||
|
||||
// Vercel Edge Runtime configuration
|
||||
// Vercel Edge Runtime configuration (ignored by Netlify)
|
||||
export const config = {
|
||||
runtime: 'edge',
|
||||
};
|
||||
@@ -323,6 +328,37 @@ jobs:
|
||||
}
|
||||
EOF
|
||||
|
||||
- name: Create netlify.toml
|
||||
run: |
|
||||
cd /tmp/functions-conversion
|
||||
cat > netlify.toml << 'EOF'
|
||||
[[edge_functions]]
|
||||
function = "edge-handler"
|
||||
path = "/*"
|
||||
|
||||
[build]
|
||||
publish = "."
|
||||
EOF
|
||||
|
||||
- name: Create Netlify Edge Function redirect
|
||||
run: |
|
||||
cd /tmp/functions-conversion
|
||||
mkdir -p netlify/edge-functions
|
||||
cat > netlify/edge-functions/edge-handler.js << 'EOF'
|
||||
/**
|
||||
* Netlify Edge Function entry point.
|
||||
*
|
||||
* This file serves as a redirect to the edge function handler
|
||||
* located at /api/index.js. Both Netlify and Vercel can use the same
|
||||
* handler code, with platform detection handling the differences.
|
||||
*
|
||||
* Netlify requires edge functions to be in netlify/edge-functions/,
|
||||
* while Vercel uses /api/ directory. This approach maintains a single
|
||||
* source of truth at /api/index.js.
|
||||
*/
|
||||
export { default, config } from '../../api/index.js';
|
||||
EOF
|
||||
|
||||
- name: Export handleRequest from src/index.js
|
||||
run: |
|
||||
cd /tmp/functions-conversion
|
||||
|
||||
Reference in new issue
Block a user