This task wouldn’t require much efforts but:
- Service Fabric doesn’t support packaging its “package” (which is not a real package but just a directory) into .sfpkg out-of-the-box. Only suggests to use ZipFile.CreateFromDirectory.
- MSBuildTasks doesn’t support .NET Core so we can’t use its Zip task. So we have to write our own instead.
- .NET Core doesn’t support
CodeTaskFactory
. Soon it will (see the same issue, in the bottom) but for now we can use RoslynCodeTaskFactory
Here’s the full project, I called it package.props
and imported from all my sfproj:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\RoslynCodeTaskFactory.2.0.7\build\RoslynCodeTaskFactory.props" />
<UsingTask TaskName="Zip"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(RoslynCodeTaskFactory)"
Condition="'$(RoslynCodeTaskFactory)' != ''">
<ParameterGroup>
<SourceDirectoryName ParameterType="System.String" Required="true" />
<DestinationArchiveFileName ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.IO.Compression.FileSystem" />
<Using Namespace="System.IO.Compression" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try
{
if (File.Exists(DestinationArchiveFileName))
{
Log.LogMessage("File {0} already exists, deleting.", DestinationArchiveFileName);
File.Delete(DestinationArchiveFileName);
}
string directoryName = Path.GetDirectoryName(DestinationArchiveFileName);
if (!Directory.Exists(directoryName))
{
Log.LogMessage("Directory {0} doesn't exist, creating..", directoryName);
Directory.CreateDirectory(directoryName);
}
Log.LogMessage("Zipping directory {0} to {1}", SourceDirectoryName, DestinationArchiveFileName);
ZipFile.CreateFromDirectory(SourceDirectoryName, DestinationArchiveFileName);
return true;
}
catch(Exception ex)
{
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
<Target Name="Package" DependsOnTargets="$(PackageDependsOn)" AfterTargets="Build" Returns="@(_AllPackageFiles)" />
<Target Name="ZipPackage" AfterTargets="Package">
<PropertyGroup>
<PackageSource>pkg\$(Configuration)</PackageSource>
<PackageDestination>sfpkg\$(MSBuildProjectName).sfpkg</PackageDestination>
</PropertyGroup>
<Zip SourceDirectoryName="$(PackageSource)" DestinationArchiveFileName="$(PackageDestination)" />
</Target>
</Project>
It will zip folder pkg\Release
to sfpkg\.sfpkg
.
Now call the Package target using PowerShell:
param
(
[Parameter(Mandatory=$true)]
[ValidateSet('Debug', 'Release')]
[string]$Configuration
)
$projects = Get-ChildItem *.sfproj -Recurse
foreach ($project in $projects)
{
Write-Host "Packaging project $project and configuration $Configuration"
& msbuild "$project" /t:Package /p:Platform=x64 /p:Configuration=$Configuration /m
}
That’s it. Now you can take the resulting sfpkg and deploy it directly to your Service Fabric cluster.