Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d6bdf9e
Add PR preview deployment workflow for frontend PRs
lmcdonough Nov 7, 2025
e902daf
Simplify PR preview workflow and add documentation
lmcdonough Nov 7, 2025
3163ae7
Add PR preview cleanup workflow for frontend
lmcdonough Nov 7, 2025
b953e02
cleaning up workflow_call parameters for cleaning up preview envs.
lmcdonough Nov 7, 2025
66d14b8
Fix PR preview workflow - add secrets inheritance
lmcdonough Nov 7, 2025
793ecff
Update reusable workflows for frontend PR cleanup and deployment to u…
lmcdonough Nov 7, 2025
0700134
Update frontend PR preview workflow - clarify env resolution and add …
lmcdonough Nov 7, 2025
91222f8
Test frontend PR preview workflow - trigger deployment
lmcdonough Nov 7, 2025
0752228
Temporarily use backend PR branch for compose file access
lmcdonough Nov 7, 2025
3d8721c
Merge remote-tracking branch 'origin/main' into 225-feature-create-gi…
lmcdonough Dec 29, 2025
f4df06d
docs: Add CI/CD documentation and update README
lmcdonough Dec 29, 2025
1ba4c2a
docs: Update PR preview documentation for path-based routing
lmcdonough Jan 4, 2026
34aa88f
fix: Prevent multiple extension creation in EditorCacheProvider
lmcdonough Jan 4, 2026
1bd05d8
Merge branch 'main' into 225-feature-create-github-actions-workflows-…
lmcdonough Jan 28, 2026
3319f47
fix(workflows): update backend workflow references to main
lmcdonough Jan 28, 2026
f493a04
fix(workflows): revert to feature branch reference until backend PR m…
lmcdonough Jan 28, 2026
67b21f5
chore: re-trigger PR preview workflow
lmcdonough Jan 30, 2026
3526ee2
fix(ci): remove stale GHCR_PAT to fix PR preview GHCR login
lmcdonough Jan 30, 2026
20b45f8
fix(ci): add backend image pre-check and PAT auth for cross-repo GHCR…
lmcdonough Jan 30, 2026
934a579
fix(workflows): update remediation docs to reference org-level GHCR s…
lmcdonough Jan 30, 2026
30812ba
fix(workflows): update secrets comment to reflect cross-repo resolution
lmcdonough Feb 1, 2026
4fc51b1
fix(workflows): document SSH secret requirements for PR preview
lmcdonough Feb 4, 2026
faed40d
fix(workflows): clarify secret inheritance for cross-repo GHCR access
lmcdonough Feb 4, 2026
7563edf
Merge branch 'main' into 225-feature-create-github-actions-workflows-…
lmcdonough Feb 6, 2026
a470318
docs(workflows): update secrets strategy comment
lmcdonough Feb 6, 2026
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
41 changes: 41 additions & 0 deletions .github/workflows/cleanup-pr-preview-frontend.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# =============================================================================
# Frontend PR Preview Cleanup Overlay Workflow
# =============================================================================
# Purpose: Trigger cleanup when frontend PRs are closed/merged
# Calls: refactor-platform-rs/cleanup-pr-preview.yml (reusable workflow)
# =============================================================================

name: Cleanup PR Preview (Frontend)

on:
pull_request:
# Trigger on PR close (includes merge)
types: [closed]

permissions:
contents: read
packages: write
pull-requests: write

jobs:
# ===========================================================================
# JOB: Call reusable cleanup workflow from backend repo
# ===========================================================================
cleanup-frontend-pr:
name: Cleanup Frontend PR Preview
# Call the reusable workflow from backend repository
# TODO: After backend PR #190 merges, change to @main
uses: refactor-group/refactor-platform-rs/.github/workflows/cleanup-pr-preview.yml@190-add-a-staging-environment-for-previewing-and-testing-ahead-of-a-new-deployment
with:
# This is a frontend PR cleanup
repo_type: 'frontend'
# PR number to cleanup
pr_number: ${{ github.event.pull_request.number }}
# Branch name for image identification
branch_name: ${{ github.head_ref }}
secrets: inherit
# =========================================================================
# NO SECRETS NEEDED!
# =========================================================================
# The reusable workflow uses the backend repo's pr-preview environment
# which contains all necessary secrets for cleanup.
154 changes: 154 additions & 0 deletions .github/workflows/pr-preview-frontend.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# =============================================================================
# Frontend PR Preview Overlay Workflow
# =============================================================================
# Purpose: Trigger PR preview deployments when frontend PRs are opened/updated
# Strategy: Build frontend from PR branch, use main-arm64 backend image
# Secrets: SSH secrets (RPI5_SSH_KEY, RPI5_HOST_KEY) must exist at repo level
# Calls: refactor-platform-rs/ci-deploy-pr-preview.yml (reusable workflow)
#
# Resilience: Pre-checks whether the backend image already exists in GHCR.
# If it does, we pass it as backend_image override so the reusable workflow
# skips the cross-repo build/push entirely. If it doesn't exist, the reusable
# workflow builds and pushes it using GHCR_PAT for cross-repo authentication.
# =============================================================================

name: PR Preview (Frontend)

on:
pull_request:
# Trigger on PR lifecycle events
types: [opened, synchronize, reopened]
# Only run for frontend code changes
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/**'
- '!.github/workflows/pr-preview-frontend.yml'
- '!.github/workflows/cleanup-pr-preview-frontend.yml'

# Prevent multiple deployments for the same PR
concurrency:
group: pr-preview-frontend-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read
packages: write
pull-requests: write
attestations: write
id-token: write

jobs:
# ===========================================================================
# JOB: Check if the backend image already exists in GHCR
# ===========================================================================
# This avoids the cross-repo build/push entirely when the image is available,
# making the workflow resilient even without GHCR_PAT.
# ===========================================================================
check-backend-image:
name: Check Backend Image
runs-on: ubuntu-latest
outputs:
image_exists: ${{ steps.check.outputs.exists }}
backend_image: ${{ steps.check.outputs.backend_image }}
steps:
- name: Login to GHCR (read access)
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Check if backend image exists
id: check
run: |
BACKEND_IMAGE="ghcr.io/refactor-group/refactor-platform-rs:main-arm64"
echo "backend_image=${BACKEND_IMAGE}" >> $GITHUB_OUTPUT

if docker manifest inspect "${BACKEND_IMAGE}" >/dev/null 2>&1; then
echo "Backend image exists: ${BACKEND_IMAGE}"
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "Backend image NOT found: ${BACKEND_IMAGE}"
echo "exists=false" >> $GITHUB_OUTPUT
fi

# ===========================================================================
# JOB: Call reusable workflow with frontend-specific configuration
# ===========================================================================
# When the backend image exists, pass it as an override to skip building.
# When it doesn't exist, the reusable workflow builds it using GHCR_PAT.
# ===========================================================================
deploy-frontend-pr:
name: Deploy Frontend PR Preview
needs: check-backend-image
# Call the reusable workflow from backend repository
# TODO: After backend PR #190 merges, change to @main
uses: refactor-group/refactor-platform-rs/.github/workflows/ci-deploy-pr-preview.yml@190-add-a-staging-environment-for-previewing-and-testing-ahead-of-a-new-deployment
with:
# This is a frontend PR deployment
repo_type: 'frontend'
# Use the PR number for port allocation and naming
pr_number: ${{ github.event.pull_request.number }}
# Build frontend from this PR's branch
branch_name: ${{ github.head_ref }}
# TODO: After backend PR #190 merges, change to 'main'
backend_branch: '190-add-a-staging-environment-for-previewing-and-testing-ahead-of-a-new-deployment'
# If the backend image already exists, pass it to skip the cross-repo
# build/push. Otherwise leave empty so the reusable workflow builds it.
backend_image: ${{ needs.check-backend-image.outputs.image_exists == 'true' && needs.check-backend-image.outputs.backend_image || '' }}
# Optional: force complete rebuild
force_rebuild: false
# =========================================================================
# SECRETS
# =========================================================================
# The reusable workflow always uses its own pr-preview environment (backend repo)
# which has all secrets (Tiptap, MailerSend, etc.). Common secrets (SSH, GHCR,
# Postgres) are also at org level for redundancy. secrets: inherit passes any
# additional org/repo secrets the frontend might have.
secrets: inherit

# ===========================================================================
# JOB: Report missing backend image (fallback diagnostic)
# ===========================================================================
# If the backend image doesn't exist and GHCR_PAT is unavailable, the deploy
# job will fail on cross-repo push. This job posts a PR comment explaining
# how to fix the issue.
# ===========================================================================
report-missing-image:
name: Report Missing Backend Image
runs-on: ubuntu-latest
needs: [check-backend-image, deploy-frontend-pr]
if: |
always() &&
needs.check-backend-image.outputs.image_exists == 'false' &&
needs.deploy-frontend-pr.result == 'failure'
permissions:
pull-requests: write
steps:
- name: Post remediation comment
uses: actions/github-script@v7
with:
script: |
const body = `## ⚠️ PR Preview Deploy Failed — Backend Image Missing

The backend image \`ghcr.io/refactor-group/refactor-platform-rs:main-arm64\` was not found in GHCR, and the cross-repo build/push failed (likely due to an expired or missing \`GHCR_PAT\` secret).

### How to fix

1. **Create a fine-grained PAT** with \`Packages: Read & write\` and \`Contents: Read\` permissions at [GitHub Settings → Fine-grained tokens](https://github.com/settings/personal-access-tokens/new)
2. **Store it as an org secret** (requires org admin):
\`\`\`bash
gh secret set GHCR_PAT --org refactor-group --visibility selected --repos "refactor-platform-rs,refactor-platform-fe"
gh secret set GHCR_USERNAME --org refactor-group --visibility selected --repos "refactor-platform-rs,refactor-platform-fe" --body "<your-username>"
\`\`\`
3. **Re-run this workflow** from the Actions tab

Alternatively, push a commit to the **backend** repo's \`main\` branch to rebuild the \`main-arm64\` image, then re-run this workflow.`;

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,30 @@ All tests should pass before merging code. The test suite is designed to:
For more detailed testing information, see [docs/testing/frontend-testing-strategy.md](./docs/testing/frontend-testing-strategy.md).

#### For Working with and Running the Application in Docker, navigate to the [Container-README](./docs/runbooks/Container-README.md)

---

## CI/CD & Deployment

This project uses GitHub Actions for continuous integration, release builds, and deployment.

- **Branch CI**: Automated linting, testing, and Docker builds on every push/PR
- **Release Builds**: Multi-architecture production images triggered by GitHub releases
- **Deployment**: Manual deployment to DigitalOcean via secure Tailscale VPN
- **PR Previews**: Automatic preview environments for each pull request

📚 **Documentation:** [docs/cicd/README.md](docs/cicd/README.md)

**Note:** The frontend shares CI/CD infrastructure with the backend repository. For comprehensive documentation including PR preview workflows, see the [Backend CI/CD Documentation](https://github.com/refactor-group/refactor-platform-rs/tree/main/docs/cicd).

### PR Preview Environments

This repository automatically deploys **isolated preview environments** for each pull request. When you open a PR, a complete stack (backend + frontend + database) deploys to a dedicated server on our Tailnet for testing before merge.

**What happens automatically:**

- ✅ PR opened → Environment deploys
- ✅ New commits → Environment updates
- ✅ PR closed/merged → Environment cleans up

**Access:** Requires Tailscale VPN connection. Access URLs are posted as a comment on your PR in the GitHub Web UI.
80 changes: 80 additions & 0 deletions docs/cicd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# CI/CD Infrastructure - Frontend

## Overview

The Refactor Platform frontend uses GitHub Actions for continuous integration, release builds, and PR preview deployments. The CI/CD infrastructure is shared with the backend repository.

**Quick Stats:**
- **5 GitHub Actions Workflows** (CI, Release, Deploy, PR Preview x2)
- **Docker-based Deployment** to GitHub Container Registry (GHCR)
- **Production Platform:** DigitalOcean (accessed via Tailscale VPN)
- **Preview Platform:** Raspberry Pi 5 (ARM64, coordinated with backend)

---

## Workflows

### 1. Branch CI Pipeline
**File:** `.github/workflows/build_and_push_nonproduction_images.yml`
**Triggers:** Push to main, Pull requests to main

Runs linting, testing, and builds Docker images for non-production branches.

### 2. Production Release Builds
**File:** `.github/workflows/build_and_push_production_images.yml`
**Triggers:** GitHub releases (type: released), Manual dispatch

Builds multi-architecture stable images for production deployment.

### 3. Production Deployment
**File:** `.github/workflows/deploy_to_do.yml`
**Triggers:** Manual dispatch only

Deploys to DigitalOcean via Tailscale VPN (coordinated with backend deployment).

### 4. Frontend PR Preview
**File:** `.github/workflows/pr-preview-frontend.yml` (on branch 225)
**Triggers:** Pull request opened/synchronize/reopened (frontend changes)

Calls the backend repository's reusable workflow to deploy PR preview environments.

**Parameters:**
- `repo_type: 'frontend'`
- `pr_number`: PR number
- `branch_name`: Frontend PR branch
- `backend_branch`: 'main' (or temporary override)

### 5. Frontend PR Cleanup
**File:** `.github/workflows/cleanup-pr-preview-frontend.yml` (on branch 225)
**Triggers:** Pull request closed/merged

Calls the backend repository's reusable cleanup workflow.

---

## PR Preview Environments

Frontend PRs trigger the same preview environment infrastructure as backend PRs. The workflows call reusable workflows in the backend repository:

- **Deployment:** `refactor-group/refactor-platform-rs/.github/workflows/ci-deploy-pr-preview.yml`
- **Cleanup:** `refactor-group/refactor-platform-rs/.github/workflows/cleanup-pr-preview.yml`

This ensures parity between frontend and backend PR previews - both create isolated full-stack environments with unique ports.

**Access:** Requires Tailscale VPN connection. Preview URLs are posted as PR comments.

---

## Comprehensive Documentation

For complete CI/CD infrastructure documentation, including:
- Detailed workflow specifications
- Docker infrastructure guides
- Database migration workflows
- Security and secrets management
- Troubleshooting guides
- Gap analysis and future improvements

See: **[Backend Repository CI/CD Docs](https://github.com/refactor-group/refactor-platform-rs/tree/main/docs/cicd)**

The backend repository contains the authoritative documentation for the shared CI/CD infrastructure, including the reusable workflows that both repositories use for PR preview deployments.
Loading
Loading