Skip to content

Merge pull request #65 from dstengle/claude/test-webapp-processor-018… #3

Merge pull request #65 from dstengle/claude/test-webapp-processor-018…

Merge pull request #65 from dstengle/claude/test-webapp-processor-018… #3

name: Build and Push Webapp to GHCR
on:
push:
branches:
- main
- 'claude/**'
paths:
- 'webapp/**'
- 'knowledgebase_processor/**'
- '.github/workflows/publish-webapp-ghcr.yml'
pull_request:
branches:
- main
paths:
- 'webapp/**'
- 'knowledgebase_processor/**'
workflow_dispatch:
inputs:
tag:
description: 'Custom tag for the image'
required: false
default: 'latest'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/kb-processor-webapp
jobs:
build-and-push:
name: Build and Push to GHCR
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
run: |
# Get short SHA
SHORT_SHA=$(git rev-parse --short HEAD)
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
# Get branch name
BRANCH_NAME=${GITHUB_REF##*/}
echo "branch=${BRANCH_NAME}" >> $GITHUB_OUTPUT
# Get timestamp
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
echo "timestamp=${TIMESTAMP}" >> $GITHUB_OUTPUT
# Get repository name (lowercase)
REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
echo "repo_lower=${REPO_LOWER}" >> $GITHUB_OUTPUT
# Determine tags
if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ github.event.inputs.tag }}" ]]; then
CUSTOM_TAG="${{ github.event.inputs.tag }}"
echo "custom_tag=${CUSTOM_TAG}" >> $GITHUB_OUTPUT
fi
- name: Build Docker image tags
id: docker_tags
run: |
GHCR_IMAGE="ghcr.io/${{ steps.meta.outputs.repo_lower }}/kb-processor-webapp"
TAGS="${GHCR_IMAGE}:${{ steps.meta.outputs.short_sha }}"
TAGS="${TAGS},${GHCR_IMAGE}:${{ steps.meta.outputs.timestamp }}"
# Add branch-specific tag
if [[ "${{ steps.meta.outputs.branch }}" == "main" ]]; then
TAGS="${TAGS},${GHCR_IMAGE}:latest"
TAGS="${TAGS},${GHCR_IMAGE}:stable"
else
SAFE_BRANCH=$(echo "${{ steps.meta.outputs.branch }}" | sed 's/\//-/g')
TAGS="${TAGS},${GHCR_IMAGE}:${SAFE_BRANCH}"
fi
# Add custom tag if provided
if [[ -n "${{ steps.meta.outputs.custom_tag }}" ]]; then
TAGS="${TAGS},${GHCR_IMAGE}:${{ steps.meta.outputs.custom_tag }}"
fi
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./webapp/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_tags.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
labels: |
org.opencontainers.image.title=Knowledge Base Processor Webapp
org.opencontainers.image.description=Web interface for the Knowledge Base Processor
org.opencontainers.image.url=https://github.com/${{ github.repository }}
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.created=${{ steps.meta.outputs.timestamp }}
org.opencontainers.image.licenses=MIT
- name: Generate deployment summary
if: github.event_name != 'pull_request'
run: |
echo "## 🚀 Deployment Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Image Details" >> $GITHUB_STEP_SUMMARY
echo "- **Registry:** GitHub Container Registry (GHCR)" >> $GITHUB_STEP_SUMMARY
echo "- **Image:** \`${{ steps.docker_tags.outputs.ghcr_image }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Commit SHA:** \`${{ steps.meta.outputs.short_sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Branch:** \`${{ steps.meta.outputs.branch }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Timestamp:** \`${{ steps.meta.outputs.timestamp }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🏷️ Tags" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.docker_tags.outputs.tags }}" | tr ',' '\n' >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Pull Command" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ steps.docker_tags.outputs.ghcr_image }}:${{ steps.meta.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🚀 Run Command" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker run -p 8000:8000 ${{ steps.docker_tags.outputs.ghcr_image }}:${{ steps.meta.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🔗 Package URL" >> $GITHUB_STEP_SUMMARY
echo "https://github.com/${{ github.repository }}/pkgs/container/kb-processor-webapp" >> $GITHUB_STEP_SUMMARY
- name: Output image URL
if: github.event_name != 'pull_request'
run: |
echo "✅ Image published successfully!"
echo "📍 Image URL: ${{ steps.docker_tags.outputs.ghcr_image }}:${{ steps.meta.outputs.short_sha }}"
echo "🌐 Access the webapp at: http://localhost:8000 (after running the container)"
echo "📦 View package: https://github.com/${{ github.repository }}/pkgs/container/kb-processor-webapp"
verify-image:
name: Verify Published Image
needs: build-and-push
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
permissions:
packages: read
steps:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Verify image exists
run: |
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
IMAGE="ghcr.io/${REPO_LOWER}/kb-processor-webapp:${SHORT_SHA}"
echo "Verifying image: ${IMAGE}"
if docker manifest inspect ${IMAGE} > /dev/null 2>&1; then
echo "✅ Image verified successfully!"
else
echo "❌ Image verification failed!"
exit 1
fi