Files
cloudlink/.gitea/workflows/docker-build.yml
T
nmemmertandClaude Sonnet 4.6 84ff218a30
Build & Release / Docker / backend (push) Successful in 1m7s
Build & Release / Docker / frontend (push) Successful in 1m14s
Build & Release / Desktop / Linux & Windows (push) Successful in 18m15s
Build & Release / Deploy to server (push) Successful in 18s
Build & Release / Create release (push) Has been cancelled
fix: support both docker compose (v2) and docker-compose (v1) in deploy
The target server has Docker Compose V1 (standalone binary) not the V2
plugin, so 'docker compose' fails. Detect which is available at runtime
and use the appropriate command.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-28 11:27:03 -04:00

180 lines
6.8 KiB
YAML

name: Build & Release
on:
push:
branches: [master, main]
tags: ['v*']
pull_request:
branches: [master, main]
env:
REGISTRY: git.necloud.us
OWNER: nate
REPO: cloudlink
jobs:
# ─── Docker: Backend ────────────────────────────────────────────────────────
build-backend:
name: Docker / backend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Log in to registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: ./backend
file: ./backend/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: |
${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/backend:latest
${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/backend:${{ github.sha }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/backend:cache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/backend:cache,mode=max
# ─── Docker: Frontend ───────────────────────────────────────────────────────
build-frontend:
name: Docker / frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Log in to registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: ./frontend
file: ./frontend/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
build-args: |
VITE_API_URL=/api
VITE_WS_URL=/ws
tags: |
${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/frontend:latest
${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/frontend:${{ github.sha }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/frontend:cache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/frontend:cache,mode=max
# ─── Desktop installers (Linux + Windows, built on Linux runner) ─────────────
build-desktop:
name: Desktop / Linux & Windows
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: desktop/package-lock.json
- name: Install desktop dependencies
working-directory: desktop
run: npm ci
- name: Install Wine (Windows cross-compile)
run: |
sudo dpkg --add-architecture i386
sudo apt-get update -q
sudo apt-get install -y --no-install-recommends wine wine32 wine64
- name: Build Linux AppImage
working-directory: desktop
run: npx electron-builder --linux AppImage --x64 --publish never
- name: Build Windows NSIS installer
working-directory: desktop
run: npx electron-builder --win nsis --x64 --publish never
- uses: actions/upload-artifact@v3
with:
name: desktop-linux-windows-${{ github.sha }}
path: |
desktop/dist/*.AppImage
desktop/dist/*.exe
if-no-files-found: warn
retention-days: 30
# ─── Deploy (on push to master only, not PRs or tags) ───────────────────────
deploy:
name: Deploy to server
runs-on: ubuntu-latest
needs: [build-backend, build-frontend]
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main')
steps:
- name: SSH deploy
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
cd ${{ secrets.DEPLOY_PATH }}
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.necloud.us -u "${{ secrets.REGISTRY_USER }}" --password-stdin
if docker compose version > /dev/null 2>&1; then
docker compose pull backend frontend
docker compose up -d --no-build backend frontend
else
docker-compose pull backend frontend
docker-compose up -d --no-build backend frontend
fi
docker logout git.necloud.us
docker image prune -f
# ─── Release (only on v* tags) ───────────────────────────────────────────────
release:
name: Create release
runs-on: ubuntu-latest
needs: [build-desktop, build-backend, build-frontend]
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Download desktop artifacts
uses: actions/download-artifact@v3
with:
name: desktop-linux-windows-${{ github.sha }}
path: ./release-assets
- name: Publish Gitea release
env:
GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
TAG: ${{ github.ref_name }}
SHA: ${{ github.sha }}
run: |
# Create the release
RELEASE=$(curl -sf -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
"https://git.necloud.us/api/v1/repos/nate/cloudlink/releases" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"CloudLink $TAG\",\"body\":\"Docker images pushed to registry. Desktop installers attached below.\"}")
RELEASE_ID=$(echo "$RELEASE" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "Release ID: $RELEASE_ID"
# Upload each installer as a release asset
for file in ./release-assets/*; do
NAME=$(basename "$file")
echo "Uploading $NAME..."
curl -sf -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/octet-stream" \
"https://git.necloud.us/api/v1/repos/nate/cloudlink/releases/$RELEASE_ID/assets?name=$NAME" \
--data-binary @"$file"
done