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
73 changes: 0 additions & 73 deletions .github/workflows/build-runtime-manual.yml

This file was deleted.

224 changes: 224 additions & 0 deletions .github/workflows/build-runtime.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
name: Build Runtime Image

on:
workflow_dispatch:
pull_request:
branches: [main, master]
types: [opened, synchronize, reopened]
paths:
- "sandbox/**"
- ".github/workflows/build-runtime.yml"
- "!sandbox/*.md"
push:
branches: [main, master]
paths:
- "sandbox/**"
- ".github/workflows/build-runtime.yml"
- "!sandbox/*.md"

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

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME }}

jobs:
build-runtime-images:
name: Build Runtime Docker Images
permissions:
packages: write
runs-on: ubuntu-24.04

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
if: ${{ github.event_name != 'pull_request' && github.actor != 'dependabot[bot]' && env.DOCKERHUB_USERNAME != '' }}
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to GitHub Container Registry
if: ${{ github.event_name != 'pull_request' && github.actor != 'dependabot[bot]' }}
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/fullstack-web-runtime
${{ env.DOCKERHUB_USERNAME && format('docker.io/{0}/fullstack-web-runtime', env.DOCKERHUB_USERNAME) || '' }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix=sha-
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') || github.ref == format('refs/heads/{0}', 'master') }}
labels: |
org.opencontainers.image.title=FullStack Web Runtime
org.opencontainers.image.description=Full-stack web development runtime with Next.js, shadcn/ui, Claude Code CLI, and container tools
org.opencontainers.image.vendor=${{ github.repository_owner }}

- name: Build and Push Docker Image
id: docker-build
uses: docker/build-push-action@v6
with:
context: ./sandbox
file: ./sandbox/Dockerfile
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64

Copilot AI Nov 8, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The runtime build workflow only builds for linux/amd64 (line 89), contradicting the PR's stated goal of multi-architecture support and the changelog which claims both amd64 and arm64 builds. Either add a matrix strategy like in docker-build-push.yml or update documentation to reflect single-architecture builds.

Suggested change
platforms: linux/amd64
platforms: linux/amd64,linux/arm64

Copilot uses AI. Check for mistakes.
tags: ${{ steps.meta.outputs.tags }}
# PR builds: load locally for validation, Push builds: push to registry
push: ${{ github.event_name != 'pull_request' && github.actor != 'dependabot[bot]' }}
load: ${{ github.event_name == 'pull_request' }}
cache-from: type=gha,scope=runtime-amd64
cache-to: type=gha,mode=max,scope=runtime-amd64

- name: Comment on PR
if: github.event_name == 'pull_request' && always()
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
const buildSuccess = '${{ steps.docker-build.outcome }}' === 'success';
const emoji = buildSuccess ? '✅' : '❌';
const status = buildSuccess ? 'Success' : 'Failed';

let body = `## ${emoji} FullStack Web Runtime Build ${status}\n\n`;
body += `### Build Details\n\n`;
body += `| Item | Value |\n`;
body += `|------|-------|\n`;
body += `| Build Status | ${buildSuccess ? '✅ Passed' : '❌ Failed'} |\n`;
body += `| Platforms | linux/amd64 (PR validation) |\n`;
body += `| Push to Registry | ⚠️ No (PR build only) |\n`;
body += `| Base Image | ubuntu:24.04 |\n`;
body += `| Node.js | 22.x LTS |\n`;
body += `| Components | Claude Code CLI, ttyd, Next.js, Prisma, PostgreSQL client, Buildah |\n\n`;

if (buildSuccess) {
body += `### 📦 Runtime image will be published after merge\n\n`;
body += `**Note**: PR builds only verify the Docker build process. `;
body += `Images are pushed to registries only when merged to main.\n\n`;
body += `**Registries**:\n`;
body += `- GitHub Container Registry: \`ghcr.io/${{ github.repository_owner }}/fullstack-web-runtime\`\n`;
if ('${{ env.DOCKERHUB_USERNAME }}') {
body += `- Docker Hub: \`docker.io/${{ env.DOCKERHUB_USERNAME }}/fullstack-web-runtime\`\n`;
}
body += `\n**Included Tools**:\n`;
body += `- Node.js 22.x + npm, pnpm, yarn\n`;
body += `- Claude Code CLI (@anthropic-ai/claude-code)\n`;
body += `- Next.js with shadcn/ui components\n`;
body += `- PostgreSQL 16 client\n`;
body += `- Container tools (Buildah, Podman, Skopeo)\n`;
body += `- Development tools (Git, GitHub CLI, ripgrep, jq, etc.)\n`;
body += `- ttyd web terminal\n`;
} else {
body += `### ❌ Build Failed\n\n`;
body += `Please check the workflow logs for detailed error information.\n`;
}

body += `\n---\n`;
body += `**Commit**: \`${{ github.sha }}\`\n`;
body += `**Triggered by**: @${{ github.actor }}\n`;

try {
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(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('FullStack Web Runtime Build')
);

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}
} catch (error) {
console.log('Failed to post comment:', error.message);
console.log('This might be expected for PRs from forks');
}

- name: Generate build summary
if: ${{ github.event_name != 'pull_request' && github.actor != 'dependabot[bot]' && always() }}
run: |
echo "## 🚀 Runtime Image Build & Push Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Build Status" >> $GITHUB_STEP_SUMMARY
if [ "${{ steps.docker-build.outcome }}" = "success" ]; then
echo "- ✅ Runtime build successful" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Platform: \`linux/amd64\`" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Pushed to GitHub Container Registry: \`ghcr.io/${{ github.repository_owner }}/fullstack-web-runtime\`" >> $GITHUB_STEP_SUMMARY
if [ -n "${{ env.DOCKERHUB_USERNAME }}" ]; then
echo "- ✅ Pushed to Docker Hub: \`docker.io/${{ env.DOCKERHUB_USERNAME }}/fullstack-web-runtime\`" >> $GITHUB_STEP_SUMMARY
fi
else
echo "- ❌ Build or push failed" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Runtime Image Details" >> $GITHUB_STEP_SUMMARY
echo "- **Base**: Ubuntu 24.04" >> $GITHUB_STEP_SUMMARY
echo "- **Node.js**: 22.x LTS" >> $GITHUB_STEP_SUMMARY
echo "- **PostgreSQL Client**: 16" >> $GITHUB_STEP_SUMMARY
echo "- **Claude Code CLI**: @anthropic-ai/claude-code" >> $GITHUB_STEP_SUMMARY
echo "- **Next.js**: Latest with shadcn/ui components" >> $GITHUB_STEP_SUMMARY
echo "- **Container Tools**: Buildah, Podman, Skopeo" >> $GITHUB_STEP_SUMMARY
echo "- **Terminal**: ttyd web-based terminal" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Build Information" >> $GITHUB_STEP_SUMMARY
echo "- **Commit SHA**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Branch**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Triggered by**: @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
echo "- **Event**: \`${{ github.event_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Build time**: $(date '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Image Tags" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Usage Example" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "# Pull the latest image" >> $GITHUB_STEP_SUMMARY
echo "docker pull ghcr.io/${{ github.repository_owner }}/fullstack-web-runtime:latest" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "# Run with environment variables" >> $GITHUB_STEP_SUMMARY
echo "docker run -d -p 7681:7681 -p 3000:3000 \\" >> $GITHUB_STEP_SUMMARY
echo " -e ANTHROPIC_AUTH_TOKEN=your_token \\" >> $GITHUB_STEP_SUMMARY
echo " -e PROJECT_NAME=my-project \\" >> $GITHUB_STEP_SUMMARY
echo " ghcr.io/${{ github.repository_owner }}/fullstack-web-runtime:latest" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
Loading
Loading