Initial commit from ux_aura_assistant
This commit is contained in:
330
FIXED_cloudflare_build.yml
Normal file
330
FIXED_cloudflare_build.yml
Normal file
@@ -0,0 +1,330 @@
|
||||
name: Cloudflare Worker AI Studio Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
description: 'Branch name'
|
||||
default: 'main'
|
||||
clone_url:
|
||||
description: 'Clone URL of repo'
|
||||
required: true
|
||||
original_url:
|
||||
description: 'Original URL of repo'
|
||||
required: false
|
||||
use_original:
|
||||
description: 'Use original repo URL'
|
||||
default: 'false'
|
||||
concurrency:
|
||||
group: aistudio-build-group
|
||||
cancel: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
container:
|
||||
image: node:20-bullseye
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.event.inputs.branch || 'main' }}
|
||||
CLONE_URL: ${{ github.event.inputs.clone_url }}
|
||||
ORIGINAL_URL: ${{ github.event.inputs.original_url }}
|
||||
USE_ORIGINAL: ${{ github.event.inputs.use_original || 'false' }}
|
||||
GIT_USERNAME: ${{ vars.GIT_USERNAME }}
|
||||
GIT_TOKEN: ${{ vars.GIT_TOKEN }}
|
||||
CLOUDFLARE_API_TOKEN: ${{ github.event.inputs.branch == 'eteam_prod' && secrets.CF_API_TOKEN_ETEAM || secrets.CF_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ github.event.inputs.branch == 'eteam_prod' && vars.CF_ACCOUNT_ID_ETEAM || vars.CF_ACCOUNT_ID }}
|
||||
|
||||
steps:
|
||||
- name: Log input values
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "===== INPUT DETAILS ====="
|
||||
echo "Branch: $BRANCH_NAME"
|
||||
echo "Clone URL: $CLONE_URL"
|
||||
echo "Original URL: ${ORIGINAL_URL:-}"
|
||||
echo "Use Original: $USE_ORIGINAL"
|
||||
echo "========================="
|
||||
|
||||
- name: Install prerequisites (rsync, jq, git)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
echo "[ERROR] git not found in image; cannot proceed without apt. Use an image that includes git."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "[INFO] Installing jq (static binary)..."
|
||||
curl -fsSL -o /usr/local/bin/jq \
|
||||
https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64
|
||||
chmod +x /usr/local/bin/jq
|
||||
fi
|
||||
|
||||
if ! command -v rsync >/dev/null 2>&1; then
|
||||
echo "[WARN] rsync not found; continuing (workflow does not require rsync for core steps)."
|
||||
fi
|
||||
|
||||
jq --version
|
||||
git --version
|
||||
|
||||
- name: Clone repository
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TARGET_URL="$CLONE_URL"
|
||||
if [ "$USE_ORIGINAL" = "true" ] && [ -n "${ORIGINAL_URL:-}" ]; then
|
||||
TARGET_URL="$ORIGINAL_URL"
|
||||
fi
|
||||
AUTH_URL="$(echo "$TARGET_URL" | sed "s#https://#https://$GIT_USERNAME:$GIT_TOKEN@#")"
|
||||
git clone --branch "$BRANCH_NAME" "$AUTH_URL" repo
|
||||
cd repo
|
||||
echo "[INFO] Repository cloned successfully."
|
||||
git remote -v
|
||||
|
||||
- name: Derive canonical repo name from origin and export
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ORIGIN_URL="$(git -C repo remote get-url origin)"
|
||||
DERIVED_REPO_NAME="$(basename "${ORIGIN_URL%.git}")"
|
||||
echo "[DEBUG] Derived repo name from origin: '${DERIVED_REPO_NAME}'"
|
||||
echo "REPO_NAME=${DERIVED_REPO_NAME}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Fetch metadata (slug + unique name) from AI Studio Manager API
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
ORIGIN_URL="$(git -C repo remote get-url origin)"
|
||||
OWNER_REPO="$(echo "$ORIGIN_URL" | awk -F[/:] '{print $(NF-1)"/"$NF}' | sed 's/\.git$//')"
|
||||
ENCODED_REPO_NAME="$(printf '%s' "$OWNER_REPO" | jq -s -R -r @uri)"
|
||||
|
||||
if [[ "$BRANCH_NAME" == "main" ]]; then
|
||||
MANAGER_API_URL="https://www.humanizeiq.ai"
|
||||
elif [[ "$BRANCH_NAME" == "eteam_prod" ]]; then
|
||||
MANAGER_API_URL="https://www.humanizeiq.ai"
|
||||
elif [[ "$BRANCH_NAME" == "dev" ]]; then
|
||||
MANAGER_API_URL="https://www.dev.humanizeiq.ai"
|
||||
else
|
||||
MANAGER_API_URL="https://www.playtest.humanizeiq.ai"
|
||||
fi
|
||||
|
||||
echo "[INFO] Using Manager API URL: $MANAGER_API_URL"
|
||||
echo "[INFO] Querying AI Studio Manager API for repoName=$OWNER_REPO"
|
||||
|
||||
RESPONSE="$(curl -sS -X GET \
|
||||
"${MANAGER_API_URL}/api/ai_studio_manager_api/app-builder/components/by-repo?repoName=${ENCODED_REPO_NAME}" \
|
||||
-H 'accept: application/json' \
|
||||
-H 'X-API-Key: system-key' || true)"
|
||||
|
||||
echo "[DEBUG] API response: ${RESPONSE:-<empty>}"
|
||||
|
||||
SLUG="$(echo "${RESPONSE:-}" | jq -r '.additional_info.slug' 2>/dev/null || echo "")"
|
||||
UNIQUE_APP_CODE="$(echo "${RESPONSE:-}" | jq -r '.additional_info.unique_app_code' 2>/dev/null || echo "")"
|
||||
|
||||
if [ -z "${SLUG:-}" ] || [ "${SLUG:-}" = "null" ]; then
|
||||
echo "[WARN] slug missing; falling back to REPO_NAME#gais_."
|
||||
BASE_NAME_VALUE="${REPO_NAME#gais_}"
|
||||
else
|
||||
BASE_NAME_VALUE="$SLUG"
|
||||
fi
|
||||
|
||||
if [ -z "${UNIQUE_APP_CODE:-}" ] || [ "${UNIQUE_APP_CODE:-}" = "null" ]; then
|
||||
echo "[WARN] unique_app_code missing; falling back to REPO_NAME."
|
||||
UNIQUE_NAME_VALUE="${REPO_NAME}"
|
||||
else
|
||||
UNIQUE_NAME_VALUE="${UNIQUE_APP_CODE}"
|
||||
fi
|
||||
|
||||
echo "BASE_NAME=${BASE_NAME_VALUE}" >> "$GITHUB_ENV"
|
||||
echo "UNIQUE_NAME=${UNIQUE_NAME_VALUE}" >> "$GITHUB_ENV"
|
||||
echo "MANAGER_API_URL=${MANAGER_API_URL}" >> "$GITHUB_ENV"
|
||||
|
||||
echo "[INFO] Using BASE_NAME=${BASE_NAME_VALUE}"
|
||||
echo "[INFO] Using UNIQUE_NAME=${UNIQUE_NAME_VALUE} for Worker base"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: repo
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm ci || npm install
|
||||
|
||||
- name: Build AI Studio / Vite project
|
||||
working-directory: repo
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BASE_NAME="${BASE_NAME:-${REPO_NAME#gais_}}"
|
||||
BASE_PATH="/${BASE_NAME}/"
|
||||
printf '[INFO] Using base path: %s\n' "$BASE_PATH"
|
||||
npm run build --if-present -- --base "$BASE_PATH"
|
||||
|
||||
- name: Copy JSON assets into dist
|
||||
working-directory: repo
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cp -v ./metadata.json dist/ || echo "No JSON files found in ./config"
|
||||
|
||||
- name: Install Wrangler CLI
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm install -g wrangler
|
||||
|
||||
- name: Deploy Cloudflare Worker
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ env.BRANCH_NAME == 'eteam_prod' && secrets.CF_API_TOKEN_ETEAM || secrets.CF_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ env.BRANCH_NAME == 'eteam_prod' && vars.CF_ACCOUNT_ID_ETEAM || vars.CF_ACCOUNT_ID }}
|
||||
working-directory: repo
|
||||
run: |
|
||||
set -euo pipefail
|
||||
SAFE_BRANCH="${BRANCH_NAME//\//-}"
|
||||
if [ "$SAFE_BRANCH" = "playtest" ]; then
|
||||
SAFE_BRANCH="pt"
|
||||
fi
|
||||
|
||||
SLUG="${BASE_NAME:-${REPO_NAME#gais_}}"
|
||||
WORKER_NAME="gais_${SLUG}_${SAFE_BRANCH}"
|
||||
|
||||
MAX_LENGTH=54
|
||||
if [ ${#WORKER_NAME} -gt $MAX_LENGTH ]; then
|
||||
echo "[WARN] Worker name '${WORKER_NAME}' is ${#WORKER_NAME} chars (max: ${MAX_LENGTH})"
|
||||
HASH=$(echo -n "$WORKER_NAME" | md5sum | cut -c1-8)
|
||||
MAX_SLUG_LEN=$((39 - ${#SAFE_BRANCH}))
|
||||
TRUNCATED_SLUG="${SLUG:0:$MAX_SLUG_LEN}"
|
||||
WORKER_NAME="gais_${TRUNCATED_SLUG}_${HASH}_${SAFE_BRANCH}"
|
||||
echo "[INFO] Truncated to: ${WORKER_NAME} (${#WORKER_NAME} chars)"
|
||||
fi
|
||||
|
||||
echo "[INFO] Using Worker name: ${WORKER_NAME}"
|
||||
|
||||
echo "[INFO] Writing wrangler.json..."
|
||||
cat > wrangler.json <<'EOF'
|
||||
{
|
||||
"name": "PLACEHOLDER",
|
||||
"compatibility_date": "1970-01-01",
|
||||
"workers_dev": true
|
||||
}
|
||||
EOF
|
||||
|
||||
jq \
|
||||
--arg name "$WORKER_NAME" \
|
||||
--arg date "$(date +%Y-%m-%d)" \
|
||||
'.name=$name | .compatibility_date=$date' \
|
||||
wrangler.json > wrangler.tmp && mv wrangler.tmp wrangler.json
|
||||
|
||||
echo "[INFO] Verifying Wrangler auth..."
|
||||
wrangler whoami
|
||||
|
||||
echo "[INFO] Deploying..."
|
||||
echo "[INFO] CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID}"
|
||||
wrangler deploy --assets ./dist
|
||||
|
||||
- name: Update Route in Traefik Database
|
||||
if: success()
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
SAFE_BRANCH="${BRANCH_NAME//\//-}"
|
||||
if [ "$SAFE_BRANCH" = "playtest" ] || [ "$SAFE_BRANCH" = "pt" ]; then
|
||||
ENVIRONMENT="playtest"
|
||||
elif [ "$SAFE_BRANCH" = "dev" ]; then
|
||||
ENVIRONMENT="nonprod"
|
||||
elif [ "$SAFE_BRANCH" = "main" ]; then
|
||||
ENVIRONMENT="prod"
|
||||
elif [ "$SAFE_BRANCH" = "eteam_prod" ]; then
|
||||
ENVIRONMENT="prod"
|
||||
else
|
||||
echo "[WARN] Unknown branch: $SAFE_BRANCH, defaulting to playtest"
|
||||
ENVIRONMENT="playtest"
|
||||
fi
|
||||
|
||||
echo "[INFO] Updating route for environment: $ENVIRONMENT"
|
||||
|
||||
APP_NAME="${BASE_NAME}"
|
||||
|
||||
echo "[INFO] Calling route update API for app: $APP_NAME using $MANAGER_API_URL"
|
||||
|
||||
ROUTE_RESPONSE="$(curl -sS -X POST \
|
||||
"${MANAGER_API_URL}/api/ai_studio_manager_api/app-builder/create-route" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'X-API-Key: system-key' \
|
||||
-d "{\"appName\":\"${APP_NAME}\",\"environment\":\"${ENVIRONMENT}\"}" || echo '{"status":"error","message":"API call failed"}')"
|
||||
|
||||
echo "[INFO] Route update response: ${ROUTE_RESPONSE}"
|
||||
|
||||
if echo "$ROUTE_RESPONSE" | jq -e '.status == "success"' > /dev/null 2>&1; then
|
||||
ROUTE_URL="$(echo "$ROUTE_RESPONSE" | jq -r '.url')"
|
||||
echo "[INFO] ✓ Route updated successfully: $ROUTE_URL"
|
||||
else
|
||||
ERROR_MSG="$(echo "$ROUTE_RESPONSE" | jq -r '.message // "Unknown error"')"
|
||||
echo "[WARN] Route update may have failed: $ERROR_MSG"
|
||||
echo "[WARN] Continuing workflow - route can be updated manually if needed"
|
||||
fi
|
||||
|
||||
- name: Create PR after successful build (NO MERGE)
|
||||
if: success()
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd repo
|
||||
|
||||
ORIGIN_URL="$(git remote get-url origin)"
|
||||
ORIGIN_URL="${ORIGIN_URL%.git}"
|
||||
REPO_OWNER="$(echo "$ORIGIN_URL" | awk -F'/' '{print $(NF-1)}')"
|
||||
REPO_NAME_ONLY="$(echo "$ORIGIN_URL" | awk -F'/' '{print $NF}')"
|
||||
|
||||
GITEA_API="https://git.code.svchub.com/api/v1"
|
||||
AUTH_HEADER="Authorization: token ${GIT_TOKEN}"
|
||||
CURRENT_BRANCH="${BRANCH_NAME}"
|
||||
|
||||
# Determine PR direction based on current branch
|
||||
if [ "$CURRENT_BRANCH" = "playtest" ]; then
|
||||
FROM_BRANCH="playtest"
|
||||
TO_BRANCH="dev"
|
||||
elif [ "$CURRENT_BRANCH" = "dev" ]; then
|
||||
FROM_BRANCH="dev"
|
||||
TO_BRANCH="main"
|
||||
elif [ "$CURRENT_BRANCH" = "main" ]; then
|
||||
if git ls-remote --exit-code --heads origin eteam_prod >/dev/null 2>&1; then
|
||||
FROM_BRANCH="main"
|
||||
TO_BRANCH="eteam_prod"
|
||||
else
|
||||
echo "[INFO] No PR rule for branch: $CURRENT_BRANCH (eteam_prod does not exist)"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
echo "[INFO] No PR rule for branch: $CURRENT_BRANCH"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Checking if PR already exists: ${FROM_BRANCH} → ${TO_BRANCH}"
|
||||
|
||||
# Check if PR already exists
|
||||
LIST_URL="${GITEA_API}/repos/${REPO_OWNER}/${REPO_NAME_ONLY}/pulls?state=open&base=${TO_BRANCH}&head=${REPO_OWNER}:${FROM_BRANCH}"
|
||||
EXISTING_PR="$(curl -sS -H "$AUTH_HEADER" "$LIST_URL" | jq -r '.[0].number // empty')"
|
||||
|
||||
if [ -n "$EXISTING_PR" ]; then
|
||||
echo "[INFO] PR already exists: #${EXISTING_PR} (${FROM_BRANCH} → ${TO_BRANCH})"
|
||||
echo "[INFO] Skipping PR creation to avoid duplicates"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Creating PR from ${FROM_BRANCH} → ${TO_BRANCH}"
|
||||
PR_PAYLOAD=$(jq -n \
|
||||
--arg title "Auto PR: ${FROM_BRANCH} → ${TO_BRANCH}" \
|
||||
--arg head "$FROM_BRANCH" \
|
||||
--arg base "$TO_BRANCH" \
|
||||
--arg body "Automated PR created after successful build on ${FROM_BRANCH}" \
|
||||
'{title:$title, head:$head, base:$base, body:$body}')
|
||||
|
||||
HTTP_CODE=$(curl -s -o /tmp/resp.json -w "%{http_code}" -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "$AUTH_HEADER" \
|
||||
-d "$PR_PAYLOAD" \
|
||||
"${GITEA_API}/repos/${REPO_OWNER}/${REPO_NAME_ONLY}/pulls" || true)
|
||||
|
||||
if [ "$HTTP_CODE" != "201" ]; then
|
||||
echo "[WARN] PR creation failed or PR already exists (HTTP $HTTP_CODE). Response:"
|
||||
cat /tmp/resp.json || true
|
||||
else
|
||||
PR_NUMBER="$(jq -r '.number' /tmp/resp.json)"
|
||||
echo "[INFO] ✓ PR #${PR_NUMBER} created: ${FROM_BRANCH} → ${TO_BRANCH}"
|
||||
fi
|
||||
Reference in New Issue
Block a user