Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2f24b67
Try to reconcile dev with CI and fix tests finally
Menelion Jan 9, 2026
bcd19cf
Fix CS
Menelion Jan 9, 2026
4f01060
Try fixing workflow
Menelion Jan 10, 2026
0bf957f
More fixes
Menelion Jan 10, 2026
43dbcfa
Meow
Menelion Jan 10, 2026
28a8b91
Meow2
Menelion Jan 10, 2026
4f2d803
Meow3
Menelion Jan 10, 2026
169c2ac
Meow4
Menelion Jan 10, 2026
dea54a0
Meow5
Menelion Jan 10, 2026
3884a98
meow6
Menelion Jan 10, 2026
48292a4
meow7
Menelion Jan 10, 2026
9228538
Meow8
Menelion Jan 10, 2026
2b65c4c
Meow9
Menelion Jan 10, 2026
eab817c
meow11
Menelion Jan 11, 2026
e3f8056
Meow12
Menelion Jan 11, 2026
246e690
meow13
Menelion Jan 11, 2026
f0c36f6
meow14
Menelion Jan 11, 2026
a88bdf8
Meow10
Menelion Jan 11, 2026
5da755c
meow15
Menelion Jan 11, 2026
9d0fc0f
meow16
Menelion Jan 12, 2026
8d980cc
meow17
Menelion Jan 12, 2026
ae559c6
meow18
Menelion Jan 12, 2026
71aa2ab
meow19
Menelion Jan 12, 2026
3435de6
meow20
Menelion Jan 12, 2026
92cf240
meow21
Menelion Jan 12, 2026
2e0f00a
meow22
Menelion Jan 12, 2026
8f44cd0
meow23
Menelion Jan 12, 2026
64b5d64
meow23
Menelion Jan 12, 2026
677a369
meow24
Menelion Jan 13, 2026
3a2dd13
meow25
Menelion Jan 13, 2026
734b824
meow26
Menelion Jan 13, 2026
26b200c
meow27
Menelion Jan 13, 2026
7c0a42d
Fix SFTP test failures in chrooted environments (#33)
Copilot Jan 13, 2026
1cb4f34
Fix whitespace formatting in SftpStorageTests.cs (#34)
Copilot Jan 13, 2026
e3b43bf
Fix SFTP integration tests by configuring writable chroot directory (…
Copilot Jan 13, 2026
3f50dc8
Fix WebDAV GetRelativePath to handle full URLs from server responses …
Copilot Jan 14, 2026
c79053d
Fix CS
Menelion Jan 14, 2026
108945c
Fix WebDAV CreateDirectoryAsync to ensure root path exists before cre…
Menelion Jan 14, 2026
ede6f3d
Remove garbage
Menelion Jan 14, 2026
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
307 changes: 190 additions & 117 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -1,117 +1,190 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest

services:
sftp:
image: atmoz/sftp:latest
ports:
- 2222:22
options: >-
--health-cmd "pgrep sshd"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
SFTP_USERS: testuser:testpass:1001:100:upload

ftp:
image: fauria/vsftpd:latest
ports:
- 21:21
- 21000-21010:21000-21010
options: >-
--health-cmd "pgrep vsftpd"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
FTP_USER: testuser
FTP_PASS: testpass
PASV_ADDRESS: localhost
PASV_MIN_PORT: 21000
PASV_MAX_PORT: 21010

localstack:
image: localstack/localstack:latest
ports:
- 4566:4566
options: >-
--health-cmd "curl -f http://localhost:4566/_localstack/health || exit 1"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
SERVICES: s3
DEBUG: 0
EDGE_PORT: 4566


steps:
- uses: actions/checkout@v6

- name: Start WebDAV server
run: |
echo "=== Starting WebDAV server ==="
docker run -d --name webdav-server -p 8080:8080 \
eclipse-temurin:11-jre bash -c "
apt-get update && apt-get install -y curl wget &&
wget -O webdav-server.jar https://repo1.maven.org/maven2/io/github/atetzner/webdav-embedded-server/0.2.1/webdav-embedded-server-0.2.1.jar &&
mkdir -p /webdav &&
java -jar webdav-server.jar --port 8080 --directory /webdav
"

- name: Wait for services to be ready
run: |
echo "=== Waiting for services to be ready ==="
sleep 15
echo "=== Testing WebDAV server ==="
curl -f http://localhost:8080/ || echo "WebDAV not ready yet, continuing..."

- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Check format
run: dotnet format --verify-no-changes
- name: Build
run: dotnet build --no-restore
- name: Create S3 test bucket
run: |
docker exec $(docker ps -q -f ancestor=localstack/localstack:latest) awslocal s3 mb s3://test-bucket
- name: Test
run: dotnet test --no-build --verbosity normal
env:
SFTP_TEST_HOST: localhost
SFTP_TEST_PORT: 2222
SFTP_TEST_USER: testuser
SFTP_TEST_PASS: testpass
SFTP_TEST_ROOT: "upload"
FTP_TEST_HOST: localhost
FTP_TEST_PORT: 21
FTP_TEST_USER: testuser
FTP_TEST_PASS: testpass
FTP_TEST_ROOT: ""
S3_TEST_BUCKET: test-bucket
S3_TEST_ACCESS_KEY: test
S3_TEST_SECRET_KEY: test
S3_TEST_ENDPOINT: http://localhost:4566
S3_TEST_PREFIX: sharpsync-tests
WEBDAV_TEST_URL: http://localhost:8080/
WEBDAV_TEST_USER: ""
WEBDAV_TEST_PASS: ""
WEBDAV_TEST_ROOT: ""
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Cleanup previous test services
run: |
echo "=== Cleaning up any previous test services ==="
docker compose -f docker-compose.test.yml down -v --remove-orphans || true
sudo rm -rf /tmp/localstack || true
echo "=== Removing stale Docker volumes ==="
docker volume rm sharp-sync_sftp-data || true
docker volume rm sharp-sync_ftp-data || true
docker volume rm sharp-sync_webdav-data || true

- name: Start test services
run: |
echo "=== Starting test services with docker-compose ==="
docker compose -f docker-compose.test.yml up -d

- name: Wait for services to be ready
run: |
echo "=== Waiting for services to be healthy ==="
docker compose -f docker-compose.test.yml ps

echo "=== Waiting for SFTP server ==="
for i in {1..18}; do
nc -z localhost 2222 && echo "SFTP ready" && break
echo "SFTP not ready, retrying in 5 seconds... ($i/18)"
sleep 5
done

echo "=== Waiting for FTP server ==="
for i in {1..18}; do
nc -z localhost 21 && echo "FTP ready" && break
echo "FTP not ready, retrying in 5 seconds... ($i/18)"
sleep 5
done

echo "=== Waiting for LocalStack ==="
for i in {1..30}; do
curl -sf http://localhost:4566/_localstack/health && echo "LocalStack ready" && break
echo "LocalStack not ready, retrying in 10 seconds... ($i/30)"
sleep 10
done

echo "=== Waiting for WebDAV server ==="
WEBDAV_BASIC_READY=false
for i in {1..30}; do
if curl -sf -u testuser:testpass http://localhost:8080/ > /dev/null 2>&1; then
echo "WebDAV responding to basic requests"
WEBDAV_BASIC_READY=true
break
fi
echo "WebDAV not responding, retrying in 5 seconds... ($i/30)"
sleep 5
done

if [ "$WEBDAV_BASIC_READY" = "false" ]; then
echo "ERROR: WebDAV server not responding after 30 attempts"
docker compose -f docker-compose.test.yml logs webdav
exit 1
fi

echo "=== Checking WebDAV full functionality (MKCOL) ==="
WEBDAV_FULLY_READY=false
for i in {1..40}; do
# Show verbose output for debugging
echo "Attempt $i: Testing MKCOL operation..."
MKCOL_RESULT=$(curl -s -w "%{http_code}" -u testuser:testpass -X MKCOL http://localhost:8080/_health-check-dir/ -o /dev/null 2>&1)
echo "MKCOL response code: $MKCOL_RESULT"

if [ "$MKCOL_RESULT" = "201" ] || [ "$MKCOL_RESULT" = "405" ]; then
echo "WebDAV is fully operational (MKCOL working)"
# Cleanup test directory
curl -sf -u testuser:testpass -X DELETE http://localhost:8080/_health-check-dir/ > /dev/null 2>&1 || true
WEBDAV_FULLY_READY=true
break
fi

# Show container status and logs on failures
if [ $((i % 5)) -eq 0 ]; then
echo "--- WebDAV container status ---"
docker compose -f docker-compose.test.yml ps webdav
echo "--- Recent WebDAV logs ---"
docker compose -f docker-compose.test.yml logs --tail=10 webdav
fi

echo "MKCOL not working yet, retrying in 5 seconds..."
sleep 5
done

if [ "$WEBDAV_FULLY_READY" = "false" ]; then
echo "ERROR: WebDAV MKCOL not working after 40 attempts"
echo "=== Full WebDAV logs ==="
docker compose -f docker-compose.test.yml logs webdav
exit 1
fi

echo "=== Final service status ==="
docker compose -f docker-compose.test.yml ps

- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Check format
run: dotnet format --verify-no-changes
- name: Build
run: dotnet build --no-restore
- name: Create S3 test bucket
run: |
docker exec sharp-sync-localstack-1 awslocal s3 mb s3://test-bucket

- name: Debug WebDAV setup
run: |
echo "=== WebDAV Container Status ==="
docker compose -f docker-compose.test.yml ps webdav
echo ""
echo "=== WebDAV Container Logs ==="
docker compose -f docker-compose.test.yml logs webdav
echo ""
echo "=== Testing WebDAV Operations ==="
echo "PROPFIND (list root):"
curl -s -w "\nHTTP Status: %{http_code}\n" -u testuser:testpass -X PROPFIND http://localhost:8080/ -H "Depth: 1" | head -30
echo ""
echo "PUT (write test):"
echo "test content" | curl -s -w "\nHTTP Status: %{http_code}\n" -u testuser:testpass -X PUT http://localhost:8080/_debug-test.txt -d @-
echo ""
echo "DELETE (cleanup):"
curl -s -w "\nHTTP Status: %{http_code}\n" -u testuser:testpass -X DELETE http://localhost:8080/_debug-test.txt

- name: Prepare WebDAV test root
run: |
echo "=== Creating WebDAV test root directory ==="
# Delete existing test root if present
curl -sf -u testuser:testpass -X DELETE http://localhost:8080/ci-root/ --output /dev/null 2>&1 || true
# Create fresh test root
curl -sf -u testuser:testpass -X MKCOL http://localhost:8080/ci-root/
echo "WebDAV test root created successfully"

- name: Test
run: dotnet test --no-build --verbosity normal
env:
SFTP_TEST_HOST: localhost
SFTP_TEST_PORT: 2222
SFTP_TEST_USER: testuser
SFTP_TEST_PASS: testpass
SFTP_TEST_ROOT: upload
FTP_TEST_HOST: localhost
FTP_TEST_PORT: 21
FTP_TEST_USER: testuser
FTP_TEST_PASS: testpass
FTP_TEST_ROOT: ""
S3_TEST_BUCKET: test-bucket
S3_TEST_ACCESS_KEY: test
S3_TEST_SECRET_KEY: test
S3_TEST_ENDPOINT: http://localhost:4566
S3_TEST_PREFIX: sharpsync-tests
WEBDAV_TEST_URL: http://localhost:8080/
WEBDAV_TEST_USER: testuser
WEBDAV_TEST_PASS: testpass
WEBDAV_TEST_ROOT: "ci-root"

- name: Dump container logs
if: failure()
run: |
echo "=== Container logs for debugging ==="
docker compose -f docker-compose.test.yml logs

- name: Stop test services
if: always()
run: |
docker compose -f docker-compose.test.yml down -v --remove-orphans || true
Loading