Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
116 changes: 116 additions & 0 deletions .github/scripts/build-and-pack-nuget.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/bin/bash
set -e

# Script to build and pack NuGet packages in dependency order
# Usage: ./build-and-pack-nuget.sh

# Get all packable projects from the solution filter
# Extract project paths from the solution filter and convert Windows paths to Unix paths
PROJECTS=$(jq -r '.solution.projects[]' War3NetPublish.slnf | sed 's/\\/\//g' | grep -v "Tests" | tr '\n' ';')

echo "=== Found projects to publish ==="
echo "$PROJECTS" | tr ';' '\n'
echo "=================================="

# Create a temporary file to track which projects have been built
# Using semicolon delimiters for exact matching
BUILT_PROJECTS=";"

# Function to check if all dependencies of a project are built
can_build_project() {
local project=$1
# Get the dependencies - dotnet list outputs them with paths like ..\ProjectName\ProjectName.csproj
# We need to extract just the project name from the filename
local deps=$(dotnet list "$project" reference 2>/dev/null | grep '\.csproj$' | while read -r line; do
# Remove everything up to the last backslash, then remove .csproj extension
echo "$line" | sed 's/.*\\//' | sed 's/\.csproj$//'
done | tr '\n' ' ')

for dep in $deps; do
if ! echo "$BUILT_PROJECTS" | grep -q ";$dep;"; then
return 1
fi
done
return 0
}

# Build projects in dependency order
REMAINING_PROJECTS="$PROJECTS"
ITERATION=0
MAX_ITERATIONS=20

while [ -n "$REMAINING_PROJECTS" ] && [ $ITERATION -lt $MAX_ITERATIONS ]; do
ITERATION=$((ITERATION + 1))

PROJECTS_TO_BUILD=""
STILL_REMAINING=""

# Process each project using semicolon as delimiter
while IFS= read -r project; do
if [ -n "$project" ]; then
if can_build_project "$project"; then
PROJECTS_TO_BUILD="${PROJECTS_TO_BUILD}${project};"
else
STILL_REMAINING="${STILL_REMAINING}${project};"
fi
fi
done < <(echo "$REMAINING_PROJECTS" | tr ';' '\n')

if [ -z "$PROJECTS_TO_BUILD" ] && [ -n "$STILL_REMAINING" ]; then
echo ""
echo "ERROR: Circular dependency detected or unable to resolve dependencies"
echo "Projects that cannot be built:"
echo "$STILL_REMAINING" | tr ';' '\n' | while read -r p; do
if [ -n "$p" ]; then
echo " - $(basename $(dirname "$p"))"
echo " Dependencies: $(dotnet list "$p" reference 2>/dev/null | grep -E "^\s+.*\.csproj" | sed 's/.*\///' | sed 's/\.csproj.*//' | tr '\n' ' ')"
fi
done
echo "Already built: $BUILT_PROJECTS"
exit 1
fi

echo ""
echo "Projects to build in iteration $ITERATION:"
if [ -n "$PROJECTS_TO_BUILD" ]; then
OLD_IFS="$IFS"
IFS=';'
for p in $PROJECTS_TO_BUILD; do
[ -n "$p" ] && echo " - $(basename $(dirname "$p"))"
done
IFS="$OLD_IFS"
else
echo " (none)"
fi

# Build and pack projects that are ready
while IFS= read -r project; do
if [ -z "$project" ]; then continue; fi
PROJECT_NAME=$(basename $(dirname "$project"))
echo "Building $PROJECT_NAME..."

# Restore with local feed for dependencies from previous iterations
dotnet restore "$project" -p:Configuration=Release --verbosity minimal --force --no-cache

# Build the project
dotnet build "$project" --configuration Release --no-restore --verbosity minimal

# Pack directly to artifacts with project name folder structure for proper NuGet feed
dotnet pack "$project" --configuration Release --no-build --output "./artifacts/${PROJECT_NAME}" -p:PACK=true --verbosity minimal

BUILT_PROJECTS="${BUILT_PROJECTS}${PROJECT_NAME};"
done < <(echo "$PROJECTS_TO_BUILD" | tr ';' '\n')

# Clear NuGet cache for local packages to ensure newly built packages are available
dotnet nuget locals temp -c

REMAINING_PROJECTS="$STILL_REMAINING"
done

if [ $ITERATION -eq $MAX_ITERATIONS ]; then
echo "Error: Maximum iterations reached. Possible circular dependency."
exit 1
fi

echo ""
echo "Successfully created $(ls ./artifacts/*/*.nupkg 2>/dev/null | wc -l) packages"
33 changes: 33 additions & 0 deletions .github/workflows/pack-nuget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Pack NuGet Packages

on:
pull_request:
branches: ['master']
workflow_dispatch:

env:
DOTNET_VERSION: '8.0.x'
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: true

jobs:
build-and-pack:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Build and pack in dependency order
run: |
chmod +x .github/scripts/build-and-pack-nuget.sh
.github/scripts/build-and-pack-nuget.sh
40 changes: 40 additions & 0 deletions .github/workflows/publish-nuget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish NuGet Packages

on:
workflow_dispatch:

env:
DOTNET_VERSION: '8.0.x'
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: true

jobs:
build-and-publish:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Build and pack in dependency order
run: |
chmod +x .github/scripts/build-and-pack-nuget.sh
.github/scripts/build-and-pack-nuget.sh

- name: Push all packages to NuGet
run: |
dotnet nuget push "./artifacts/*/*.nupkg" \
--api-key $NUGET_API_KEY \
--source https://api.nuget.org/v3/index.json \
--skip-duplicate
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
32 changes: 32 additions & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="local-feed" value="./artifacts" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="local-feed">
<package pattern="War3Net.*" />
</packageSource>
<packageSource key="nuget.org">
<package pattern="Cake.Common" />
<package pattern="Cake.Core" />
<package pattern="Cake.Incubator" />
<package pattern="DotNetZip" />
<package pattern="ICSharpCode.Decompiler" />
<package pattern="JpegLibrary" />
<package pattern="Pidgin" />
<package pattern="NETStandard.Library" />
<package pattern="Newtonsoft.Json" />
<package pattern="runtime.native.System" />
<package pattern="StyleCop.Analyzers" />
<package pattern="StyleCop.Analyzers.Unstable" />

<!-- Wildcards -->
<package pattern="Microsoft.*" />
<package pattern="NuGet.*" />
<package pattern="System.*" />
</packageSource>
</packageSourceMapping>
</configuration>
20 changes: 20 additions & 0 deletions War3NetPublish.slnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"solution": {
"path": "War3Net.sln",
"projects": [
"src\\War3Net.Build.Core\\War3Net.Build.Core.csproj",
"src\\War3Net.Build\\War3Net.Build.csproj",
"src\\War3Net.CodeAnalysis.Decompilers\\War3Net.CodeAnalysis.Decompilers.csproj",
"src\\War3Net.CodeAnalysis.Jass\\War3Net.CodeAnalysis.Jass.csproj",
"src\\War3Net.CodeAnalysis.Transpilers\\War3Net.CodeAnalysis.Transpilers.csproj",
"src\\War3Net.CodeAnalysis\\War3Net.CodeAnalysis.csproj",
"src\\War3Net.Common\\War3Net.Common.csproj",
"src\\War3Net.Drawing.Blp\\War3Net.Drawing.Blp.csproj",
"src\\War3Net.IO.Compression\\War3Net.IO.Compression.csproj",
"src\\War3Net.IO.Mpq\\War3Net.IO.Mpq.csproj",
"src\\War3Net.IO.Slk\\War3Net.IO.Slk.csproj",
"submodules\\CSharp.lua\\CSharp.lua.CoreSystem\\CSharp.lua.CoreSystem.csproj",
"submodules\\CSharp.lua\\CSharp.lua\\CSharp.lua.csproj"
]
}
}
1 change: 1 addition & 0 deletions War3NetStable.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"src\\War3Net.CodeAnalysis.Decompilers\\War3Net.CodeAnalysis.Decompilers.csproj",
"src\\War3Net.CodeAnalysis.Jass\\War3Net.CodeAnalysis.Jass.csproj",
"src\\War3Net.CodeAnalysis.Transpilers\\War3Net.CodeAnalysis.Transpilers.csproj",
"src\\War3Net.CodeAnalysis\\War3Net.CodeAnalysis.csproj",
"src\\War3Net.Common\\War3Net.Common.csproj",
"src\\War3Net.Drawing.Blp\\War3Net.Drawing.Blp.csproj",
"src\\War3Net.IO.Compression\\War3Net.IO.Compression.csproj",
Expand Down
Loading