diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index c4696228..ab33044f 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -5,3 +5,8 @@ updates:
target-branch: "develop"
schedule:
interval: "daily"
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ target-branch: "develop"
+ schedule:
+ interval: "daily"
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 39604b70..35eb2696 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -14,15 +14,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: Cache NuGet packages
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
diff --git a/.github/workflows/nuget-publish.yml b/.github/workflows/nuget-publish.yml
index 2170b1a7..8ca70d2e 100644
--- a/.github/workflows/nuget-publish.yml
+++ b/.github/workflows/nuget-publish.yml
@@ -2,32 +2,8 @@ name: NuGet Publish
on:
push:
- branches: [ master, develop ]
+ branches: [ develop ]
tags: [ '*' ]
- workflow_dispatch:
- inputs:
- version:
- description: 'Override version (optional)'
- required: false
- type: string
- environment:
- description: 'Publish environment'
- required: false
- default: 'auto'
- type: choice
- options:
- - auto
- - staging
- - production
- create_release:
- description: 'Create GitHub release (production only)'
- required: false
- type: boolean
- default: false
- release_notes:
- description: 'Release notes'
- required: false
- type: string
env:
DOTNET_VERSION: 10.0.x
@@ -45,17 +21,17 @@ jobs:
create-release: ${{ steps.setup.outputs.create-release }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Cache NuGet packages
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
@@ -134,11 +110,6 @@ jobs:
environment = 'production';
// Create GitHub release for all tags
createRelease = true;
- } else if (ref === 'refs/heads/master') {
- // master branch builds (preview versions)
- version = `${baseVersion}-preview-${context.runNumber}`;
- environment = 'staging';
- shouldPublish = false; // Don't auto-publish from master
}
}
@@ -185,7 +156,7 @@ jobs:
ls -la ./artifacts/ || echo "No artifacts found"
- name: Upload artifacts
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v6
if: steps.setup.outputs.should-publish == 'true'
with:
name: nuget-packages-${{ steps.setup.outputs.version }}
@@ -202,13 +173,13 @@ jobs:
steps:
- name: Download artifacts
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v7
with:
name: nuget-packages-${{ needs.build.outputs.version }}
path: ./artifacts
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
@@ -243,7 +214,7 @@ jobs:
- name: Upload release assets
if: needs.build.outputs.create-release == 'true'
- uses: actions/github-script@v7
+ uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
diff --git a/Netorrent.Example/Netorrent.Example.csproj b/Netorrent.Example/Netorrent.Example.csproj
index 7eec74b7..b1b8ab9c 100644
--- a/Netorrent.Example/Netorrent.Example.csproj
+++ b/Netorrent.Example/Netorrent.Example.csproj
@@ -7,8 +7,8 @@
enable
-
-
+
+
diff --git a/Netorrent.Tests.Integration/Fixtures/OpenTrackerFixture.cs b/Netorrent.Tests.Integration/Fixtures/OpenTrackerFixture.cs
index 4985b450..1fa8e10b 100644
--- a/Netorrent.Tests.Integration/Fixtures/OpenTrackerFixture.cs
+++ b/Netorrent.Tests.Integration/Fixtures/OpenTrackerFixture.cs
@@ -14,8 +14,7 @@ public class OpenTrackerFixture : IAsyncInitializer, IAsyncDisposable
public async Task InitializeAsync()
{
- _container = new ContainerBuilder()
- .WithImage("xbank/opentracker-docker")
+ _container = new ContainerBuilder("xbank/opentracker-docker")
.WithName("opentracker-test")
.WithPortBinding("6969/tcp", true)
.WithPortBinding("6969/udp", true)
diff --git a/Netorrent.Tests.Integration/Netorrent.Tests.Integration.csproj b/Netorrent.Tests.Integration/Netorrent.Tests.Integration.csproj
index e182a278..324ffe13 100644
--- a/Netorrent.Tests.Integration/Netorrent.Tests.Integration.csproj
+++ b/Netorrent.Tests.Integration/Netorrent.Tests.Integration.csproj
@@ -7,7 +7,7 @@
true
-
+
diff --git a/Netorrent.Tests/Netorrent.Tests.csproj b/Netorrent.Tests/Netorrent.Tests.csproj
index cfb17590..77b9f44d 100644
--- a/Netorrent.Tests/Netorrent.Tests.csproj
+++ b/Netorrent.Tests/Netorrent.Tests.csproj
@@ -11,12 +11,12 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/Netorrent/IO/MessageStream.cs b/Netorrent/IO/MessageStream.cs
index 6f18dea7..f7460839 100644
--- a/Netorrent/IO/MessageStream.cs
+++ b/Netorrent/IO/MessageStream.cs
@@ -9,10 +9,10 @@ namespace Netorrent.IO;
internal class MessageStream(Stream stream, Handshake handshake, TimeSpan timeout) : IMessageStream
{
private readonly Channel _incomingMessages = Channel.CreateBounded(
- new BoundedChannelOptions(512) { SingleWriter = true, SingleReader = true }
+ new BoundedChannelOptions(128) { SingleWriter = true, SingleReader = true }
);
private readonly Channel _outgoingMessages = Channel.CreateBounded(
- new BoundedChannelOptions(512) { SingleWriter = false, SingleReader = true }
+ new BoundedChannelOptions(128) { SingleWriter = false, SingleReader = true }
);
public Handshake Handshake => handshake;
diff --git a/Netorrent/Netorrent.csproj b/Netorrent/Netorrent.csproj
index 42685cd2..d4b6206c 100644
--- a/Netorrent/Netorrent.csproj
+++ b/Netorrent/Netorrent.csproj
@@ -25,11 +25,11 @@
CS8600;CS8602;CS8603;CS8604;CS8618;CS8625
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/Netorrent/P2P/Download/RequestScheduler.cs b/Netorrent/P2P/Download/RequestScheduler.cs
index cdc384aa..d032d7d6 100644
--- a/Netorrent/P2P/Download/RequestScheduler.cs
+++ b/Netorrent/P2P/Download/RequestScheduler.cs
@@ -22,7 +22,7 @@ ILogger logger
private readonly Channel _downloadMessageChannel =
Channel.CreateBounded(
- new BoundedChannelOptions(512) { SingleWriter = false, SingleReader = true }
+ new BoundedChannelOptions(128) { SingleWriter = false, SingleReader = true }
);
private static readonly DownloadMessage.CheckTimeoutMessage _timeoutMessage = new();
diff --git a/Netorrent/P2P/PeerConnection.cs b/Netorrent/P2P/PeerConnection.cs
index 0eaf2122..fb4c6136 100644
--- a/Netorrent/P2P/PeerConnection.cs
+++ b/Netorrent/P2P/PeerConnection.cs
@@ -167,13 +167,13 @@ private async Task RunAsync(CancellationTokenSource cancellationTokenSource)
await SendBitfieldAsync(MyBitField, cancellationTokenSource.Token).ConfigureAwait(false);
await using var downloadTimer = DownloadTracker
- .StartSampling(500.Milliseconds)
+ .StartSampling(100.Milliseconds)
.ConfigureAwait(false);
await using var uploadTimer = UploadTracker
- .StartSampling(500.Milliseconds)
+ .StartSampling(100.Milliseconds)
.ConfigureAwait(false);
await using var requestWindowTimer = PeerRequestWindow
- .StartSampling(500.Milliseconds, DownloadTracker)
+ .StartSampling(100.Milliseconds, DownloadTracker)
.ConfigureAwait(false);
try
diff --git a/Netorrent/P2P/PeersClient.cs b/Netorrent/P2P/PeersClient.cs
index d8631544..c6f43bbe 100644
--- a/Netorrent/P2P/PeersClient.cs
+++ b/Netorrent/P2P/PeersClient.cs
@@ -27,7 +27,7 @@ ILogger logger
private readonly Subject _peerConnected = new();
private readonly Channel _peerConnections =
Channel.CreateBounded(
- new BoundedChannelOptions(100) { SingleReader = true, SingleWriter = false }
+ new BoundedChannelOptions(128) { SingleReader = true, SingleWriter = false }
);
public PeerId PeerId => peerId;
diff --git a/Netorrent/P2P/Upload/UploadScheduler.cs b/Netorrent/P2P/Upload/UploadScheduler.cs
index 13f7561e..53dbe5eb 100644
--- a/Netorrent/P2P/Upload/UploadScheduler.cs
+++ b/Netorrent/P2P/Upload/UploadScheduler.cs
@@ -23,7 +23,7 @@ ILogger logger
private readonly Channel _uploadMessagesChannel =
Channel.CreateBounded(
- new BoundedChannelOptions(256) { SingleWriter = false, SingleReader = true }
+ new BoundedChannelOptions(128) { SingleWriter = false, SingleReader = true }
);
private static readonly UploadMessage.CheckRoundMessage _checkRoundMessage = new();
diff --git a/Netorrent/TorrentFile/Torrent.cs b/Netorrent/TorrentFile/Torrent.cs
index 7eb1d84b..27914151 100644
--- a/Netorrent/TorrentFile/Torrent.cs
+++ b/Netorrent/TorrentFile/Torrent.cs
@@ -54,7 +54,7 @@ IReadOnlySet downloadedPieces
var files = metaInfo.Info.NormalizedFiles;
var totalSize = files.Sum(i => i.Length);
var trackersChannel = Channel.CreateBounded(
- new BoundedChannelOptions(100) { SingleWriter = false, SingleReader = true }
+ new BoundedChannelOptions(128) { SingleWriter = false, SingleReader = true }
);
MetaInfo = metaInfo;
diff --git a/README.md b/README.md
index ecae42b4..518df0c9 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Netorrent
-A high-performance, async-first .NET 10.0 BitTorrent client library for downloading and seeding torrents.
+A async-first .NET 10.0 BitTorrent client library for downloading and seeding torrents.
## Installation
@@ -56,9 +56,10 @@ await using var client = new TorrentClient();
await using var torrent = await client.LoadTorrentAsync("file.torrent", "output");
await torrent.StartAsync();
+var completionTask = torrent.Completion.AsTask();
// Monitor detailed statistics
-while (!torrent.Completion.IsCompleted)
+while (!completionTask.IsCompleted)
{
var data = torrent.Statistics.Data;
var peers = torrent.Statistics.Peers;
@@ -72,6 +73,8 @@ while (!torrent.Completion.IsCompleted)
await Task.Delay(1000);
}
+
+await completionTask;
```
### Advanced Configuration
@@ -160,40 +163,6 @@ The library is designed with async-first architecture for optimal performance:
- **Installation**: `dotnet add package Netorrent --version 1.0.0-nightly-*`
- **Warning**: May contain breaking changes or bugs
-### 🚀 Preview Releases
-- **Purpose**: Pre-release testing of upcoming features
-- **Versioning**: Pre-release suffix (e.g., `1.0.0-preview-123`)
-- **Updates**: Periodic builds from master branch
-- **Installation**: `dotnet add package Netorrent --prerelease`
-
-### Version Selection Strategies
-
-**For Production Applications:**
-```xml
-
-```
-
-**For Testing Latest Features:**
-```xml
-
-```
-
-**For Early Adopters:**
-```xml
-
-```
-
-## CI/CD Integration
-
-The project uses GitHub Actions for automated publishing:
-
-- **Per-commit nightly builds** from `develop` branch
-- **Release builds** from git tags
-- **Manual publishing** for custom versions
-- **Comprehensive testing** before all publications
-
-See [`.github/workflows/`](.github/workflows/) for complete workflow configurations.
-
## Features
- [x] **Torrent files** - Complete .torrent file support
diff --git a/docs/NuGet-Publishing.md b/docs/NuGet-Publishing.md
deleted file mode 100644
index 75d5aa71..00000000
--- a/docs/NuGet-Publishing.md
+++ /dev/null
@@ -1,289 +0,0 @@
-# NuGet Publishing Setup Guide
-
-This guide explains how the Netorrent library uses GitHub Actions to publish packages to NuGet with both nightly and stable releases.
-
-## Overview
-
-The project implements a dual-feed publishing strategy:
-- **Nightly builds**: Per-commit packages from `develop` branch
-- **Stable releases**: Versioned packages from git tags
-
-## Required Setup
-
-### 1. GitHub Secrets
-
-Add these secrets to your GitHub repository:
-
-#### `NUGET_API_KEY`
-- **Purpose**: Authenticate with NuGet.org for publishing
-- **How to get**:
- 1. Go to [nuget.org](https://www.nuget.org/)
- 2. Sign in with your Microsoft account
- 3. Go to Account > API Keys
- 4. Create a new API key with `Push` scope
- 5. Set the glob pattern to `Netorrent.*` (or leave blank for all packages)
- 6. Copy the generated key
-
-### 2. Environment Protection Rules
-
-Configure these environments in GitHub repository settings:
-
-#### `nightly` Environment
-- **Purpose**: Protect nightly package publishing
-- **Protection rules**:
- - No reviewers required (for rapid deployment)
- - Wait timer: 0 minutes
-
-#### `production` Environment
-- **Purpose**: Protect stable release publishing
-- **Protection rules**:
- - Require reviewers (1-2 reviewers recommended)
- - Wait timer: 5 minutes (optional)
- - Prevent self-approval
-
-## Workflow Triggers
-
-### Automatic Triggers
-
-#### Nightly Builds (Per-Commit)
-- **Trigger**: Every push to `develop` branch
-- **Version**: `1.0.0-nightly-YYYYMMDD-HHMM-commit`
-- **Package Type**: Pre-release
-- **Symbol Packages**: No
-- **Retention**: 30 days
-
-#### Release Builds
-- **Trigger**: Git tags matching `v*` (e.g., `v1.0.0`, `v1.1.0`)
-- **Version**: From git tag
-- **Package Type**: Stable
-- **Symbol Packages**: Yes
-- **GitHub Release**: Created automatically
-
-### Manual Triggers
-
-#### Manual Publishing Workflow
-- **Trigger**: Workflow dispatch from GitHub Actions tab
-- **Options**:
- - Custom version specification
- - Environment selection (staging/production)
- - Optional GitHub release creation
- - Custom release notes
-
-## Version Strategy
-
-### Nightly Version Format
-```
-1.0.0-nightly-20250114-1430-a1b2c3d
-│ │ │ │ │
-│ │ │ │ └─ Short commit SHA
-│ │ │ └─────── Timestamp (HHMM)
-│ │ └───────────── Date (YYYYMMDD)
-│ └───────────────────── Base version
-└───────────────────────── Nightly identifier
-```
-
-### Release Version Format
-```
-1.2.3
-│ │ │
-│ │ └─ Patch: Bug fixes
-│ └─── Minor: New features (backward compatible)
-└───── Major: Breaking changes
-```
-
-## Configuration Files
-
-### Main Workflow: `.github/workflows/nuget-publish.yml`
-
-Key features:
-- Smart version detection based on trigger type
-- Comprehensive testing before publishing
-- Conditional symbol package inclusion
-- Artifact management with retention policies
-- GitHub release automation
-
-### Manual Workflow: `.github/workflows/manual-publish.yml`
-
-Key features:
-- Version format validation
-- Environment-specific publishing
-- Optional GitHub release creation
-- Release artifact attachment
-
-### CI Workflow: `.github/workflows/dotnet.yml`
-
-Updated to avoid conflicts with publishing workflows:
-- Limited to main and develop branches
-- Added package caching
-- Code coverage collection
-- Artifact upload for debugging
-
-## Publishing Process
-
-### 1. Development Flow
-
-```bash
-# Create feature branch
-git checkout -b feature/new-feature
-# Make changes...
-git commit -m "Add new feature"
-git push origin feature/new-feature
-# Create PR to develop
-# Merge to develop
-# → Automatic nightly build triggered
-```
-
-### 2. Release Flow
-
-```bash
-# Ensure develop is stable
-git checkout develop
-git pull origin develop
-
-# Create release branch
-git checkout -b release/v1.0.0
-
-# Update version in project file if needed
-# Commit version changes
-git commit -m "Bump version to 1.0.0"
-git push origin release/v1.0.0
-
-# Merge to main
-git checkout main
-git merge release/v1.0.0
-git push origin main
-
-# Create and push tag
-git tag v1.0.0
-git push origin v1.0.0
-# → Automatic release build triggered
-```
-
-### 3. Manual Publishing
-
-1. Go to GitHub Actions tab
-2. Select "Manual NuGet Publish" workflow
-3. Click "Run workflow"
-4. Fill in parameters:
- - Version: `1.0.0`, `1.0.0-preview-123`, or `1.0.0-nightly-custom`
- - Environment: `staging` or `production`
- - Create Release: Optional for production releases
-5. Click "Run workflow"
-
-## Consumer Usage
-
-### Stable Installation
-```xml
-
-```
-
-### Range Installation
-```xml
-
-```
-
-### Nightly Installation
-```xml
-
-```
-
-### Pre-release Installation
-```bash
-dotnet add package Netorrent --prerelease
-```
-
-## Troubleshooting
-
-### Common Issues
-
-#### 1. Package Already Exists
-- **Cause**: Version already published
-- **Solution**: Use `--skip-duplicate` flag (already configured)
-
-#### 2. API Key Invalid
-- **Cause**: Expired or incorrect API key
-- **Solution**: Regenerate API key and update GitHub secrets
-
-#### 3. Version Format Error
-- **Cause**: Invalid semantic version format
-- **Solution**: Ensure version follows `X.Y.Z[-suffix]` format
-
-#### 4. Tests Failed
-- **Cause**: Breaking changes introduced
-- **Solution**: Fix test failures before publishing
-
-### Debugging
-
-#### Workflow Logs
-- Check GitHub Actions workflow runs
-- Review build and test logs
-- Verify package creation steps
-
-#### Package Verification
-```bash
-# Download and inspect package
-dotnet nuget push --source ./local-feed package.nupkg
-
-# Verify package contents
-dotnet nuget locals --list all
-```
-
-## Best Practices
-
-### 1. Version Management
-- Follow semantic versioning
-- Update version numbers for breaking changes
-- Use consistent version formatting
-
-### 2. Testing
-- Ensure all tests pass before publishing
-- Maintain code coverage
-- Test package installation in clean environment
-
-### 3. Release Notes
-- Provide meaningful release notes
-- Document breaking changes
-- Include migration guides for major versions
-
-### 4. Security
-- Keep API keys secure
-- Use environment protection rules
-- Regularly rotate API keys
-
-### 5. Monitoring
-- Monitor package download statistics
-- Set up alerts for publishing failures
-- Track consumer feedback
-
-## Advanced Configuration
-
-### Multiple Package Feeds
-
-For organizations requiring separate feeds:
-
-```yaml
-# Custom feed configuration
-NIGHTLY_FEED: https://api.nuget.org/v3/index.json
-STABLE_FEED: https://api.nuget.org/v3/index.json
-PRIVATE_FEED: https://pkgs.dev.azure.com/yourorg/_packaging/yourfeed/nuget/v3/index.json
-```
-
-### Conditional Publishing
-
-```yaml
-# Only publish on specific conditions
-- if: github.actor == 'dependabot[bot]'
- run: echo "Skipping publishing for dependabot updates"
-```
-
-### Package Validation
-
-```yaml
-# Additional validation steps
-- name: Validate package
- run: |
- dotnet nuget verify artifacts/*.nupkg
- dotnet nuget verify artifacts/*.snupkg
-```
-
-This setup provides a robust, automated NuGet publishing pipeline that supports both rapid development cycles through nightly builds and stable releases for production use.
\ No newline at end of file