Skip to content

Commit 44f970c

Browse files
committed
Merge branch 'main' into pr/1514
2 parents ab8e485 + 8aeeb34 commit 44f970c

File tree

197 files changed

+20446
-2763
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

197 files changed

+20446
-2763
lines changed

.claude/settings.local.json

Lines changed: 0 additions & 99 deletions
This file was deleted.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: "Docker Build Media Server"
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
tag:
7+
description: "Tag for the Docker image"
8+
required: false
9+
default: "latest"
10+
type: string
11+
push:
12+
branches:
13+
- main
14+
paths:
15+
- "apps/media-server/**"
16+
17+
jobs:
18+
build:
19+
name: Build Docker Image (${{ matrix.platform }})
20+
runs-on: ${{ matrix.runner }}
21+
strategy:
22+
matrix:
23+
include:
24+
- platform: amd64
25+
runner: ubuntu-24.04
26+
- platform: arm64
27+
runner: ubuntu-24.04-arm
28+
fail-fast: false
29+
permissions:
30+
contents: read
31+
packages: write
32+
33+
steps:
34+
- name: Checkout Repository
35+
uses: actions/checkout@v4
36+
37+
- name: Set up Docker Buildx
38+
uses: docker/setup-buildx-action@v3
39+
40+
- name: Login to GitHub Container Registry
41+
uses: docker/login-action@v3
42+
with:
43+
registry: ghcr.io
44+
username: ${{ github.actor }}
45+
password: ${{ secrets.GITHUB_TOKEN }}
46+
47+
- name: Downcase GITHUB_REPOSITORY_OWNER
48+
run: |
49+
echo "REPOSITORY_OWNER=${GITHUB_REPOSITORY_OWNER@L}" >>${GITHUB_ENV}
50+
51+
- name: Build and Push Platform Image
52+
id: build
53+
uses: docker/build-push-action@v5
54+
with:
55+
context: ./apps/media-server
56+
file: ./apps/media-server/Dockerfile.standalone
57+
platforms: linux/${{ matrix.platform }}
58+
push: true
59+
outputs: type=image,name=ghcr.io/${{ env.REPOSITORY_OWNER }}/cap-media-server,push-by-digest=true
60+
cache-from: type=gha,scope=media-server-${{ matrix.platform }}
61+
cache-to: type=gha,mode=max,scope=media-server-${{ matrix.platform }}
62+
63+
- name: Export Digest
64+
run: |
65+
mkdir -p /tmp/digests
66+
digest="${{ steps.build.outputs.digest }}"
67+
touch "/tmp/digests/${digest#sha256:}"
68+
69+
- name: Upload Digest
70+
uses: actions/upload-artifact@v4
71+
with:
72+
name: digests-media-server-${{ matrix.platform }}
73+
path: /tmp/digests/*
74+
if-no-files-found: error
75+
retention-days: 1
76+
77+
merge:
78+
name: Create Multi-Architecture Manifest
79+
needs: build
80+
runs-on: ubuntu-latest
81+
permissions:
82+
contents: read
83+
packages: write
84+
85+
steps:
86+
- name: Download Digests
87+
uses: actions/download-artifact@v4
88+
with:
89+
path: /tmp/digests
90+
pattern: digests-media-server-*
91+
merge-multiple: true
92+
93+
- name: Set up Docker Buildx
94+
uses: docker/setup-buildx-action@v3
95+
96+
- name: Login to GitHub Container Registry
97+
uses: docker/login-action@v3
98+
with:
99+
registry: ghcr.io
100+
username: ${{ github.actor }}
101+
password: ${{ secrets.GITHUB_TOKEN }}
102+
103+
- name: Downcase GITHUB_REPOSITORY_OWNER
104+
run: |
105+
echo "REPOSITORY_OWNER=${GITHUB_REPOSITORY_OWNER@L}" >>${GITHUB_ENV}
106+
107+
- name: Create Image Manifest
108+
run: |
109+
docker buildx imagetools create -t ghcr.io/${{ env.REPOSITORY_OWNER }}/cap-media-server:${{ inputs.tag || 'latest' }} \
110+
$(find /tmp/digests -type f -not -path "*/\.*" -exec basename {} \; | xargs -I {} echo "ghcr.io/${{ env.REPOSITORY_OWNER }}/cap-media-server@sha256:{}")
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: "Test Self-Hosting"
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- main
8+
paths:
9+
- "docker-compose.yml"
10+
- "docker-compose.coolify.yml"
11+
- "apps/media-server/**"
12+
- "apps/web/Dockerfile"
13+
- ".github/workflows/test-self-hosting.yml"
14+
pull_request:
15+
paths:
16+
- "docker-compose.yml"
17+
- "docker-compose.coolify.yml"
18+
- "apps/media-server/**"
19+
- "apps/web/Dockerfile"
20+
- ".github/workflows/test-self-hosting.yml"
21+
22+
jobs:
23+
test-docker-compose:
24+
name: Test Docker Compose Self-Hosting
25+
runs-on: ubuntu-latest
26+
timeout-minutes: 15
27+
28+
steps:
29+
- name: Checkout Repository
30+
uses: actions/checkout@v4
31+
32+
- name: Start Cap with Docker Compose
33+
run: |
34+
echo "Starting Cap..."
35+
docker compose up -d
36+
echo "Waiting for services to initialize..."
37+
38+
- name: Wait for MySQL to be healthy
39+
run: |
40+
echo "Waiting for MySQL..."
41+
timeout 120 bash -c 'until docker inspect cap-mysql --format="{{.State.Health.Status}}" 2>/dev/null | grep -q "healthy"; do sleep 2; done'
42+
echo "MySQL is healthy"
43+
44+
- name: Wait for MinIO to be healthy
45+
run: |
46+
echo "Waiting for MinIO..."
47+
timeout 60 bash -c 'until docker inspect cap-minio --format="{{.State.Health.Status}}" 2>/dev/null | grep -q "healthy"; do sleep 2; done'
48+
echo "MinIO is healthy"
49+
50+
- name: Wait for Media Server to be healthy
51+
run: |
52+
echo "Waiting for Media Server..."
53+
timeout 60 bash -c 'until docker inspect cap-media-server --format="{{.State.Health.Status}}" 2>/dev/null | grep -q "healthy"; do sleep 2; done'
54+
echo "Media Server is healthy"
55+
56+
- name: Wait for Cap Web to be healthy
57+
run: |
58+
echo "Waiting for Cap Web..."
59+
timeout 180 bash -c 'until docker inspect cap-web --format="{{.State.Health.Status}}" 2>/dev/null | grep -q "healthy"; do sleep 2; done'
60+
echo "Cap Web is healthy"
61+
62+
- name: Show service status
63+
run: docker compose ps
64+
65+
- name: Test Cap Web responds
66+
run: |
67+
echo "Testing Cap Web..."
68+
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000)
69+
if [ "$response" = "307" ] || [ "$response" = "200" ]; then
70+
echo "✓ Cap Web responds (HTTP $response)"
71+
else
72+
echo "✗ Cap Web failed (HTTP $response)"
73+
exit 1
74+
fi
75+
76+
- name: Test login page renders
77+
run: |
78+
echo "Testing login page..."
79+
if curl -s http://localhost:3000/login | grep -q "Cap"; then
80+
echo "✓ Login page renders correctly"
81+
else
82+
echo "✗ Login page failed to render"
83+
exit 1
84+
fi
85+
86+
- name: Test Media Server health
87+
run: |
88+
echo "Testing Media Server..."
89+
health=$(docker exec cap-web wget -qO- http://media-server:3456/health)
90+
if echo "$health" | grep -q '"status":"ok"'; then
91+
echo "✓ Media Server is healthy"
92+
echo " Response: $health"
93+
else
94+
echo "✗ Media Server health check failed"
95+
exit 1
96+
fi
97+
98+
- name: Test database has tables
99+
run: |
100+
echo "Testing database..."
101+
tables=$(docker exec cap-mysql mysql -ucap -pcap-local-pwd-123 cap -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='cap';" -s -N 2>/dev/null)
102+
if [ "$tables" -gt 0 ]; then
103+
echo "✓ Database has $tables tables (migrations ran successfully)"
104+
else
105+
echo "✗ Database has no tables"
106+
exit 1
107+
fi
108+
109+
- name: Test MinIO bucket exists
110+
run: |
111+
echo "Testing MinIO bucket..."
112+
if docker compose logs minio-setup 2>&1 | grep -q "Bucket created successfully\|already exists"; then
113+
echo "✓ MinIO bucket is configured"
114+
else
115+
echo "✗ MinIO bucket setup failed"
116+
docker compose logs minio-setup
117+
exit 1
118+
fi
119+
120+
- name: Show Cap Web logs
121+
if: always()
122+
run: |
123+
echo "=== Cap Web Logs ==="
124+
docker compose logs cap-web | tail -50
125+
126+
- name: Show all logs on failure
127+
if: failure()
128+
run: |
129+
echo "=== All Service Logs ==="
130+
docker compose logs
131+
132+
- name: Cleanup
133+
if: always()
134+
run: |
135+
docker compose down -v
136+
echo "Cleanup complete"

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,11 @@ tauri.windows.conf.json
5858
scripts/backfill-releases.sh
5959
scripts/update-github-releases.sh
6060
scripts/releases-backfill-data.txt
61+
62+
# SEO agent state (machine-local, contains sensitive ranking data)
63+
seo/
64+
65+
# OpenCode commands (local)
66+
.opencode/
67+
analysis/
68+
analysis/plans/

0 commit comments

Comments
 (0)