Skip to content

Merge pull request #167 from krelltunez/claude/beautiful-darwin-bfnle3 #382

Merge pull request #167 from krelltunez/claude/beautiful-darwin-bfnle3

Merge pull request #167 from krelltunez/claude/beautiful-darwin-bfnle3 #382

Workflow file for this run

name: Build & Push to GHCR
on:
push:
branches: ['**']
pull_request:
release:
types: [published]
jobs:
# Runs on every push and PR to verify the image builds and passes the
# WebDAV round-trip test before anything reaches GHCR.
test:
runs-on: ubuntu-latest
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image locally
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64
load: true
tags: lifeglance:smoke
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Start containers
run: |
docker network create test-net
docker run -d --name webdav --network test-net \
-e AUTH_TYPE=Basic \
-e USERNAME=testuser \
-e PASSWORD=testpass \
bytemark/webdav
docker run -d --name lifeglance --network test-net \
-p 8080:80 lifeglance:smoke
sleep 5
- name: WebDAV round-trip
run: |
PROXY="http://localhost:8080/api/webdav-proxy"
DAV_FILE=$(python3 -c "import urllib.parse; print(urllib.parse.quote('http://webdav/testfile.bin', safe=''))")
DAV_ROOT=$(python3 -c "import urllib.parse; print(urllib.parse.quote('http://webdav/', safe=''))")
AUTH="Authorization: Basic $(printf '%s' 'testuser:testpass' | base64 -w 0)"
# 5 MB test payload
dd if=/dev/urandom bs=1M count=5 of=/tmp/payload.bin 2>/dev/null
PAYLOAD_SIZE=$(wc -c < /tmp/payload.bin)
# 1. PUT 5 MB -- expect 201 or 204
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-X PUT -H "$AUTH" -H "Content-Type: application/octet-stream" \
--data-binary @/tmp/payload.bin \
"$PROXY/?url=$DAV_FILE")
echo "PUT: $STATUS"
[ "$STATUS" = "201" ] || [ "$STATUS" = "204" ] \
|| { echo "FAIL: PUT returned $STATUS, expected 201 or 204"; docker logs lifeglance; exit 1; }
# 2. PROPFIND Depth:1 -- expect 207
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-X PROPFIND -H "$AUTH" -H "Depth: 1" \
"$PROXY/?url=$DAV_ROOT")
echo "PROPFIND: $STATUS"
[ "$STATUS" = "207" ] \
|| { echo "FAIL: PROPFIND returned $STATUS, expected 207"; docker logs lifeglance; exit 1; }
# 3. GET -- expect 200 and body size matches what was PUT
curl -s -o /tmp/got.bin -H "$AUTH" "$PROXY/?url=$DAV_FILE"
GOT_SIZE=$(wc -c < /tmp/got.bin)
echo "GET: expected ${PAYLOAD_SIZE} bytes, got ${GOT_SIZE} bytes"
[ "$GOT_SIZE" = "$PAYLOAD_SIZE" ] \
|| { echo "FAIL: body size mismatch"; docker logs lifeglance; exit 1; }
# 4. Bare /api/webdav-proxy with no ?url= -- expect 400, not 500
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$PROXY")
echo "Bare proxy: $STATUS"
[ "$STATUS" = "400" ] \
|| { echo "FAIL: bare proxy returned $STATUS, expected 400"; docker logs lifeglance; exit 1; }
- name: Cleanup
if: always()
run: |
docker rm -f lifeglance webdav || true
docker network rm test-net || true
# Runs on release only, gated on test passing.
publish-to-ghcr:
needs: test
if: github.event_name == 'release'
runs-on: ubuntu-latest
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/krelltunez/lifeglance
tags: |
type=raw,value=latest
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max