Skip to content

update logs

update logs #30

Workflow file for this run

name: Continuous Release
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
env:
DOTNET_VERSION: '9.0.x'
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
jobs:
build-and-release:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
rid: win-x64
binary_extension: .exe
- os: ubuntu-latest
rid: linux-x64
binary_extension: ""
- os: macos-latest
rid: osx-x64
binary_extension: ""
- os: macos-latest
rid: osx-arm64
binary_extension: ""
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate version info
id: version
shell: bash
run: |
# Generate a more stable version format
YEAR_SHORT=$(($(date +'%Y') - 2000))
MONTH=$((10#$(date +'%m')))
DAY=$((10#$(date +'%d')))
# Get build number from commits, but keep it reasonable
RAW_BUILD=$(git rev-list --count HEAD)
BUILD_NUMBER=$((RAW_BUILD % 10000 + 1000)) # Keep between 1000-10999
SHORT_SHA=$(git rev-parse --short=8 HEAD)
# Create semantic version (max 4 parts for .NET)
VERSION="${YEAR_SHORT}.${MONTH}.${DAY}.${BUILD_NUMBER}"
FULL_VERSION="${VERSION}-${SHORT_SHA}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "full_version=${FULL_VERSION}" >> $GITHUB_OUTPUT
echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT
echo "Generated versions:"
echo " Assembly version: ${VERSION}"
echo " Full version: ${FULL_VERSION}"
echo " Commit: ${SHORT_SHA}"
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Update version in Directory.Build.props
shell: bash
run: |
echo "Updating version information..."
# Create a new Directory.Build.props with updated versions
cat > Directory.Build.props.new << 'EOF'
<Project>
<PropertyGroup>
<Version>${{ steps.version.outputs.version }}</Version>
<AssemblyVersion>${{ steps.version.outputs.version }}</AssemblyVersion>
<FileVersion>${{ steps.version.outputs.version }}</FileVersion>
<InformationalVersion>${{ steps.version.outputs.full_version }}</InformationalVersion>
EOF
# Append the rest of the original file (skip the first few version lines)
tail -n +8 Directory.Build.props >> Directory.Build.props.new
mv Directory.Build.props.new Directory.Build.props
echo "Updated Directory.Build.props:"
head -10 Directory.Build.props
- name: Restore dependencies
run: dotnet restore TSP.sln
- name: Build native binary
shell: bash
run: |
echo "Building for ${{ matrix.rid }}..."
# Ensure output directory exists
mkdir -p artifacts
dotnet publish TravelingSalesman.ConsoleApp/TravelingSalesman.ConsoleApp.csproj \
-c Release \
-r ${{ matrix.rid }} \
--self-contained \
-p:PublishAot=true \
-p:PublishSingleFile=true \
-p:PublishTrimmed=true \
-o ./publish-${{ matrix.rid }} \
--verbosity minimal
echo "Build completed. Files in publish directory:"
ls -la ./publish-${{ matrix.rid }}/
# Create final binary name
BINARY_NAME="TSP-${{ matrix.rid }}-${{ steps.version.outputs.sha }}${{ matrix.binary_extension }}"
# Move and rename the binary
if [[ "${{ matrix.rid }}" == win-* ]]; then
mv "./publish-${{ matrix.rid }}/TravelingSalesman.ConsoleApp.exe" "./artifacts/${BINARY_NAME}"
else
mv "./publish-${{ matrix.rid }}/TravelingSalesman.ConsoleApp" "./artifacts/${BINARY_NAME}"
chmod +x "./artifacts/${BINARY_NAME}"
fi
echo "Binary created: ${BINARY_NAME}"
ls -lah ./artifacts/
- name: Test binary functionality
shell: bash
continue-on-error: true
run: |
echo "Testing binary functionality..."
cd artifacts
BINARY_NAME="TSP-${{ matrix.rid }}-${{ steps.version.outputs.sha }}${{ matrix.binary_extension }}"
if [ ! -f "$BINARY_NAME" ]; then
echo "❌ Binary not found: $BINARY_NAME"
ls -la
exit 1
fi
echo "✅ Binary exists: $BINARY_NAME ($(du -h "$BINARY_NAME" | cut -f1))"
# Test execution with timeout and error handling
echo "Testing binary execution..."
if timeout 30s sh -c "echo -e '4\n5\n' | ./'$BINARY_NAME'" > test_output.log 2>&1; then
echo "✅ Binary executed successfully"
# Check for log directory creation
if [ -d "logs" ]; then
echo "✅ Logs directory created"
if [ "$(ls -A logs 2>/dev/null)" ]; then
echo "✅ Log files created:"
ls -la logs/
echo "Sample log content (first 3 lines):"
head -3 logs/* 2>/dev/null | head -10 || echo "No readable log content"
else
echo "⚠️ Logs directory empty"
fi
else
echo "⚠️ Logs directory not created"
fi
# Show some output
echo "Test output (first 20 lines):"
head -20 test_output.log || echo "No output captured"
else
echo "⚠️ Binary test failed or timed out"
echo "Test output:"
cat test_output.log 2>/dev/null || echo "No output captured"
fi
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.rid }}
path: |
./artifacts/TSP-${{ matrix.rid }}-${{ steps.version.outputs.sha }}${{ matrix.binary_extension }}
./artifacts/logs/
./artifacts/test_output.log
if-no-files-found: warn
create-release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: build-and-release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate version info
id: version
shell: bash
run: |
# Use same logic as build job
YEAR_SHORT=$(($(date +'%Y') - 2000))
MONTH=$((10#$(date +'%m')))
DAY=$((10#$(date +'%d')))
RAW_BUILD=$(git rev-list --count HEAD)
BUILD_NUMBER=$((RAW_BUILD % 10000 + 1000))
SHORT_SHA=$(git rev-parse --short=8 HEAD)
VERSION="${YEAR_SHORT}.${MONTH}.${DAY}.${BUILD_NUMBER}"
FULL_VERSION="${VERSION}-${SHORT_SHA}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "full_version=${FULL_VERSION}" >> $GITHUB_OUTPUT
echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Debug artifact structure
run: |
echo "Downloaded artifacts structure:"
find ./artifacts -type f -ls | head -30
echo ""
echo "Looking for binaries:"
find ./artifacts -name "TSP-*" -type f -ls
- name: Prepare release assets
run: |
mkdir -p ./release-assets
# Copy all binaries
echo "Copying binaries..."
find ./artifacts -name "TSP-*" -type f \( -name "*.exe" -o ! -name "*.*" \) -exec cp -v {} ./release-assets/ \;
# Copy any log files that exist
echo "Copying log files..."
find ./artifacts -name "*.log" -type f -exec cp -v {} ./release-assets/ \; 2>/dev/null || echo "No log files found"
# Create comprehensive version info
cat > ./release-assets/version.txt << EOF
TSP Solver Release Information
============================
Version: ${{ steps.version.outputs.full_version }}
Assembly Version: ${{ steps.version.outputs.version }}
Commit: ${{ github.sha }}
Short SHA: ${{ steps.version.outputs.sha }}
Branch: ${{ github.ref_name }}
Build Date: $(date -u +'%Y-%m-%d %H:%M:%S UTC')
Build Trigger: ${{ github.event_name }}
Supported Platforms:
- Windows x64 (Native AOT)
- Linux x64 (Native AOT)
- macOS x64 (Intel, Native AOT)
- macOS ARM64 (Apple Silicon, Native AOT)
Features:
- Multiple TSP algorithms (Nearest Neighbor, 2-Opt, Simulated Annealing, Genetic Algorithm)
- Comprehensive logging with Serilog (console + file)
- Interactive and benchmark modes
- Cross-platform native AOT compilation
- Docker support
- Single-file deployment
Logging Details:
- Console output for user interaction
- Detailed file logging in logs/ directory
- Daily rotating log files (30 day retention)
- Structured logging for performance analysis
- Debug-level logging for algorithm internals
Usage Examples:
# Interactive mode
./TSP-linux-x64-${{ steps.version.outputs.sha }}
# Check version
./TSP-linux-x64-${{ steps.version.outputs.sha }} --version 2>/dev/null || echo "Run interactively"
# View logs
ls -la logs/
tail -f logs/tsp-solver-*.log
EOF
# Create checksums
echo "Creating checksums..."
cd ./release-assets
find . -name "TSP-*" -type f -exec sha256sum {} \; > checksums.txt
cd ..
echo "Release assets prepared:"
ls -la ./release-assets/
echo ""
echo "Checksums:"
cat ./release-assets/checksums.txt
- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ steps.version.outputs.full_version }}
name: TSP Solver v${{ steps.version.outputs.full_version }}
draft: false
prerelease: false
generate_release_notes: true
fail_on_unmatched_files: false
files: |
./release-assets/*
body: |
## 🚀 TSP Solver v${{ steps.version.outputs.full_version }}
**Automated Release** - Built from commit [${{ steps.version.outputs.sha }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})
### 📦 Downloads
| Platform | Download | Size |
|----------|----------|------|
| Windows x64 | [`TSP-win-x64-${{ steps.version.outputs.sha }}.exe`](../../releases/download/v${{ steps.version.outputs.full_version }}/TSP-win-x64-${{ steps.version.outputs.sha }}.exe) | Single executable |
| Linux x64 | [`TSP-linux-x64-${{ steps.version.outputs.sha }}`](../../releases/download/v${{ steps.version.outputs.full_version }}/TSP-linux-x64-${{ steps.version.outputs.sha }}) | Single executable |
| macOS Intel | [`TSP-osx-x64-${{ steps.version.outputs.sha }}`](../../releases/download/v${{ steps.version.outputs.full_version }}/TSP-osx-x64-${{ steps.version.outputs.sha }}) | Single executable |
| macOS Apple Silicon | [`TSP-osx-arm64-${{ steps.version.outputs.sha }}`](../../releases/download/v${{ steps.version.outputs.full_version }}/TSP-osx-arm64-${{ steps.version.outputs.sha }}) | Single executable |
📋 **[version.txt](../../releases/download/v${{ steps.version.outputs.full_version }}/version.txt)** - Release information
📋 **[checksums.txt](../../releases/download/v${{ steps.version.outputs.full_version }}/checksums.txt)** - SHA256 checksums
### ✨ Key Features
- 🧠 **Multiple Algorithms**: Nearest Neighbor, 2-Opt, Simulated Annealing, Genetic Algorithm
- 📊 **Comprehensive Logging**: Console + file logging with Serilog
- 🎯 **Interactive Mode**: Solve custom TSP instances with different city patterns
- 🏆 **Benchmark Mode**: Compare all algorithms performance
- 📈 **Performance Tracking**: Detailed metrics and algorithm progress reporting
- 🐳 **Docker Support**: Containerized execution environment
- ⚡ **Native AOT**: Fast startup, single-file deployment, no .NET runtime required
- 🔄 **Cross-Platform**: Windows, Linux, macOS (Intel & ARM64)
### 📋 Quick Start
```bash
# Download and run (Linux/macOS example)
wget https://github.com/kusl/tsp/releases/download/v${{ steps.version.outputs.full_version }}/TSP-linux-x64-${{ steps.version.outputs.sha }}
chmod +x TSP-linux-x64-${{ steps.version.outputs.sha }}
./TSP-linux-x64-${{ steps.version.outputs.sha }}
# Check logs after running
ls -la logs/
```
### 🔄 Recent Changes
${{ github.event.head_commit.message }}
### 📊 Algorithm Performance
| Algorithm | Best For | Time Complexity | Quality |
|-----------|----------|----------------|---------|
| Nearest Neighbor | Quick results | O(n²) | Good |
| 2-Opt | Improved solutions | O(n²) per iteration | Better |
| Simulated Annealing | Avoiding local optima | O(n) per iteration | Very Good |
| Genetic Algorithm | Large problems | O(p×g×n) | Best |
---
🔧 **Built with**: .NET 9 | Native AOT | Serilog Logging | GitHub Actions
📝 **License**: MIT | 🐛 **Issues**: [Report here](../../issues)
- name: Workflow Summary
if: always()
run: |
echo "## Release Workflow Summary" >> $GITHUB_STEP_SUMMARY
echo "- **Version**: ${{ steps.version.outputs.full_version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Commit**: ${{ steps.version.outputs.sha }}" >> $GITHUB_STEP_SUMMARY
echo "- **Release**: [v${{ steps.version.outputs.full_version }}](../../releases/tag/v${{ steps.version.outputs.full_version }})" >> $GITHUB_STEP_SUMMARY
echo "- **Assets**: $(find ./release-assets -type f | wc -l) files prepared" >> $GITHUB_STEP_SUMMARY