Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
13f9a15
refactor(video-player): rewrite with robust autoplay and poster fallback
actions-user Mar 17, 2026
99b3b00
style(globals.css): add separator-3 style, fix separator display, and…
actions-user Mar 17, 2026
4d21780
feat(about): add Counter, ProgressBar, and TeamMember components
actions-user Mar 17, 2026
4fdb8cc
feat(portfolio): add PortfolioCard and PortfolioModal components
actions-user Mar 17, 2026
d79dea5
refactor(layout): add shared ContactSection banner component
actions-user Mar 17, 2026
917d7ff
feat(header): add built-in route loading progress bar and navigation …
actions-user Mar 17, 2026
5d3bf5f
redesign(footer): dark theme with social links, contact info, and sit…
actions-user Mar 17, 2026
2903af8
redesign(accordion-tabs): add tabbed navigation with icons and improv…
actions-user Mar 17, 2026
8d4974c
style(scrolling-portfolio): condense JSX formatting and inline short …
actions-user Mar 17, 2026
4f5023f
fix(pages): update ContactSection import path and use avif image format
actions-user Mar 17, 2026
04a43c5
feat(about): redesign about page with team members, counters, and com…
actions-user Mar 17, 2026
3e3d289
feat(pages): add Contact, Portfolio, and Services pages with contact API
actions-user Mar 17, 2026
e4ac7d0
assets: add portfolio images, staff photos, and background videos
actions-user Mar 17, 2026
09471b2
feat: enable GitHub Pages preview deployments for all branches/PRs
actions-user Mar 17, 2026
88f6cac
Updated node version to 24 and fixed manager error/warning.
actions-user Mar 17, 2026
7055b39
fix: remove repo name from basePath when using custom domain
actions-user Mar 17, 2026
ea1042f
Potential fix for pull request finding
digitalnomad91 Mar 17, 2026
955ef9e
fix(ci): add CNAME to gh-pages deployment for custom domain
actions-user Mar 17, 2026
2ce3752
fix(ci): preserve preview directories when deploying main to gh-pages
actions-user Mar 17, 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
37 changes: 37 additions & 0 deletions .github/workflows/cleanup-gh-pages-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: 🧹 Cleanup GitHub Pages Preview

on:
pull_request:
types: [closed]

permissions:
contents: write

jobs:
cleanup:
name: 🗑 Remove Preview Deployment
runs-on: ubuntu-latest

steps:
- name: 🔍 Checkout gh-pages branch
uses: actions/checkout@v4
with:
ref: gh-pages
fetch-depth: 1

- name: 🧹 Remove preview directory
run: |
BRANCH="${{ github.head_ref }}"
SAFE_BRANCH=$(echo "$BRANCH" | sed 's/[^a-zA-Z0-9._-]/-/g')
PREVIEW_DIR="preview/${SAFE_BRANCH}"

if [ -d "$PREVIEW_DIR" ]; then
echo "Removing preview directory: $PREVIEW_DIR"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git rm -rf "$PREVIEW_DIR"
git commit -m "🧹 Remove preview for closed PR #${{ github.event.pull_request.number }} ($BRANCH)"
git push
else
echo "No preview directory found at $PREVIEW_DIR, skipping cleanup."
fi
167 changes: 126 additions & 41 deletions .github/workflows/nextjs-static-gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,173 @@

on:
push:
branches: ['main'] # Triggers on push to main branch
branches: ['**'] # Triggers on push to any branch
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch: # Allows manual triggering

permissions:
contents: read
pages: write
id-token: write
contents: write
pull-requests: write

concurrency:
group: 'pages'
cancel-in-progress: false
group: 'pages-${{ github.head_ref || github.ref_name }}'
cancel-in-progress: true

jobs:
build:
name: 🏗 Build Static Site
build-and-deploy:
name: 🏗 Build & Deploy
runs-on: ubuntu-latest



steps:
- name: 🔍 Checkout repository
uses: actions/checkout@v4

- name: 🔧 Set deployment variables
id: vars
run: |
REPO_NAME="${{ github.event.repository.name }}"
# Custom domain means no repo name prefix in the URL path.
# Set CUSTOM_DOMAIN to your domain, or leave empty to use github.io/<repo> URLs.
CUSTOM_DOMAIN="dev.codebuilder.org"

# Get the branch name (works for both push and PR events)
if [ "${{ github.event_name }}" = "pull_request" ]; then
BRANCH="${{ github.head_ref }}"
else
BRANCH="${{ github.ref_name }}"
fi

# Sanitize branch name for use in URL paths
SAFE_BRANCH=$(echo "$BRANCH" | sed 's/[^a-zA-Z0-9._-]/-/g')

if [ -n "$CUSTOM_DOMAIN" ]; then
BASE_URL="https://${CUSTOM_DOMAIN}"
else
BASE_URL="https://${{ github.repository_owner }}.github.io/${REPO_NAME}"
fi

if [ "$BRANCH" = "main" ]; then
if [ -n "$CUSTOM_DOMAIN" ]; then
echo "base_path=" >> $GITHUB_OUTPUT
else
echo "base_path=/${REPO_NAME}" >> $GITHUB_OUTPUT
fi
echo "dest_dir=" >> $GITHUB_OUTPUT
# keep_files must be true so preview/ directories are preserved
echo "keep_files=true" >> $GITHUB_OUTPUT
echo "is_main=true" >> $GITHUB_OUTPUT
echo "preview_url=${BASE_URL}/" >> $GITHUB_OUTPUT
else
echo "base_path=/preview/${SAFE_BRANCH}" >> $GITHUB_OUTPUT
echo "dest_dir=preview/${SAFE_BRANCH}" >> $GITHUB_OUTPUT
echo "keep_files=true" >> $GITHUB_OUTPUT
echo "preview_url=${BASE_URL}/preview/${SAFE_BRANCH}/" >> $GITHUB_OUTPUT
fi

echo "branch=$BRANCH" >> $GITHUB_OUTPUT
echo "safe_branch=$SAFE_BRANCH" >> $GITHUB_OUTPUT

- name: 🔎 Detect package manager
id: detect-pm
run: |
if [ -f "pnpm-lock.yaml" ]; then
echo "manager=pnpm" >> $GITHUB_ENV
echo "command=install" >> $GITHUB_ENV
echo "runner=pnpm exec" >> $GITHUB_ENV
echo "manager=pnpm" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=pnpm exec" >> $GITHUB_OUTPUT
else
echo "manager=npm" >> $GITHUB_ENV
echo "command=ci" >> $GITHUB_ENV
echo "runner=npx --no-install" >> $GITHUB_ENV
echo "manager=npm" >> $GITHUB_OUTPUT
echo "command=ci" >> $GITHUB_OUTPUT
echo "runner=npx --no-install" >> $GITHUB_OUTPUT
fi

- name: 📦 Install pnpm
if: env.manager == 'pnpm'
if: steps.detect-pm.outputs.manager == 'pnpm'
run: npm install -g pnpm

- name: ⚙️ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: ${{ env.manager }}

- name: 🌐 Setup GitHub Pages
uses: actions/configure-pages@v5

# NOTE: We do NOT need to create .env or secrets here, as we provide them directly to the build step below.

node-version: '24'
cache: ${{ steps.detect-pm.outputs.manager }}

- name: 🚫 Ephemerally delete server/api files
run: |
echo "Deleting src/app/api, src/server, src/proxy.ts, and src/app/jobs/[id] for static build..."
rm -rf src/app/api src/server src/proxy.ts src/app/jobs/[id] src/app/[...not-found] prisma.config.ts

- name: 📥 Install dependencies
run: ${{ env.manager }} ${{ env.command }}
run: ${{ steps.detect-pm.outputs.manager }} ${{ steps.detect-pm.outputs.command }}

- name: 🏗 Generate Static Build
env:
NEXT_OUTPUT_MODE: export
GITHUB_PAGES: 1
NEXT_BASE_PATH: ${{ steps.vars.outputs.base_path }}
run: |
echo "Building static files for GitHub Pages..."
echo "Base path: $NEXT_BASE_PATH"
echo "Preview URL: ${{ steps.vars.outputs.preview_url }}"
pnpm build
touch out/.nojekyll

- name: 📤 Upload static site
uses: actions/upload-pages-artifact@v3
- name: 🧹 Clean stale root files from gh-pages (main only)
if: steps.vars.outputs.is_main == 'true'
run: |
# Checkout the gh-pages branch into a temp directory
git fetch origin gh-pages || true
mkdir -p /tmp/gh-pages-current
cd /tmp/gh-pages-current
git init
git remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
git fetch origin gh-pages --depth=1 || exit 0
git checkout gh-pages || exit 0

# Delete everything EXCEPT the preview/ directory and CNAME
find . -maxdepth 1 ! -name '.' ! -name '.git' ! -name 'preview' ! -name 'CNAME' -exec rm -rf {} +

git add -A
git diff --cached --quiet || git -c user.name="github-actions" -c user.email="github-actions@github.com" commit -m "clean stale root files before main deploy"
git push origin gh-pages || true

- name: 🚀 Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action '🚀 Deploy Static Next.js to GitHub Pages' step
Uses Step
uses 'peaceiris/actions-gh-pages' with ref 'v4', not a pinned commit hash
with:
path: ./out # With 'output: export', Next.js automatically puts files here.

deploy:
name: 🚀 Deploy to GitHub Pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: 🌍 Deploy
id: deployment
uses: actions/deploy-pages@v4
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./out
destination_dir: ${{ steps.vars.outputs.dest_dir }}
keep_files: ${{ steps.vars.outputs.keep_files }}
cname: dev.codebuilder.org

- name: 💬 Comment preview URL on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const url = '${{ steps.vars.outputs.preview_url }}';
const sha = context.sha.substring(0, 7);
const body = `🚀 **Preview deployment ready!**\n\n📎 **Preview URL:** ${url}\n\n_Deployed from commit \`${sha}\`_`;

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

const botComment = comments.find(c => c.body.includes('Preview deployment ready!'));

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}
21 changes: 15 additions & 6 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ const isStaticExport = process.env.NEXT_OUTPUT_MODE === 'export'

console.log(`\n Next.js static export mode: ${isStaticExport}`)

const repoName = 'codebuilder-frontend';
const isGithubPages = !!process.env.GITHUB_PAGES;
const repoName = 'codebuilder-frontend'
const isGithubPages = !!process.env.GITHUB_PAGES
// Set by the GitHub Pages workflow to support preview deployments in subdirectories.
// e.g. "/codebuilder-frontend" for main, "/codebuilder-frontend/preview/my-branch" for previews.
const ghPagesBasePath = process.env.NEXT_BASE_PATH || ''

const nextConfig = {
/**
Expand All @@ -21,10 +24,16 @@ const nextConfig = {

// Conditionally set the output mode for the build.
output: isStaticExport ? 'export' : undefined,
//basePath: //isGithubPages ? `/${repoName}` : '',
//assetPrefix: //isGithubPages ? `/${repoName}/` : '',
basePath: ghPagesBasePath || undefined,
assetPrefix: ghPagesBasePath ? `${ghPagesBasePath}/` : undefined,

allowedDevOrigins: ['https://api.codebuilder.org', 'https://new.codebuilder.org', 'https://new.codebuilder.org:443', 'https://dev.codebuilder.org', 'https://dev.codebuilder.org:443'], // resolves the CORS warning
allowedDevOrigins: [
'https://api.codebuilder.org',
'https://new.codebuilder.org',
'https://new.codebuilder.org:443',
'https://dev.codebuilder.org',
'https://dev.codebuilder.org:443',
], // resolves the CORS warning

// Note: If you are using next/image, you may need to add an
// unoptimized: true flag here if you are not using a custom loader.
Expand Down Expand Up @@ -65,7 +74,7 @@ const nextConfig = {

return config
},
} as unknown as NextConfig;
} as unknown as NextConfig

// // Only include page.* files for static export, include route.* for all other builds
// if (isStaticExport) {
Expand Down
Binary file added public/images/portfolio/acs2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/portfolio/cdc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/portfolio/logo-12252.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/portfolio/logo-ddna.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/portfolio/pifm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/portfolio/sf_heart.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/portfolio/taxcoursecentral.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/staff/corbin.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/staff/kevin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/staff/larrygoodrie.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/staff/tom.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/videos/background-video-portfolio.mp4
Binary file not shown.
Binary file added public/videos/background-video-portfolio.webm
Binary file not shown.
Binary file added public/videos/contact-background.mp4
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/videos/cover-images/macbook-typing-poster.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/videos/network-technology-services.mp4
Binary file not shown.
Loading
Loading