diff --git a/.github/workflows/cloudflare-conditional-deploy.yml b/.github/workflows/cloudflare-conditional-deploy.yml index bb0c30557..8bff74bb5 100644 --- a/.github/workflows/cloudflare-conditional-deploy.yml +++ b/.github/workflows/cloudflare-conditional-deploy.yml @@ -1,4 +1,4 @@ -name: Cloudflare conditional deploy (wrangler + deployments box, no comments) +name: Cloudflare conditional deploy on: # Previews on PRs targeting gh-pages (Codex PRs) @@ -6,32 +6,27 @@ on: types: [opened, synchronize, reopened] branches: - gh-pages - # Keep pushes to gh-pages enabled (you can add prod steps later) + # Production branch pushes (no prod steps yet; safe to keep for later) push: branches: - gh-pages jobs: - deploy: + detect-and-deploy: name: Detect changes and deploy only touched apps runs-on: ubuntu-latest - # Needed for GitHub Deployments box + # Create PR comments + GitHub Deployments permissions: contents: read deployments: write pull-requests: write - # Auto-cancel older runs for same PR/branch + # Auto-cancel older runs for the same PR/branch concurrency: - group: cf-wrangler-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + group: cf-pages-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true - env: - # Convenient refs - BRANCH_NAME: ${{ github.head_ref || github.ref_name }} - COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - steps: - name: Checkout uses: actions/checkout@v4 @@ -62,6 +57,7 @@ jobs: echo "Changed files:" echo "$DIFF" + # default outputs (false) { echo "library=false" echo "hbnb=false" @@ -72,427 +68,189 @@ jobs: echo "bpvsbuckler=false" } >> "$GITHUB_OUTPUT" - if echo "$DIFF" | grep -qE '^static/library/'; then echo "library=true" >> "$GITHUB_OUTPUT"; fi - if echo "$DIFF" | grep -qE '^static/hbnb/'; then echo "hbnb=true" >> "$GITHUB_OUTPUT"; fi - if echo "$DIFF" | grep -qE '^static/forces/'; then echo "forces=true" >> "$GITHUB_OUTPUT"; fi - if echo "$DIFF" | grep -qE '^static/gui/'; then echo "gui=true" >> "$GITHUB_OUTPUT"; fi - if echo "$DIFF" | grep -qE '^static/datro/'; then echo "datro=true" >> "$GITHUB_OUTPUT"; fi + # detect changes in each app directory + if echo "$DIFF" | grep -qE '^static/library/'; then echo "library=true" >> "$GITHUB_OUTPUT"; fi + if echo "$DIFF" | grep -qE '^static/hbnb/'; then echo "hbnb=true" >> "$GITHUB_OUTPUT"; fi + if echo "$DIFF" | grep -qE '^static/forces/'; then echo "forces=true" >> "$GITHUB_OUTPUT"; fi + if echo "$DIFF" | grep -qE '^static/gui/'; then echo "gui=true" >> "$GITHUB_OUTPUT"; fi + if echo "$DIFF" | grep -qE '^static/datro/'; then echo "datro=true" >> "$GITHUB_OUTPUT"; fi 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: Setup Node + - 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' - - - name: Install Wrangler - run: npm i -g wrangler@^4.47.0 + node-version: '22' # or '20' ###################################################################### - # Each app: wrangler pages deploy + GitHub Deployment box - # Requires repo secrets: - # CLOUDFLARE_API_TOKEN + # PREVIEW DEPLOYS FOR PRs — posts a comment with the preview URL(s) + # Uses andykenward/github-actions-cloudflare-pages to create GH Deployments + # Repo Secrets required: + # CLOUDFLARE_API_TOKEN (Account:Read + Pages:Builds:Edit) # CLOUDFLARE_ACCOUNT_ID # - # PROJECT_NAME must match your Cloudflare Pages project names: - # library, hbnb, ceo, gui, datro-homepage, projections, bpvsbuckler - # - # GitHub Environments already created: + # IMPORTANT: `cloudflare-project-name` must match CF Pages project names. + # IMPORTANT: `github-environment` must match your GitHub Environments: # library(preview), hbnb(preview), ceo(preview), gui(preview), # datro(preview), projections(preview), bpvsbuckler(preview) ###################################################################### - # ---------- library ---------- - - name: Deploy library (preview) - id: deploy_library + - name: Build library if: github.event_name == 'pull_request' && steps.changes.outputs.library == 'true' - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: library - DIRECTORY: static/library - BRANCH_NAME: ${{ env.BRANCH_NAME }} - COMMIT_SHA: ${{ env.COMMIT_SHA }} - shell: bash run: | - set -euo pipefail - if [ -f "$DIRECTORY/package.json" ]; then - (cd "$DIRECTORY" && (npm ci || npm install) && npm run build --if-present) - fi - OUT=$(wrangler pages deploy "$DIRECTORY" \ - --project-name="$PROJECT_NAME" \ - --branch="$BRANCH_NAME" \ - --commit-dirty=true \ - --commit-hash="$COMMIT_SHA" 2>&1 | tee /tmp/wrangler_library.log || true) - echo "$OUT" - URL=$(echo "$OUT" | grep -Eo 'https://[a-zA-Z0-9.-]+\.pages\.dev[[:alnum:]/._-]*' | tail -n1 || true) - if [ -z "${URL:-}" ]; then - echo "No preview URL detected in wrangler output" - exit 1 + if [ -f static/library/package.json ]; then + cd static/library + npm ci + npm run build --if-present fi - echo "url=$URL" >> "$GITHUB_OUTPUT" - - name: Deployment box: library(preview) + - name: Deploy library (Preview) and comment URL if: github.event_name == 'pull_request' && steps.changes.outputs.library == 'true' - uses: actions/github-script@v7 + uses: andykenward/github-actions-cloudflare-pages@v3.1.0 + id: deploy_library with: - script: | - const ref = context.payload.pull_request?.head.sha || context.sha; - const env = "library(preview)"; - const url = "${{ steps.deploy_library.outputs.url }}"; - const { data: dep } = await github.rest.repos.createDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - ref, - environment: env, - transient_environment: true, - auto_merge: false, - required_contexts: [], - description: "Cloudflare Pages preview" - }); - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: dep.id, - state: "success", - environment: env, - environment_url: url, - log_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, - auto_inactive: false - }); + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-project-name: library + directory: static/library + github-token: ${{ secrets.GITHUB_TOKEN }} + github-environment: library(preview) - # ---------- hbnb ---------- - - name: Deploy hbnb (preview) - id: deploy_hbnb + - name: Build hbnb if: github.event_name == 'pull_request' && steps.changes.outputs.hbnb == 'true' - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: hbnb - DIRECTORY: static/hbnb - BRANCH_NAME: ${{ env.BRANCH_NAME }} - COMMIT_SHA: ${{ env.COMMIT_SHA }} - shell: bash run: | - set -euo pipefail - if [ -f "$DIRECTORY/package.json" ]; then - (cd "$DIRECTORY" && (npm ci || npm install) && npm run build --if-present) + if [ -f static/hbnb/package.json ]; then + cd static/hbnb + npm ci + npm run build --if-present fi - OUT=$(wrangler pages deploy "$DIRECTORY" \ - --project-name="$PROJECT_NAME" \ - --branch="$BRANCH_NAME" \ - --commit-dirty=true \ - --commit-hash="$COMMIT_SHA" 2>&1 | tee /tmp/wrangler_hbnb.log || true) - echo "$OUT" - URL=$(echo "$OUT" | grep -Eo 'https://[a-zA-Z0-9.-]+\.pages\.dev[[:alnum:]/._-]*' | tail -n1 || true) - if [ -z "${URL:-}" ]; then echo "No preview URL found"; exit 1; fi - echo "url=$URL" >> "$GITHUB_OUTPUT" - - name: Deployment box: hbnb(preview) + - name: Deploy hbnb (Preview) and comment URL if: github.event_name == 'pull_request' && steps.changes.outputs.hbnb == 'true' - uses: actions/github-script@v7 + uses: andykenward/github-actions-cloudflare-pages@v3.1.0 + id: deploy_hbnb with: - script: | - const ref = context.payload.pull_request?.head.sha || context.sha; - const env = "hbnb(preview)"; - const url = "${{ steps.deploy_hbnb.outputs.url }}"; - const { data: dep } = await github.rest.repos.createDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - ref, - environment: env, - transient_environment: true, - auto_merge: false, - required_contexts: [], - description: "Cloudflare Pages preview" - }); - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: dep.id, - state: "success", - environment: env, - environment_url: url, - log_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, - auto_inactive: false - }); + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-project-name: hbnb + directory: static/hbnb + github-token: ${{ secrets.GITHUB_TOKEN }} + github-environment: hbnb(preview) - # ---------- forces (ceo) ---------- - - name: Deploy forces/ceo (preview) - id: deploy_forces + - name: Build forces (ceo) if: github.event_name == 'pull_request' && steps.changes.outputs.forces == 'true' - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: ceo - DIRECTORY: static/forces - BRANCH_NAME: ${{ env.BRANCH_NAME }} - COMMIT_SHA: ${{ env.COMMIT_SHA }} - shell: bash run: | - set -euo pipefail - if [ -f "$DIRECTORY/package.json" ]; then - (cd "$DIRECTORY" && (npm ci || npm install) && npm run build --if-present) + if [ -f static/forces/package.json ]; then + cd static/forces + npm ci + npm run build --if-present fi - OUT=$(wrangler pages deploy "$DIRECTORY" \ - --project-name="$PROJECT_NAME" \ - --branch="$BRANCH_NAME" \ - --commit-dirty=true \ - --commit-hash="$COMMIT_SHA" 2>&1 | tee /tmp/wrangler_forces.log || true) - echo "$OUT" - URL=$(echo "$OUT" | grep -Eo 'https://[a-zA-Z0-9.-]+\.pages\.dev[[:alnum:]/._-]*' | tail -n1 || true) - if [ -z "${URL:-}" ]; then echo "No preview URL found"; exit 1; fi - echo "url=$URL" >> "$GITHUB_OUTPUT" - - name: Deployment box: ceo(preview) + - name: Deploy forces/ceo (Preview) and comment URL if: github.event_name == 'pull_request' && steps.changes.outputs.forces == 'true' - uses: actions/github-script@v7 + uses: andykenward/github-actions-cloudflare-pages@v3.1.0 + id: deploy_forces with: - script: | - const ref = context.payload.pull_request?.head.sha || context.sha; - const env = "ceo(preview)"; - const url = "${{ steps.deploy_forces.outputs.url }}"; - const { data: dep } = await github.rest.repos.createDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - ref, - environment: env, - transient_environment: true, - auto_merge: false, - required_contexts: [], - description: "Cloudflare Pages preview" - }); - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: dep.id, - state: "success", - environment: env, - environment_url: url, - log_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, - auto_inactive: false - }); + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-project-name: ceo + directory: static/forces + github-token: ${{ secrets.GITHUB_TOKEN }} + github-environment: ceo(preview) - # ---------- gui ---------- - - name: Deploy gui (preview) - id: deploy_gui + - name: Build gui if: github.event_name == 'pull_request' && steps.changes.outputs.gui == 'true' - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: gui - DIRECTORY: static/gui - BRANCH_NAME: ${{ env.BRANCH_NAME }} - COMMIT_SHA: ${{ env.COMMIT_SHA }} - shell: bash run: | - set -euo pipefail - if [ -f "$DIRECTORY/package.json" ]; then - (cd "$DIRECTORY" && (npm ci || npm install) && npm run build --if-present) + if [ -f static/gui/package.json ]; then + cd static/gui + npm ci + npm run build --if-present fi - OUT=$(wrangler pages deploy "$DIRECTORY" \ - --project-name="$PROJECT_NAME" \ - --branch="$BRANCH_NAME" \ - --commit-dirty=true \ - --commit-hash="$COMMIT_SHA" 2>&1 | tee /tmp/wrangler_gui.log || true) - echo "$OUT" - URL=$(echo "$OUT" | grep -Eo 'https://[a-zA-Z0-9.-]+\.pages\.dev[[:alnum:]/._-]*' | tail -n1 || true) - if [ -z "${URL:-}" ]; then echo "No preview URL found"; exit 1; fi - echo "url=$URL" >> "$GITHUB_OUTPUT" - - name: Deployment box: gui(preview) + - name: Deploy gui (Preview) and comment URL if: github.event_name == 'pull_request' && steps.changes.outputs.gui == 'true' - uses: actions/github-script@v7 + uses: andykenward/github-actions-cloudflare-pages@v3.1.0 + id: deploy_gui with: - script: | - const ref = context.payload.pull_request?.head.sha || context.sha; - const env = "gui(preview)"; - const url = "${{ steps.deploy_gui.outputs.url }}"; - const { data: dep } = await github.rest.repos.createDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - ref, - environment: env, - transient_environment: true, - auto_merge: false, - required_contexts: [], - description: "Cloudflare Pages preview" - }); - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: dep.id, - state: "success", - environment: env, - environment_url: url, - log_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, - auto_inactive: false - }); + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-project-name: gui + directory: static/gui + github-token: ${{ secrets.GITHUB_TOKEN }} + github-environment: gui(preview) - # ---------- datro-homepage ---------- - - name: Deploy datro-homepage (preview) - id: deploy_datro + - name: Build datro-homepage if: github.event_name == 'pull_request' && steps.changes.outputs.datro == 'true' - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: datro-homepage - DIRECTORY: static/datro - BRANCH_NAME: ${{ env.BRANCH_NAME }} - COMMIT_SHA: ${{ env.COMMIT_SHA }} - shell: bash run: | - set -euo pipefail - if [ -f "$DIRECTORY/package.json" ]; then - (cd "$DIRECTORY" && (npm ci || npm install) && npm run build --if-present) + if [ -f static/datro/package.json ]; then + cd static/datro + npm ci + npm run build --if-present fi - OUT=$(wrangler pages deploy "$DIRECTORY" \ - --project-name="$PROJECT_NAME" \ - --branch="$BRANCH_NAME" \ - --commit-dirty=true \ - --commit-hash="$COMMIT_SHA" 2>&1 | tee /tmp/wrangler_datro.log || true) - echo "$OUT" - URL=$(echo "$OUT" | grep -Eo 'https://[a-zA-Z0-9.-]+\.pages\.dev[[:alnum:]/._-]*' | tail -n1 || true) - if [ -z "${URL:-}" ]; then echo "No preview URL found"; exit 1; fi - echo "url=$URL" >> "$GITHUB_OUTPUT" - - name: Deployment box: datro(preview) + - name: Deploy datro-homepage (Preview) and comment URL if: github.event_name == 'pull_request' && steps.changes.outputs.datro == 'true' - uses: actions/github-script@v7 + uses: andykenward/github-actions-cloudflare-pages@v3.1.0 + id: deploy_datro with: - script: | - const ref = context.payload.pull_request?.head.sha || context.sha; - const env = "datro(preview)"; - const url = "${{ steps.deploy_datro.outputs.url }}"; - const { data: dep } = await github.rest.repos.createDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - ref, - environment: env, - transient_environment: true, - auto_merge: false, - required_contexts: [], - description: "Cloudflare Pages preview" - }); - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: dep.id, - state: "success", - environment: env, - environment_url: url, - log_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, - auto_inactive: false - }); + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-project-name: datro-homepage + directory: static/datro + github-token: ${{ secrets.GITHUB_TOKEN }} + github-environment: datro(preview) - # ---------- projections ---------- - - name: Deploy projections (preview) - id: deploy_projections + - name: Build projections if: github.event_name == 'pull_request' && steps.changes.outputs.projections == 'true' - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: projections - DIRECTORY: static/projections - BRANCH_NAME: ${{ env.BRANCH_NAME }} - COMMIT_SHA: ${{ env.COMMIT_SHA }} - shell: bash run: | - set -euo pipefail - if [ -f "$DIRECTORY/package.json" ]; then - (cd "$DIRECTORY" && (npm ci || npm install) && npm run build --if-present) + if [ -f static/projections/package.json ]; then + cd static/projections + npm ci + npm run build --if-present fi - OUT=$(wrangler pages deploy "$DIRECTORY" \ - --project-name="$PROJECT_NAME" \ - --branch="$BRANCH_NAME" \ - --commit-dirty=true \ - --commit-hash="$COMMIT_SHA" 2>&1 | tee /tmp/wrangler_projections.log || true) - echo "$OUT" - URL=$(echo "$OUT" | grep -Eo 'https://[a-zA-Z0-9.-]+\.pages\.dev[[:alnum:]/._-]*' | tail -n1 || true) - if [ -z "${URL:-}" ]; then echo "No preview URL found"; exit 1; fi - echo "url=$URL" >> "$GITHUB_OUTPUT" - - name: Deployment box: projections(preview) + - name: Deploy projections (Preview) and comment URL if: github.event_name == 'pull_request' && steps.changes.outputs.projections == 'true' - uses: actions/github-script@v7 + uses: andykenward/github-actions-cloudflare-pages@v3.1.0 + id: deploy_projections with: - script: | - const ref = context.payload.pull_request?.head.sha || context.sha; - const env = "projections(preview)"; - const url = "${{ steps.deploy_projections.outputs.url }}"; - const { data: dep } = await github.rest.repos.createDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - ref, - environment: env, - transient_environment: true, - auto_merge: false, - required_contexts: [], - description: "Cloudflare Pages preview" - }); - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: dep.id, - state: "success", - environment: env, - environment_url: url, - log_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, - auto_inactive: false - }); + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-project-name: projections + directory: static/projections + github-token: ${{ secrets.GITHUB_TOKEN }} + github-environment: projections(preview) - # ---------- bpvsbuckler ---------- - - name: Deploy bpvsbuckler (preview) - id: deploy_bpvsbuckler + - name: Build bpvsbuckler if: github.event_name == 'pull_request' && steps.changes.outputs.bpvsbuckler == 'true' - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: bpvsbuckler - DIRECTORY: static/bpvsbuckler - BRANCH_NAME: ${{ env.BRANCH_NAME }} - COMMIT_SHA: ${{ env.COMMIT_SHA }} - shell: bash run: | - set -euo pipefail - if [ -f "$DIRECTORY/package.json" ]; then - (cd "$DIRECTORY" && (npm ci || npm install) && npm run build --if-present) + if [ -f static/bpvsbuckler/package.json ]; then + cd static/bpvsbuckler + npm ci + npm run build --if-present fi - OUT=$(wrangler pages deploy "$DIRECTORY" \ - --project-name="$PROJECT_NAME" \ - --branch="$BRANCH_NAME" \ - --commit-dirty=true \ - --commit-hash="$COMMIT_SHA" 2>&1 | tee /tmp/wrangler_bpvs.log || true) - echo "$OUT" - URL=$(echo "$OUT" | grep -Eo 'https://[a-zA-Z0-9.-]+\.pages\.dev[[:alnum:]/._-]*' | tail -n1 || true) - if [ -z "${URL:-}" ]; then echo "No preview URL found"; exit 1; fi - echo "url=$URL" >> "$GITHUB_OUTPUT" - - name: Deployment box: bpvsbuckler(preview) + - name: Deploy bpvsbuckler (Preview) and comment URL if: github.event_name == 'pull_request' && steps.changes.outputs.bpvsbuckler == 'true' - uses: actions/github-script@v7 + uses: andykenward/github-actions-cloudflare-pages@v3.1.0 + id: deploy_bpvsbuckler with: - script: | - const ref = context.payload.pull_request?.head.sha || context.sha; - const env = "bpvsbuckler(preview)"; - const url = "${{ steps.deploy_bpvsbuckler.outputs.url }}"; - const { data: dep } = await github.rest.repos.createDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - ref, - environment: env, - transient_environment: true, - auto_merge: false, - required_contexts: [], - description: "Cloudflare Pages preview" - }); - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: dep.id, - state: "success", - environment: env, - environment_url: url, - log_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, - auto_inactive: false - }); + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-project-name: bpvsbuckler + directory: static/bpvsbuckler + github-token: ${{ secrets.GITHUB_TOKEN }} + github-environment: bpvsbuckler(preview) + + - name: Done + run: echo "Conditional deploy workflow finished." diff --git a/static/datro/css/release-controls.css b/static/datro/css/release-controls.css new file mode 100644 index 000000000..37f77ab36 --- /dev/null +++ b/static/datro/css/release-controls.css @@ -0,0 +1,188 @@ +.release-topbar { + margin: 5.5rem auto 1.5rem; + padding: 1rem 1.5rem; + background: linear-gradient(135deg, rgba(30, 30, 80, 0.92), rgba(40, 40, 110, 0.92)); + border-radius: 18px; + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: 0 8px 18px rgba(0, 0, 0, 0.25); + color: #ffffff; + max-width: 100%; +} + +@media (max-width: 768px) { + .release-topbar { + margin-top: 4.75rem; + padding: 0.85rem 1rem; + } +} + +.release-dropdown-wrapper { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0.75rem; + margin-bottom: 0.85rem; +} + +.release-back-button { + display: none; + align-items: center; + justify-content: center; + gap: 0.35rem; + padding: 0.45rem 0.9rem; + border-radius: 999px; + border: 1px solid rgba(255, 255, 255, 0.35); + background: rgba(255, 255, 255, 0.08); + color: #ffffff; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + cursor: pointer; + transition: background 0.2s ease, border-color 0.2s ease; +} + +.release-back-button:hover, +.release-back-button:focus { + background: rgba(255, 255, 255, 0.18); + border-color: rgba(255, 255, 255, 0.55); + outline: none; +} + +.release-back-button.is-visible { + display: inline-flex; +} + +.release-select { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + padding: 0.5rem 2.5rem 0.5rem 1rem; + border-radius: 999px; + border: 1px solid rgba(255, 255, 255, 0.35); + background: rgba(255, 255, 255, 0.12); + color: #ffffff; + font-weight: 600; + letter-spacing: 0.04em; + cursor: pointer; + min-width: 160px; + position: relative; +} + +.release-select option { + color: #222222; +} + +.release-select:focus { + outline: none; + border-color: rgba(255, 255, 255, 0.55); + box-shadow: 0 0 0 2px rgba(102, 204, 255, 0.25); +} + +.release-slider { + display: flex; + align-items: stretch; + gap: 0.75rem; + overflow-x: auto; + padding: 0.35rem 0.25rem 0.2rem; + scroll-behavior: smooth; +} + +.release-slider::-webkit-scrollbar { + height: 6px; +} + +.release-slider::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.08); + border-radius: 999px; +} + +.release-slider::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.35); + border-radius: 999px; +} + +.release-slider { + scrollbar-width: thin; + scrollbar-color: rgba(255, 255, 255, 0.35) rgba(255, 255, 255, 0.08); +} + +.release-item { + display: inline-flex; + align-items: center; + gap: 0.55rem; + padding: 0.55rem 0.85rem 0.55rem 1rem; + border-radius: 999px; + border: 1px solid transparent; + background: rgba(255, 255, 255, 0.12); + color: #ffffff; + text-align: left; + flex: 0 0 auto; + min-width: max-content; + transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; +} + +.release-item.is-active { + background: rgba(255, 255, 255, 0.25); + border-color: rgba(102, 204, 255, 0.5); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); +} + +.release-toggle { + border: none; + background: transparent; + color: inherit; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + cursor: pointer; + white-space: nowrap; + padding: 0; +} + +.release-toggle:focus { + outline: none; + text-decoration: underline; +} + +.release-padlock { + border: 1px solid rgba(255, 255, 255, 0.35); + background: rgba(255, 255, 255, 0.1); + border-radius: 50%; + width: 2.35rem; + height: 2.35rem; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 1.15rem; + color: #ffffff; + cursor: pointer; + transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease; +} + +.release-padlock:hover, +.release-padlock:focus { + background: rgba(255, 255, 255, 0.18); + border-color: rgba(255, 255, 255, 0.55); + outline: none; +} + +.release-padlock.is-unlocked { + border-color: rgba(102, 204, 255, 0.8); + color: #66ccff; + background: rgba(102, 204, 255, 0.15); +} + +@media (max-width: 600px) { + .release-item { + padding: 0.5rem 0.75rem; + } + .release-toggle { + font-size: 0.85rem; + } + .release-padlock { + width: 2rem; + height: 2rem; + font-size: 1rem; + } +} + diff --git a/static/datro/index.html b/static/datro/index.html index d7b9d3ca5..5eff694c5 100644 --- a/static/datro/index.html +++ b/static/datro/index.html @@ -34,7 +34,8 @@ - + + @@ -83,6 +84,7 @@ + - - - + + + @@ -145,7 +147,7 @@