Commit fa499cf7 authored by Mikael Lindemann's avatar Mikael Lindemann
Browse files

Described the build flow in README.

parent 609e910b
......@@ -8,6 +8,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EEFA0116-3375-4A6C-8964-148AD3A53B65}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
README.md = README.md
UmbracoPackage.targets = UmbracoPackage.targets
EndProjectSection
EndProject
......
......@@ -12,6 +12,7 @@
<PackageTags>umbraco;umbraco-cms;custom-property-editor;contact-number</PackageTags>
<PackageIcon>images\icon.png</PackageIcon>
<PackageIconUrl>https://appstract.dk/dist/images/apple-touch-icon.png</PackageIconUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<ContentTargetFolders>content</ContentTargetFolders>
<IncludeSymbols>true</IncludeSymbols>
......
# UmbracoContactNumber
## Build steps
### How to build the NuGet package
This is automated by properties in the .csproj file by setting the following property to true:
```xml
<Project ...>
<PropertyGroup>
...
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
...
</PropertyGroup>
...
</Project>
```
Furthermore, to fill out the NuGet package information such as owner, name, and so on, the following properties are set:
```xml
<Project ...>
<PropertyGroup>
<Id>Appstract.UmbracoContactNumber</Id>
<Authors>Appstract Consulting Aps</Authors>
<Owners>Appstract Consulting Aps</Owners>
<PackageProjectUrl>https://gitlab.dev.appstract.dk/internal/umbracocontactnumber</PackageProjectUrl>
<RepositoryUrl>https://gitlab.dev.appstract.dk/internal/umbracocontactnumber</RepositoryUrl>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<Description>
This adds a contact (phone) number custom property editor that allows to select a country code from a list of countries and shows a green checkbox if the number is known to be of correct length for the country.
</Description>
<PackageReleaseNotes>Initial release with hardcoded country database.</PackageReleaseNotes>
<Copyright>Copyright 2020</Copyright>
<PackageTags>umbraco;umbraco-cms;custom-property-editor;contact-number</PackageTags>
<PackageIcon>images\icon.png</PackageIcon>
<PackageIconUrl>https://appstract.dk/dist/images/apple-touch-icon.png</PackageIconUrl>
<ContentTargetFolders>content</ContentTargetFolders>
...
</PropertyGroup>
...
</Project>
```
To include the custom property editor in the NuGet package, the following items are included with `Pack="true"`:
```xml
<Project ...>
...
<ItemGroup>
<Content Include="App_Plugins\Appstract.UmbracoContactNumber\**\*.*" Pack="true" />
<None Include="..\.editorconfig" Link=".editorconfig" />
<None Include="Appstract-a Logo.png" Pack="true" PackagePath="images\icon.png" />
...
</ItemGroup>
...
</Project>
```
### How to build the Umbraco package
An MSBuild target that builds the Umbraco package has been defined to run after the build completes.
The targets file is imported as follows:
```xml
<Project ...>
...
<Import Project="../UmbracoPackage.targets" />
</Project>
```
As input it takes an `Item` element of the name `UmbracoPackageContent`.
In the project file, files are included into the Umbraco package by using the following syntax:
```xml
<Project ...>
...
<ItemGroup>
...
<UmbracoPackageContent Include="App_Plugins\Appstract.UmbracoContactNumber\**\*.*" />
<UmbracoPackageContent Include="$(OutputPath)\$(AssemblyName).dll" />
<UmbracoPackageContent Include="package.xml" />
</ItemGroup>
...
</Project>
```
Here, `App_Plugins\Appstract.UmbracoContactNumber\**\*.*` means take all files with extensions that are located below `App_Plugins\Appstract.UmbracoContactNumber\`.
#### The Umbraco package structure
The Umbraco package is a zip-file consisting of a manifest called `package.xml` and the files to include in the package.
In this case, the files to include is the compiled `Appstract.UmbracoContactNumber.dll` as well as the custom property editor located in `App_Plugins\Appstract.UmbracoContactNumber`.
The manifest has a `<file>` element for each of the included files, which specifies the source (in the package) as well as where the file should be located when installed (both path and name, in case two folders contain a file with the same name).
Furthermore the manifest has some metadata that describes the package itself in terms of name, version, license, required Umbraco version, readme and so on.
It is also possible to create Umbraco data on install. In this case we create a default data type instance of the custom property editor by adding an element to the `<DataTypes>` element. Since the custom property editor has no configuration for now, it's just consisting of a name, an id, a GUID, and a database type.
#### MSBuild target definitions walkthrough
Source: `UmbracoPackage.targets`.
The first property group defines an intermediate folder where the contents of the Umbraco package:
```xml
<Project ...>
<PropertyGroup Condition=" '$(UmbracoPackageIntermediateOutputPath)' == '' ">
<UmbracoPackageIntermediateOutputPath>$(BaseIntermediateOutputPath)\umbracopackage_staging\</UmbracoPackageIntermediateOutputPath>
</PropertyGroup>
...
</Project>
```
By using `Condition` it is possible to override the intermediate output folder on a per-project basis.
This is useful if multiple projects create different Umbraco Packages.
If not overridden, it defaults to `$(BaseIntermediateOutputPath)\umbracopackage_staging\` which usually resolves to `obj\umbracopackage_staging\`.
##### UmbracoPackage
The first target `UmbracoPackage` is set up to run after a build, and only if the input files have changed with respect to the resulting Umbraco package file.
It has the following steps:
1. Create the `$(UmbracoPackageIntermediateOutputPath)` folder if it doesn't exist.
2. Remove all files from `$(UmbracoPackageIntermediateOutputPath)`. This is to avoid packaging files that should have been removed from the package.
3. Copy all items from `@(UmbracoPackageContent)` into `$(UmbracoPackageIntermediateOutputPath)` without keeping the folder structure.
4. Change the version in the `package.xml` to follow the MSBuild Version property. Note that only the `package.xml` in `$(UmbracoPackageIntermediateOutputPath)` is changed, not the source file.
5. Zip `$(UmbracoPackageIntermediateOutputPath)` into a package, and place it in `$(BaseOutputPath)\$(Configuration)\$(AssemblyName).$(Version).zip`, overwriting any existing file. `$(BaseOutputPath)\$(Configuration)\$(AssemblyName).$(Version).zip` usually resolves to `bin\Release\Appstract.UmbracoContactNumber.1.0.0.zip`. This folder is also where the NuGet package is stored.
##### UmbracoPackageClean
The second target `UmbracoPackageClean` is set up to run after cleaning the project. It removes the contents of `$(UmbracoPackageIntermediateOutputPath)` as well as the containing folder.
#### Roadmap
If we make many of these packages in the future, it might be worthwhile spending some time on creating an actual Umbraco Package task, that takes the files and metadata as input, and creates the packages.xml from scratch, rather than relying on it being well-formed.
MSBuild tasks can be written in .NET and distributed as NuGet packages, such that this can be easily imported into other projects.
The downside to doing this, is that Umbraco can change the format without notice - so it would be great if they distributed such an opportunity alongside Umbraco itself.
\ No newline at end of file
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PropertyGroup Condition=" '$(UmbracoPackageIntermediateOutputPath)' == '' ">
<UmbracoPackageIntermediateOutputPath>$(BaseIntermediateOutputPath)\umbracopackage_staging\</UmbracoPackageIntermediateOutputPath>
</PropertyGroup>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment