Add PR preview deployments with GitHub Pages - #1
Conversation
🚀 Preview Deployment Ready!
This preview will be automatically updated when you push new commits to this PR. Browse all previews: https://preview.wafer.space ⚡ Deployed to custom domain • Preview will be removed when PR is closed |
Add critical guidance about verifying working directory before running commands due to complex submodule architecture and multiple working directories. Key guidance: • Always verify current working directory with pwd before commands • Main repository root: ./ (top-level directory with _config.yml) • Theme submodule: ./_theme/ (contains Jekyll theme files) • Preview cleanup: /tmp/preview-cleanup/ (temporary cleanup workspace) • Temporary directories: _tmp/preview-repo/ (relative to repository root) Common mistakes addressed: • Running Jekyll commands from wrong directory • Editing theme files when not in _theme/ directory • Git operations in wrong repository context This prevents common development errors and ensures commands are run in the correct context for this complex repository architecture.
Implements a comprehensive GitHub Actions workflow for automatically deploying pull request previews to a custom domain at preview.wafer.space. Core features: • Automatic PR preview deployments at https://preview.wafer.space/pr-{number}/ • GitHub Deployments API integration with status tracking • Secure SSH authentication for private theme submodule access • Custom domain deployment using dedicated preview repository • Automatic cleanup when PRs are closed • Professional PR comments with deployment status • Central preview index page listing all active previews Architecture: • Modular JavaScript modules for GitHub API interactions • Reusable Markdown templates for consistent messaging • Jekyll builds with PR-specific baseurl configuration • Dedicated preview.wafer.space repository avoids CNAME conflicts • Memory-only SSH key handling for enhanced security This provides a solid foundation for PR preview functionality with enterprise-grade security practices and maintainable code organization. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
Adds a GitHub Actions workflow and supporting scripts/templates to build, deploy, and track Jekyll-based preview environments for each pull request on a custom GitHub Pages domain, with automatic cleanup on PR close.
- Introduces
.github/workflows/pr-preview.ymlto build and deploy previews per PR - Adds scripts in
.github/scripts/for creating deployments, updating status, generating directories, and commenting PRs - Provides template files in
.github/templates/and documentation updates for users and local workflows
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| CLAUDE.md | Adds a critical reminder to verify working directory |
| .github/workflows/pr-preview.yml | New Actions workflow for PR preview deployments |
| .github/workflows/pr-preview.md | Markdown docs for the PR preview workflow |
| .github/templates/redirect-template.html | HTML template for slugified redirect pages |
| .github/templates/preview-index.html | Template for the central index of active PR previews |
| .github/templates/pr-comment-template.md | Template for the success comment posted on PRs |
| .github/templates/pr-cleanup-template.md | Template for cleanup notification on closed PRs |
| .github/scripts/create-deployment.js | Script to create GitHub Deployment entries |
| .github/scripts/update-deployment-status.js | Script to mark deployments as success/failure/inactive |
| .github/scripts/generate-pr-directory-name.js | Module to slugify PR titles into directory names |
| .github/scripts/generate-preview-index.sh | Bash script to build the preview index page |
| .github/scripts/comment-pr-preview.js | Script to post or update preview status comments on PR |
| .github/scripts/comment-pr-cleanup.js | Script to comment on PR when its preview is removed |
| .github/scripts/cleanup-deployments.js | Marks all deployments inactive when a PR is closed |
| .claude/settings.local.json | Local Claude tooling settings updated with new commands |
Comments suppressed due to low confidence (2)
.github/workflows/pr-preview.yml:19
- Consider using a per-PR concurrency group (e.g.,
pr-preview-${{ github.event.pull_request.number }}) so builds for different PRs don’t block each other.
group: pr-preview-deployment
.github/workflows/pr-preview.yml:161
- Exiting with
exit 1when there are no changes marks the step as a failure—useexit 0or skip pushing to avoid failing the job when no changes occur.
if git diff --staged --quiet; then
| # Replace placeholder with actual items | ||
| if ! sed -i "s|<!-- PREVIEW_ITEMS_PLACEHOLDER -->|$PREVIEW_ITEMS|g" "$OUTPUT_FILE"; then |
There was a problem hiding this comment.
Embedding raw HTML in a single sed replacement can break if $PREVIEW_ITEMS contains the delimiter or unescaped characters; consider using a here-document or safer template engine for placeholder insertion.
| # Replace placeholder with actual items | |
| if ! sed -i "s|<!-- PREVIEW_ITEMS_PLACEHOLDER -->|$PREVIEW_ITEMS|g" "$OUTPUT_FILE"; then | |
| # Replace placeholder with actual items using a here-document | |
| if ! { | |
| awk -v preview_items="$PREVIEW_ITEMS" ' | |
| /<!-- PREVIEW_ITEMS_PLACEHOLDER -->/ { print preview_items; next } | |
| { print } | |
| ' "$TEMPLATE_FILE" > "$OUTPUT_FILE"; | |
| }; then |
|
|
||
| // Validate template path to prevent directory traversal | ||
| const resolvedPath = path.resolve(templatePath); | ||
| if (!resolvedPath.includes('.github/templates/pr-comment-template.md')) { |
There was a problem hiding this comment.
The includes check may be too permissive—use a strict equality or path comparison (e.g., resolvedPath === path.resolve(templatePath)) to prevent directory traversal risks.
| if (!resolvedPath.includes('.github/templates/pr-comment-template.md')) { | |
| const expectedPath = path.resolve('.github/templates/pr-comment-template.md'); | |
| if (resolvedPath !== expectedPath) { |
🧹 Preview Deployment RemovedThe preview deployment for this PR has been removed from https://preview.wafer.space |
Summary
• Adds automatic preview deployments for pull requests using GitHub Pages
• Each PR gets a custom preview URL at
https://preview.wafer.space/pr-123/• Automatic cleanup when PRs are closed
• Clean commit history with logical progression
Features Added
• GitHub Actions workflow for PR preview deployments with custom domain support
• External templates and scripts for maintainability and clean separation of concerns
• Deployment tracking using GitHub Deployments API with environment status
• Preview index page listing all active previews at
https://preview.wafer.space/• Automatic PR comments with preview URLs and deployment status
• Proper error handling that fails fast on real problems instead of silent suppression
Technical Details
• Uses Jekyll with PR-specific base URLs for proper routing
• SSH deploy key integration for private theme submodule access
• Custom domain configuration with CNAME file generation
• Comprehensive documentation for users and maintainers
Test Plan
🤖 Generated with Claude Code