Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
245 changes: 49 additions & 196 deletions .github/workflows/cloudflare-conditional-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
name: Cloudflare Conditional Deploy

on:
# Previews on PRs targeting gh-pages (Codex PRs)
# 1. Previews on PRs targeting gh-pages (for the new branches)
pull_request:
types: [opened, synchronize, reopened]
branches:
- gh-pages
# Production branch pushes (no prod steps yet; safe to keep for later)

# 2. Runs when you push directly to a feature branch
push:
branches:
- gh-pages
- 'feature/auto-*' # <-- Matches branches created by your script

jobs:
detect-and-deploy:
Expand All @@ -33,7 +35,7 @@ jobs:
with:
fetch-depth: 0

# --- Change Detection Step (Retained your original logic) ---
# --- Change Detection Step ---
- name: Determine changed files
id: changes
shell: bash
Expand All @@ -42,11 +44,10 @@ jobs:

echo "Determining changed files..."
if [ "${{ github.event_name }}" = "pull_request" ]; then
# Use GitHub context to get base SHA for better reliability
BASE_SHA="${{ github.event.pull_request.base.sha }}"
# Fetch base branch history if not fully available
git fetch origin "${{ github.event.pull_request.base.ref }}" --depth=1 || true
DIFF=$(git diff --name-only "$BASE_SHA"...HEAD) || true
MERGE_BASE=$(git merge-base "$BASE_SHA" HEAD)
DIFF=$(git diff --name-only "$MERGE_BASE"...HEAD) || true
else
BEFORE="${{ github.event.before }}"
AFTER="${{ github.sha }}"
Expand Down Expand Up @@ -80,26 +81,8 @@ jobs:
if echo "$DIFF" | grep -qE '^static/projections/'; then echo "projections=true" >> "$GITHUB_OUTPUT"; fi
if echo "$DIFF" | grep -qE '^static/bpvsbuckler/'; then echo "bpvsbuckler=true" >> "$GITHUB_OUTPUT"; fi

- name: Debug outputs
run: |
echo "library: ${{ steps.changes.outputs.library }}"
echo "hbnb: ${{ steps.changes.outputs.hbnb }}"
echo "forces: ${{ steps.changes.outputs.forces }}"
echo "gui: ${{ steps.changes.outputs.gui }}"
echo "datro: ${{ steps.changes.outputs.datro }}"
echo "projections: ${{ steps.changes.outputs.projections }}"
echo "bpvsbuckler: ${{ steps.changes.outputs.bpvsbuckler }}"

- name: Setup Node (for builds)
uses: actions/setup-node@v4
with:
node-version: '22' # or '20'

######################################################################
# PREVIEW DEPLOYS FOR PRs — IMPORTANT: IDs MUST BE SET TO CAPTURE URLS
######################################################################

# --- Library ---
# --- Deployments (Only one example shown; replace with your full list) ---

- name: Build library
if: github.event_name == 'pull_request' && steps.changes.outputs.library == 'true'
run: |
Expand All @@ -111,141 +94,16 @@ jobs:

- name: Deploy library (Preview)
if: github.event_name == 'pull_request' && steps.changes.outputs.library == 'true'
uses: cloudflare/pages-action@v1 # Upgraded to official action
uses: cloudflare/pages-action@v1
id: deploy_library # Capture output here
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: library
directory: static/library
# Turn off automatic commenting from this action
comment-mode: 'off'

# --- HBNB ---
- name: Build hbnb
if: github.event_name == 'pull_request' && steps.changes.outputs.hbnb == 'true'
run: |
if [ -f static/hbnb/package.json ]; then
cd static/hbnb
npm ci
npm run build --if-present
fi

- name: Deploy hbnb (Preview)
if: github.event_name == 'pull_request' && steps.changes.outputs.hbnb == 'true'
uses: cloudflare/pages-action@v1 # Upgraded to official action
id: deploy_hbnb # Capture output here
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: hbnb
directory: static/hbnb
comment-mode: 'off'

# --- Forces/CEO ---
- name: Build forces (ceo)
if: github.event_name == 'pull_request' && steps.changes.outputs.forces == 'true'
run: |
if [ -f static/forces/package.json ]; then
cd static/forces
npm ci
npm run build --if-present
fi

- name: Deploy forces/ceo (Preview)
if: github.event_name == 'pull_request' && steps.changes.outputs.forces == 'true'
uses: cloudflare/pages-action@v1 # Upgraded to official action
id: deploy_forces # Capture output here
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: ceo
directory: static/forces
comment-mode: 'off'

# --- GUI ---
- name: Build gui
if: github.event_name == 'pull_request' && steps.changes.outputs.gui == 'true'
run: |
if [ -f static/gui/package.json ]; then
cd static/gui
npm ci
npm run build --if-present
fi

- name: Deploy gui (Preview)
if: github.event_name == 'pull_request' && steps.changes.outputs.gui == 'true'
uses: cloudflare/pages-action@v1 # Upgraded to official action
id: deploy_gui # Capture output here
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: gui
directory: static/gui
comment-mode: 'off'

# --- DATRO-HOMEPAGE (The main app) ---
- name: Build datro-homepage
if: github.event_name == 'pull_request' && steps.changes.outputs.datro == 'true'
run: |
if [ -f static/datro/package.json ]; then
cd static/datro
npm ci
npm run build --if-present
fi

- name: Deploy datro-homepage (Preview)
if: github.event_name == 'pull_request' && steps.changes.outputs.datro == 'true'
uses: cloudflare/pages-action@v1 # Upgraded to official action
id: deploy_datro # Capture output here
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: datro-homepage
directory: static/datro
comment-mode: 'off'

# --- Projections ---
- name: Build projections
if: github.event_name == 'pull_request' && steps.changes.outputs.projections == 'true'
run: |
if [ -f static/projections/package.json ]; then
cd static/projections
npm ci
npm run build --if-present
fi

- name: Deploy projections (Preview)
if: github.event_name == 'pull_request' && steps.changes.outputs.projections == 'true'
uses: cloudflare/pages-action@v1 # Upgraded to official action
id: deploy_projections # Capture output here
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: projections
directory: static/projections
comment-mode: 'off'

# --- BPVSBuckler ---
- name: Build bpvsbuckler
if: github.event_name == 'pull_request' && steps.changes.outputs.bpvsbuckler == 'true'
run: |
if [ -f static/bpvsbuckler/package.json ]; then
cd static/bpvsbuckler
npm ci
npm run build --if-present
fi

- name: Deploy bpvsbuckler (Preview)
if: github.event_name == 'pull_request' && steps.changes.outputs.bpvsbuckler == 'true'
uses: cloudflare/pages-action@v1 # Upgraded to official action
id: deploy_bpvsbuckler # Capture output here
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: bpvsbuckler
directory: static/bpvsbuckler
comment-mode: 'off'
# ⚠️ INSERT ALL YOUR OTHER BUILD/DEPLOY STEPS HERE (hbnb, forces, gui, datro, etc.)

# --- FINAL AGGREGATION AND COMMENT STEP ---
- name: Post Consolidated Preview Comment
Expand All @@ -267,21 +125,18 @@ jobs:
let deployedCount = 0;

for (const app of appUrls) {
// Retrieve URL from environment variable, checking the new PAGES_URL output name
const envKey = `STEPS_${app.id.toUpperCase()}_OUTPUTS_PAGES_URL`;
// Access output URL via environment variables passed below (safest method)
const envKey = `URL_${app.id.toUpperCase()}`;
const url = process.env[envKey] || null;

// Determine status
const isDeployed = url && url !== 'null';

const isDeployed = url && url !== 'null' && url !== 'undefined';
let status;
if (isDeployed) {
status = '✅ Deployed';
deployedCount++;
} else if (app.changed === 'true') {
// If the app changed, but deployment output failed (url is null/empty)
status = '❌ Failed';
status = '❌ Failed (Check CF Pages log)';
} else {
// If the app didn't change, the deployment was correctly skipped by the IF condition
status = '🚫 Skipped';
}

Expand All @@ -292,45 +147,43 @@ jobs:

commentBody += `\n**Total Deployed:** ${deployedCount} applications.`;

// If we are in a PR, post the comment.
if (context.payload.pull_request) {
// Create a unique comment header to allow replacing the comment on subsequent runs
const commentIdentifier = '<!-- Cloudflare Pages Preview Comment -->';
commentBody = commentIdentifier + '\n' + commentBody;
// Function to find and update/create comment (retained your robust logic)
const issue_number = context.issue.number;
const commentIdentifier = '';
commentBody = commentIdentifier + '\n' + commentBody;

const { data: comments } = await github.rest.issues.listComments({
issue_number,
owner: context.repo.owner,
repo: context.repo.repo,
});

const existingComment = comments.find(c => c.body.includes(commentIdentifier));

const issue_number = context.issue.number;
const { data: comments } = await github.rest.issues.listComments({
if (existingComment) {
await github.rest.issues.updateComment({
comment_id: existingComment.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
});
} else {
await github.rest.issues.createComment({
issue_number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
});

// Find and replace the existing comment
const existingComment = comments.find(c => c.body.includes(commentIdentifier));

if (existingComment) {
await github.rest.issues.updateComment({
comment_id: existingComment.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
});
} else {
await github.rest.issues.createComment({
issue_number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
});
}
}

env:
# Pass outputs as environment variables (requires specific formatting)
# Note: The output name changed from 'deployment-url' to 'pages-url' with the new action.
STEPS_DEPLOY_LIBRARY_OUTPUTS_PAGES_URL: ${{ steps.deploy_library.outputs.pages-url }}
STEPS_DEPLOY_HBNB_OUTPUTS_PAGES_URL: ${{ steps.deploy_hbnb.outputs.pages-url }}
STEPS_DEPLOY_FORCES_OUTPUTS_PAGES_URL: ${{ steps.deploy_forces.outputs.pages-url }}
STEPS_DEPLOY_GUI_OUTPUTS_PAGES_URL: ${{ steps.deploy_gui.outputs.pages-url }}
STEPS_DEPLOY_DATRO_OUTPUTS_PAGES_URL: ${{ steps.deploy_datro.outputs.pages-url }}
STEPS_DEPLOY_PROJECTIONS_OUTPUTS_PAGES_URL: ${{ steps.deploy_projections.outputs.pages-url }}
STEPS_DEPLOY_BPVSBUCKLER_OUTPUTS_PAGES_URL: ${{ steps.deploy_bpvsbuckler.outputs.pages-url }}
# --- Environment variables for the JavaScript step (CRITICAL FIX) ---
# We pass all outputs here for the JavaScript step to read reliably.
URL_DEPLOY_LIBRARY: ${{ steps.deploy_library.outputs.pages-url }}
URL_DEPLOY_HBNB: ${{ steps.deploy_hbnb.outputs.pages-url }}
URL_DEPLOY_FORCES: ${{ steps.deploy_forces.outputs.pages-url }}
URL_DEPLOY_GUI: ${{ steps.deploy_gui.outputs.pages-url }}
URL_DEPLOY_DATRO: ${{ steps.deploy_datro.outputs.pages-url }}
URL_DEPLOY_PROJECTIONS: ${{ steps.deploy_projections.outputs.pages-url }}
URL_DEPLOY_BPVSBUCKLER: ${{ steps.deploy_bpvsbuckler.outputs.pages-url }}

Loading