Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac: Add automatic code signing and notarization #1805

Merged
merged 7 commits into from
Nov 17, 2020
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
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ indent_size = 2
indent_style = space
indent_size = 2
tab_size = 2

[*.yml]
intent_style = space
indent_size = 2
30 changes: 26 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: test
path: artifacts/test/${{ env.BuildConfiguration }}/**/*
path: |
artifacts/test/${{ env.BuildConfiguration }}/**/*
!artifacts/test/${{ env.BuildConfiguration }}/**/*Mac64.*

- name: Upload sample artifacts
uses: actions/upload-artifact@v2
Expand Down Expand Up @@ -94,17 +96,29 @@ jobs:
with:
dotnet-version: ${{ env.DotNetVersion }}

- name: setup-xamarin
- name: Setup Xamarin and XCode
uses: maxim-lobanov/setup-xamarin@v1
with:
mono-version: latest
xamarin-mac-version: latest
xcode-version: latest

- name: Import code signing certificate
uses: apple-actions/import-codesign-certs@v1
with:
p12-file-base64: ${{ secrets.DEVID_CERTIFICATE_P12 }}
p12-password: ${{ secrets.DEVID_CERTIFICATE_P12_PASSWORD }}

- name: Set notarization credentials
if: startsWith(github.ref, 'refs/tags/')
run: |
xcrun altool --store-password-in-keychain-item "AC_PASSWORD" -u "${{ secrets.AC_USERNAME }}" -p "${{ secrets.AC_PASSWORD }}"
echo "BuildParameters=${{ env.BuildParameters }} /p:EnableNotarizationBuild=True" >> $GITHUB_ENV

- name: Build
run: dotnet build ${{ env.BuildParameters }} /p:Platform=Mac /t:Package /bl:artifacts/log/Build.Mac.binlog
run: dotnet build ${{ env.BuildParameters }} /p:Platform=Mac /t:Package /p:EnableCodeSignBuild=True /bl:artifacts/log/Build.Mac.binlog

- name: Build VS/Mac Extension
- name: Build VS/Mac extension
run: msbuild ${{ env.BuildParameters }} /t:BuildAddins /bl:artifacts/log/Addin.Mac.binlog

- name: Upload nuget artifacts
Expand All @@ -121,6 +135,14 @@ jobs:
name: addins
path: artifacts/addin/${{ env.BuildConfiguration }}/net472/Eto.Addin.MonoDevelop*.mpack

- name: Upload test artifacts
uses: actions/upload-artifact@v2
with:
name: test
path: |
artifacts/test/${{ env.BuildConfiguration }}/**/*Mac64.*
artifacts/test/${{ env.BuildConfiguration }}/**/*Gtk2.*

- name: Upload log files
if: ${{ failure() }}
uses: actions/upload-artifact@v2
Expand Down
6 changes: 0 additions & 6 deletions build/Build.proj
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,6 @@
<MSBuild Projects="$(SourceDir)Eto.sln" Targets="Restore" Properties="$(BuildProperties);_RestoreEnforceEvaluate=True" />
<MSBuild Projects="$(SourceDir)Eto.sln" Targets="$(PackageTargets)" Properties="$(BuildProperties)" />

<!-- When building windows, assume xamarin.mac is installed and build XamMac2 platform
Note: works when compiling through VS 2017 but not msbuild command line.. why?
<MSBuild Projects="$(SourceDir)Eto.sln" Targets="Eto_XamMac2_modern:$(PackageTargets)" Properties="Configuration=$(Configuration);Platform=Mac" Condition="$(OSPlatform) == 'Windows'"/>
<MSBuild Projects="$(SourceDir)Eto.sln" Targets="Eto_XamMac2_net45:$(PackageTargets)" Properties="Configuration=$(Configuration);Platform=Mac" Condition="$(OSPlatform) == 'Windows'"/>
-->

<MSBuild Projects="$(BasePath)samples\Samples.sln" Targets="Restore" Properties="$(BuildProperties);_RestoreEnforceEvaluate=True"/>
<MSBuild Projects="$(BasePath)samples\Samples.sln" Targets="$(PackageTargets)" Properties="$(BuildProperties)"/>
</Target>
Expand Down
2 changes: 1 addition & 1 deletion lib/monomac
17 changes: 7 additions & 10 deletions src/Eto.Mac/build/BundleDotNetCore.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0" InitialTargets="MacTouchApp">


<PropertyGroup Condition="$(MacBuildBundle) == 'True'">
<PropertyGroup>
<!-- properties you can override in your project file -->

<!-- Set to True to automatically publish the bundle during build -->
Expand All @@ -17,29 +17,26 @@
<MacBundleRuntimeIdentifiers Include="$(RuntimeIdentifiers)" Condition="$(RuntimeIdentifiers) != ''" />
<MacBundleRuntimeIdentifiers Include="$(RuntimeIdentifier)" Condition="$(RuntimeIdentifier) != ''" />
</ItemGroup>
<PropertyGroup Condition="$(MacBundleRuntimeIdentifiers) == ''">

</PropertyGroup>
<ItemGroup>
<!-- runtime identifiers have been explicitly set -->
<MacBundleRuntimeIdentifiers Include="$(MacBundleRuntimeIdentifiers)" Condition="$(MacBundleRuntimeIdentifiers) != ''" />
</ItemGroup>

<Target Name="MacTouchApp" Condition="$(MacBuildBundle) == 'True'">
<Target Name="MacTouchApp">
<!-- This makes it so we can debug in VS for Mac right away without building first -->
<MakeDir Directories="$(OutputAppPath)" Condition="$(IsMac) == 'True' AND $(VisualStudioVersion) != '' AND $(TargetFramework) != '' AND $(RuntimeIdentifier) != ''" />
</Target>

<!-- Build target to automatically publish -->
<Target Name="MacBuildAppBundle" AfterTargets="AfterBuild" Condition="$(MacAutoPublishBundle) == 'True' AND $(MacIsBuildingBundle) != 'True'" Outputs="$(OutputAppPath)">
<Target Name="MacBuildAppBundle" AfterTargets="AfterBuild" DependsOnTargets="$(MacBuildAppBundleDependsOnTargets)" Condition="$(MacAutoPublishBundle) == 'True' AND $(MacIsBuildingBundle) != 'True'" Outputs="$(OutputAppPath)">
<Error Text="No RuntimeIdentifiers or MacRuntimeIdentifiers have been specified" Condition="@(MacBundleRuntimeIdentifiers->Count()) == 0" />
<PropertyGroup>
<MacTempBuildPath>$(IntermediateOutputPath)macbuild\</MacTempBuildPath>

<MacBuildProperties>MacIsBuildingBundle=True</MacBuildProperties>
<MacBuildProperties>$(MacBuildProperties);MacBundlingProject=$(MSBuildProjectFullPath)</MacBuildProperties>
<MacBuildProperties>$(MacBuildProperties);TargetFramework=$(TargetFramework)</MacBuildProperties>
<MacBuildProperties Condition="$(PublishSingleFile) == '' AND $(Configuration) == 'Release'">$(MacBuildProperties);PublishSingleFile=True</MacBuildProperties>
<MacBuildProperties Condition="$(PublishSingleFile) == '' AND $(Configuration) == 'Release' AND $(EnableCodeSigning) != 'True'">$(MacBuildProperties);PublishSingleFile=True</MacBuildProperties>
<MacBuildProperties Condition="$(PublishTrimmed) == '' AND $(Configuration) == 'Release'">$(MacBuildProperties);PublishTrimmed=True</MacBuildProperties>
<MacBuildProperties>$(MacBuildProperties);SelfContained=$(MacBundleDotNet)</MacBuildProperties>
<MacBuildProperties>$(MacBuildProperties);MacTempBuildPath=$(MacTempBuildPath)</MacBuildProperties>
Expand All @@ -55,7 +52,7 @@
Condition="$([System.String]::Copy(%(MacBundleRuntimeIdentifiers.Identity)).StartsWith('osx'))" />
</Target>

<Target Name="MacCleanAppBundle" AfterTargets="AfterClean" Condition="$(MacBuildBundle) == 'True'">
<Target Name="MacCleanAppBundle" AfterTargets="AfterClean">
<RemoveDir Directories="$(MacTempBuildPath)" />
</Target>

Expand All @@ -70,7 +67,7 @@
</Target>

<!-- Publish with bundled runtime -->
<Target Name="MacPublishAppBundle" AfterTargets="Publish" Condition="$(MacBuildBundle) == 'True'" DependsOnTargets="MacInitializeBundle">
<Target Name="MacPublishAppBundle" AfterTargets="Publish" DependsOnTargets="MacInitializeBundle">
<ItemGroup>
<LauncherFiles Include="$(PublishDir)**\*" />
<LauncherFiles Remove="$(PublishDir)**\*.pdb" Condition="$(MacIncludeSymbols) != 'True'" />
Expand Down
8 changes: 4 additions & 4 deletions src/Eto.Mac/build/BundleMono.targets
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
<!-- minimum installed version of mono required to run -->
<MacMonoMinimumVersion Condition="$(MacMonoMinimumVersion) == ''">6.0</MacMonoMinimumVersion>
</PropertyGroup>
<Target Name="MacTouchApp" Condition="$(MacBuildBundle) == 'True'">

<Target Name="MacTouchApp">
<!-- This makes it so we can debug in VS for Mac right away without building first -->
<MakeDir Directories="$(OutputAppPath)" Condition="$(IsMac) == 'True' AND $(VisualStudioVersion) != '' AND $(TargetFramework) != '' AND $(RuntimeIdentifier) == ''" />
</Target>

<!-- Build target -->
<Target Name="BuildAppBundle" AfterTargets="AfterBuild" DependsOnTargets="DetectMkBundle" Condition="$(MacBuildBundle) == 'True'" Outputs="$(OutputAppPath)">
<Target Name="MacBuildAppBundle" AfterTargets="AfterBuild" DependsOnTargets="DetectMkBundle;$(MacBuildAppBundleDependsOnTargets)" Outputs="$(OutputAppPath)">
<!-- bundle mono with mkbundle -->
<CallTarget Targets="MacBundleMono" Condition="$(MacBundleMono) == 'True'" />
<!-- copy executables and run with installed mono -->
Expand All @@ -43,7 +43,7 @@
<MkBundleExe>$(MonoBinPath)mkbundle</MkBundleExe>

<IsDetectingMkBundle Condition="$(MacBundleMono) == 'detect'">True</IsDetectingMkBundle>
<MacBundleMono Condition="$(MacBundleMono) == 'detect' AND Exists('$(MkBundleExe)')">True</MacBundleMono>
<MacBundleMono Condition="$(MacBundleMono) == 'detect' AND Exists('$(MkBundleExe)') AND $(EnableCodeSigning) != 'True'">True</MacBundleMono>

<MacBundleTarget Condition="$(MacBundleTarget) == 'default'"></MacBundleTarget>
</PropertyGroup>
Expand Down
14 changes: 14 additions & 0 deletions src/Eto.Mac/build/CodeSign.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
74 changes: 74 additions & 0 deletions src/Eto.Mac/build/CodeSign.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0" >

<PropertyGroup>
<!-- Search key for the code signing identity for the .app (partial strings match)
If empty, this will use the code signing identity if only a single identity is installed.
-->
<CodeSigningKey Condition="$(CodeSigningKey) == ''"></CodeSigningKey>
<!-- Search key for the code signing identity for the .dmg (partial strings match) -->
<DmgCodeSigningKey Condition="$(DmgCodeSigningKey) == ''">$(CodeSigningKey)</DmgCodeSigningKey>
<!-- Code signing entitlements to use -->
<CodeSignEntitlements Condition="$(CodeSignEntitlements) == ''">$(MSBuildThisFileDirectory)CodeSign.entitlements</CodeSignEntitlements>
</PropertyGroup>

<PropertyGroup>
<MacBuildDmgDependsOnTargets>MacCodeSignApp;$(MacBuildDmgDependsOnTargets)</MacBuildDmgDependsOnTargets>
</PropertyGroup>

<Target Name="MacCodeSign" AfterTargets="MacBuildAppBundle" DependsOnTargets="$(MacCodeSignDependsOnTargets)">
</Target>

<Target Name="MacCodeSignApp" DependsOnTargets="MacBuildAppBundle">

<MSBuild Projects="$(MSBuildThisFileFullPath)" Targets="_MacResolveCodeSignIdentity" Properties="CodeSignSearchKey=$(CodeSigningKey)" >
<Output TaskParameter="TargetOutputs" PropertyName="ResolvedCodeSigningKey" />
</MSBuild>

<PropertyGroup>
<CodeSignEntitlements Condition="$(CodeSignEntitlements) != '' AND !Exists($(CodeSignEntitlements)) AND Exists('$(MSBuildProjectDirectory)\$(CodeSignEntitlements)')">$(MSBuildProjectDirectory)\$(CodeSignEntitlements)</CodeSignEntitlements>

<_CodeSignOptions Condition="$(CodeSignEntitlements) != ''">--entitlements "$(CodeSignEntitlements)"</_CodeSignOptions>
</PropertyGroup>

<ItemGroup>
<_CodeSignFiles Include="$(OutputAppPath)" CodeSignOptions="--deep --options runtime $(_CodeSignOptions)" />
</ItemGroup>

<Exec Command='codesign --force %(_CodeSignFiles.CodeSignOptions) --sign "$(ResolvedCodeSigningKey)" "@(_CodeSignFiles)"' />

<Message Text="Code signed $(OutputAppPath)" Importance="high" />
</Target>

<Target Name="MacCodeSignDmg" DependsOnTargets="MacBuildDmg" Condition="$(EnableDmgBuild) == 'True'">

<MSBuild Projects="$(MSBuildThisFileFullPath)" Targets="_MacResolveCodeSignIdentity" Properties="CodeSignSearchKey=$(DmgCodeSigningKey)" >
<Output TaskParameter="TargetOutputs" PropertyName="ResolvedDmgCodeSigningKey" />
</MSBuild>

<Exec Command='codesign --force --sign "$(ResolvedDmgCodeSigningKey)" "$(_DmgPath)"' />

<Message Text="Code signed $(_DmgPath)" Importance="high" />
</Target>

<!-- Resolve a code sign identity. Parameters: CodeSignSearchKey -->
<Target Name="_MacResolveCodeSignIdentity" Outputs="$(ResolvedCodeSignIdentity)">

<!-- get valid identities that match -->
<Exec Command="security find-identity -v -p codesigning | grep -v 'valid identities found' | grep '$(CodeSignSearchKey)' | awk '{print $2}'"
ConsoleToMSBuild="True"
StandardOutputImportance="normal">
<Output TaskParameter="ConsoleOutput" ItemName="MatchingIdentities"/>
</Exec>

<Error Text="Could not find code sign key matching '$(CodeSignSearchKey)'. Ensure you have installed your code sign certificate."
Condition="@(MatchingIdentities->Count()) == '0'" />

<Error Text="More than one valid code signing certificate matches '$(CodeSignSearchKey)'. Enter a more specific key for the certificate."
Condition="@(MatchingIdentities->Count()) > '1'" />

<PropertyGroup>
<ResolvedCodeSignIdentity>@(MatchingIdentities)</ResolvedCodeSignIdentity>
</PropertyGroup>
</Target>

</Project>
Binary file added src/Eto.Mac/build/Dmg.background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 126 additions & 0 deletions src/Eto.Mac/build/Dmg.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0" >

<PropertyGroup>
<!-- File Name of the DMG -->
<DmgName Condition="$(DmgName) == ''">$(MacBundleName)</DmgName>
<!-- DMG volume name -->
<DmgVolumeName Condition="$(DmgVolumeName) == ''">$(DmgName)</DmgVolumeName>
<!-- Where to put the DMG -->
<DmgOutputPath Condition="$(DmgOutputPath) == ''">$(OutputPath)</DmgOutputPath>

<!-- True to add typical formatting to the DMG, add application shortcut icon, background, auto-open, etc. -->
<DmgBeautify Condition="$(DmgBeautify) == ''">True</DmgBeautify>

<!-- Size of the icons in the DMG -->
<DmgIconSize Condition="$(DmgIconSize) == ''">72</DmgIconSize>
<!-- Bounds of the Finder window when opened (left, top, right, bottom) -->
<DmgBounds Condition="$(DmgBounds) == ''">400, 100, 900, 430</DmgBounds>
<!-- Location of your app icon (x, y) -->
<DmgAppLocation Condition="$(DmgAppLocation) == ''">120, 150</DmgAppLocation>
<!-- Location of the applications shortcut icon (x, y) -->
<DmgApplicationsShortcutLocation Condition="$(DmgApplicationsShortcutLocation) == ''">380, 150</DmgApplicationsShortcutLocation>
<!-- Image to use for the background, or 'none' to omit the background image. -->
<DmgBackgroundImage Condition="$(DmgBackgroundImage) == ''">$(MSBuildThisFileDirectory)Dmg.background.png</DmgBackgroundImage>
</PropertyGroup>

<PropertyGroup>
<_MacDmgTempPath>$(IntermediateOutputPath)macdmg\</_MacDmgTempPath>
<_MacDmgContentPath>$(_MacDmgTempPath)content\</_MacDmgContentPath>
<_DmgPath>$(DmgOutputPath)$(DmgName).dmg</_DmgPath>
</PropertyGroup>

<ItemGroup>
<AvailableItemName Include="DmgContent" />
</ItemGroup>

<Target Name="MacBuildDmg" AfterTargets="MacBuildAppBundle" DependsOnTargets="$(MacBuildDmgDependsOnTargets)">
</Target>

<Target Name="MacCreateDmg" DependsOnTargets="MacBuildAppBundle">
<Message Text="Creating $(DmgName).dmg" />

<RemoveDir Directories="$(_MacDmgTempPath)" />
<Delete Files="$(_DmgPath)" />

<ItemGroup>
<_DmgAppFiles Include="$(OutputAppPath)**\*" TargetPath="$([System.IO.Path]::GetFileName($(OutputAppPath.TrimEnd('/'))))\%(RecursiveDir)%(Filename)%(Extension)" />
<_DmgFiles Include="@(_DmgAppFiles)" TargetPath="$([System.IO.Path]::GetFileName($(OutputAppPath.TrimEnd('/'))))\%(RecursiveDir)%(Filename)%(Extension)" />
<_DmgFiles Include="@(DmgContent)" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" Condition="%(TargetPath) == ''"/>
<_DmgFiles Include="@(DmgContent)" Condition="%(TargetPath) != ''"/>
</ItemGroup>

<Copy SourceFiles="@(_DmgFiles)" DestinationFiles="@(_DmgFiles->'$(_MacDmgContentPath)%(TargetPath)')" />

<Exec Command='hdiutil create "$(_DmgPath)" -ov -quiet -volname "$(DmgVolumeName)" -format UDZO -fs HFS+ -srcfolder "$(_MacDmgContentPath)"' />

<Message Text="$(MSBuildProjectName) -> $(_DmgPath)" Importance="high" />
</Target>

<Target Name="MacBeautifyDmg" Condition="$(DmgBeautify) == 'True'">

<PropertyGroup>
<_TempReadWriteDmgPath>$(_MacDmgTempPath)$(DmgName).rw.dmg</_TempReadWriteDmgPath>
</PropertyGroup>

<!-- convert to read-write so we can modify the dmg directly -->
<Exec Command='hdiutil convert -format UDRW -o "$(_TempReadWriteDmgPath)" "$(_DmgPath)"'
StandardOutputImportance="normal" />

<Exec Command="hdiutil attach -readwrite -noverify -noautoopen '$(_TempReadWriteDmgPath)' | grep 'Apple_HFS' | awk -v m='\x' -v N='3' '{$N=m$N; print substr($0,index($0,m)+1)}'"
ConsoleToMSBuild="True"
StandardOutputImportance="normal">
<Output TaskParameter="ConsoleOutput" PropertyName="_DmgVolume" />
</Exec>

<Exec Command="sleep 2" />

<Exec Command="bless '$(_DmgVolume)/' --openfolder '$(_DmgVolume)'" />

<PropertyGroup>
<DmgBackgroundImage Condition="$(DmgBackgroundImage) != '' AND !Exists($(DmgBackgroundImage)) AND Exists('$(MSBuildProjectDirectory)\$(DmgBackgroundImage)')">$(MSBuildProjectDirectory)\$(DmgBackgroundImage)</DmgBackgroundImage>
<_DmgBackgroundImageName>$([System.IO.Path]::GetFileName($(DmgBackgroundImage)))</_DmgBackgroundImageName>
<_DmgFinderOptions Condition="$(DmgBackgroundImage) != '' AND Exists($(DmgBackgroundImage))">set background picture of theViewOptions to file &quot;.background:$(_DmgBackgroundImageName)&quot;</_DmgFinderOptions>
</PropertyGroup>

<Copy SourceFiles="$(DmgBackgroundImage)"
DestinationFiles="$(_DmgVolume)/.background/$(_DmgBackgroundImageName)"
Condition="$(DmgBackgroundImage) != '' AND Exists($(DmgBackgroundImage))" />

<Exec Command="echo '
tell application &quot;Finder&quot;
tell disk &quot;'$(_DmgVolume.SubString(9))'&quot;
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {$(DmgBounds)}
set theViewOptions to the icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to $(DmgIconSize)
$(_DmgFinderOptions)
make new alias file at container window to POSIX file &quot;/Applications&quot; with properties {name:&quot;Applications&quot;}
set position of item &quot;'$(MacBundleName)'&quot; of container window to {$(DmgAppLocation)}
set position of item &quot;Applications&quot; of container window to {$(DmgApplicationsShortcutLocation)}
update without registering applications
delay 2
close
end tell
set visible to false
end tell
' | osascript"
StandardOutputImportance="normal" />

<Exec Command="hdiutil detach '$(_DmgVolume)'"
StandardOutputImportance="normal" />

<Delete Files="$(_DmgPath)" />
<Exec Command='hdiutil convert -format UDZO -o "$(_DmgPath)" "$(_TempReadWriteDmgPath)" '
StandardOutputImportance="normal" />

</Target>

<Target Name="MacCleanDmg" AfterTargets="Clean" Condition="$(MacIsBuildingBundle) != 'True'">
<Delete Files="$(_DmgPath)" />
</Target>

</Project>
Loading