Make-NuGet #45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Make-NuGet | |
| on: | |
| push: | |
| branches: [ main ] | |
| paths: [ '.github/workflows/make-nuget.yml' ] | |
| workflow_dispatch: | |
| env: | |
| NUGET_VERSION_PREFIX: 4.13.0 | |
| permissions: | |
| packages: write | |
| jobs: | |
| make-nuget: | |
| name: Make NuGet | |
| runs-on: ubuntu-22.04 | |
| defaults: | |
| run: | |
| shell: bash | |
| strategy: | |
| matrix: | |
| include: | |
| - { os: win, arch: x64, upstream: win-x64 } | |
| - { os: win, arch: x86, upstream: win-x86 } | |
| - { os: win, arch: arm64, upstream: win-arm64 } | |
| - { os: osx, arch: x64, upstream: osx-x64 } | |
| - { os: osx, arch: arm64, upstream: osx-arm64 } | |
| - { os: linux, arch: x64, upstream: rhel.8-x64 } | |
| - { os: linux, arch: arm64, upstream: rhel.8-arm64 } | |
| - { os: linux-musl, arch: x64, upstream: alpine.3.22-x64 } | |
| - { os: linux-musl, arch: arm64, upstream: alpine.3.22-arm64 } | |
| - { os: android, arch: arm64, upstream: android-arm64 } | |
| - { os: android, arch: x64, upstream: android-x64 } | |
| steps: | |
| - name: Download OpenCvSharp Artifacts | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| echo "Fetching latest successful opencvsharp.yml run of branch ${{ github.ref_name }}" | |
| RUN_ID=$(gh run list -R ${{ github.repository }} \ | |
| --workflow=opencvsharp.yml \ | |
| --branch=${{ github.ref_name }} \ | |
| --status=success --limit=1 \ | |
| --json databaseId | jq -r '.[0].databaseId') | |
| echo "Run id = $RUN_ID" | |
| ART_NAME="opencvsharp-${{ matrix.upstream }}" | |
| echo "Download artifact ${ART_NAME}" | |
| gh run download -R ${{ github.repository }} "$RUN_ID" --name "$ART_NAME" --dir opencvsharp | |
| echo "::group::Artifact tree" | |
| ls -lR opencvsharp | |
| echo "::endgroup::" | |
| - name: Build NuGet package | |
| env: | |
| VERSION: ${{ env.NUGET_VERSION_PREFIX }}.${{ github.run_number }} | |
| run: | | |
| set -euo pipefail | |
| PKG_ID="Sdcb.OpenCvSharp4.mini.runtime.${{ matrix.os }}-${{ matrix.arch }}" | |
| AUTHOR="sdcb" | |
| LICENSE="Apache-2.0" | |
| GIT_URL="https://github.com/sdcb/opencvsharp-mini-runtime" | |
| TAGS="Sdcb OpenCV OpenCvSharp OpenCvSharp4" | |
| YEAR=$(date +%Y) | |
| case "${{ matrix.os }}" in | |
| win* ) | |
| LIB_NAME="OpenCvSharpExtern.dll" | |
| RUNTIME_RID="win-${{ matrix.arch }}" | |
| ;; | |
| osx* ) | |
| LIB_NAME="libOpenCvSharpExtern.dylib" | |
| RUNTIME_RID="osx-${{ matrix.arch }}" | |
| ;; | |
| * ) | |
| LIB_NAME="libOpenCvSharpExtern.so" | |
| RUNTIME_RID="linux-${{ matrix.arch }}" | |
| ;; | |
| esac | |
| LIB_SRC="${{ github.workspace }}/opencvsharp/lib/${LIB_NAME}" | |
| if [[ ! -f "$LIB_SRC" ]]; then | |
| echo "::error file not found::${LIB_SRC}" | |
| exit 1 | |
| fi | |
| WORK="$RUNNER_TEMP/pkg" | |
| mkdir -p \ | |
| "$WORK/runtimes/${RUNTIME_RID}/native" \ | |
| "$WORK/lib/netstandard2.0" \ | |
| "$WORK/lib/net45" \ | |
| "$WORK/build/net45" | |
| cp "$LIB_SRC" "$WORK/runtimes/${RUNTIME_RID}/native/" | |
| touch "$WORK/lib/netstandard2.0/_._" | |
| cp "$WORK/lib/netstandard2.0/_._" "$WORK/lib/net45/_._" | |
| NORMALIZED_NAME="$(echo "${PKG_ID}" | tr '.-' '_' )_Dlls" | |
| PROPS_FILE="$WORK/build/net45/${PKG_ID}.props" | |
| cat > "$PROPS_FILE" <<EOF | |
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
| <PropertyGroup> | |
| <${NORMALIZED_NAME}>\$(MSBuildThisFileDirectory)..\\..\\runtimes</${NORMALIZED_NAME}> | |
| </PropertyGroup> | |
| <ItemGroup Condition="\$(TargetFrameworkVersion.StartsWith('v4')) Or \$(TargetFramework.StartsWith('net4'))"> | |
| <Content Include="\$(${NORMALIZED_NAME})\\${RUNTIME_RID}\\native\\${LIB_NAME}"> | |
| <Link>dll\\${{ matrix.arch }}\\${LIB_NAME}</Link> | |
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |
| </Content> | |
| </ItemGroup> | |
| </Project> | |
| EOF | |
| NUSPEC_FILE="$WORK/${PKG_ID}.nuspec" | |
| cat > "$NUSPEC_FILE" <<EOF | |
| <?xml version="1.0" encoding="utf-8"?> | |
| <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> | |
| <metadata> | |
| <id>${PKG_ID}</id> | |
| <version>${VERSION}</version> | |
| <title>${PKG_ID} native bindings</title> | |
| <authors>${AUTHOR}</authors> | |
| <requireLicenseAcceptance>true</requireLicenseAcceptance> | |
| <description>Native binding for ${AUTHOR}.OpenCvSharp4.mini to work on ${RUNTIME_RID}.</description> | |
| <summary>Native binding for ${AUTHOR}.OpenCvSharp4.mini to work on ${RUNTIME_RID}.</summary> | |
| <copyright>Copyright ${YEAR}</copyright> | |
| <license type="expression">${LICENSE}</license> | |
| <projectUrl>${GIT_URL}</projectUrl> | |
| <repository type="git" url="${GIT_URL}.git" /> | |
| <tags>${TAGS}</tags> | |
| <dependencies /> | |
| <frameworkAssemblies /> | |
| </metadata> | |
| <files> | |
| <file src="lib\\netstandard2.0\\_._" target="lib\\netstandard2.0" /> | |
| <file src="lib\\net45\\_._" target="lib\\net45" /> | |
| <file src="runtimes\\${RUNTIME_RID}\\native\\${LIB_NAME}" target="runtimes\\${RUNTIME_RID}\\native" /> | |
| <file src="build\\net45\\${PKG_ID}.props" target="build\\net45" /> | |
| </files> | |
| </package> | |
| EOF | |
| pushd "$WORK" >/dev/null | |
| nuget pack "${NUSPEC_FILE}" -OutputDirectory "${{ github.workspace }}/nupkgs" | |
| popd >/dev/null | |
| echo "::group::generated nupkg" | |
| ls -l "${{ github.workspace }}/nupkgs" | |
| echo "::endgroup::" | |
| # ------------------------------------------------------------ | |
| # 3. 上传结果 | |
| # ------------------------------------------------------------ | |
| - name: Upload nupkg artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: nuget-${{ matrix.os }}-${{ matrix.arch }} | |
| path: nupkgs/*.nupkg | |
| if-no-files-found: error | |
| test-nuget: | |
| name: Test NuGet | |
| needs: make-nuget | |
| strategy: | |
| matrix: | |
| include: | |
| - { os: win, arch: x64, runs-on: windows-2022, upstream: win-x64 } | |
| - { os: win, arch: x86, runs-on: windows-2022, upstream: win-x86 } | |
| - { os: win, arch: arm64, runs-on: windows-11-arm, upstream: win-arm64 } | |
| - { os: osx, arch: x64, runs-on: macos-15-intel, upstream: osx-x64 } | |
| - { os: osx, arch: arm64, runs-on: macos-15, upstream: osx-arm64 } | |
| - { os: linux, arch: x64, runs-on: ubuntu-22.04, upstream: rhel.8-x64 } | |
| - { os: linux, arch: arm64, runs-on: ubuntu-22.04-arm, upstream: rhel.8-arm64 } | |
| # - { os: linux-musl, arch: x64, runs-on: ubuntu-22.04, upstream: alpine.3.22-x64 } | |
| # - { os: linux-musl, arch: arm64, runs-on: ubuntu-22.04-arm, upstream: alpine.3.22-arm64 } | |
| # - { os: android, arch: arm64, runs-on: ubuntu-22.04, upstream: android-arm64 } | |
| # - { os: android, arch: x64, runs-on: ubuntu-22.04, upstream: android-x64 } | |
| runs-on: ${{ matrix.runs-on }} | |
| defaults: | |
| run: | |
| shell: bash | |
| steps: | |
| - name: Download NuGet artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: nuget-${{ matrix.os }}-${{ matrix.arch }} | |
| path: ./nupkg | |
| - name: Create test project | |
| run: | | |
| mkdir TestApp && cd TestApp | |
| cat > TestApp.csproj <<'EOF' | |
| <Project Sdk="Microsoft.NET.Sdk"> | |
| <PropertyGroup> | |
| <OutputType>Exe</OutputType> | |
| <TargetFramework>net8.0</TargetFramework> | |
| <ImplicitUsings>enable</ImplicitUsings> | |
| <PlatformTarget>${{ matrix.arch }}</PlatformTarget> | |
| </PropertyGroup> | |
| </Project> | |
| EOF | |
| dotnet add package OpenCvSharp4 | |
| dotnet nuget add source ../nupkg --name local | |
| dotnet add package Sdcb.OpenCvSharp4.mini.runtime.${{ matrix.os }}-${{ matrix.arch }} --source ../nupkg | |
| - name: Write test code | |
| run: | | |
| cat > TestApp/Program.cs <<'EOF' | |
| using OpenCvSharp; | |
| using OpenCvSharp.Dnn; | |
| using System; | |
| class Program | |
| { | |
| static void Main() | |
| { | |
| using Mat mat = new Mat(rows: 3, cols: 4, type: MatType.CV_8SC4); | |
| if (EnableDnnTest) | |
| CheckDnn(); | |
| Console.WriteLine("OpenCvSharp nuget test good!"); | |
| } | |
| const bool EnableDnnTest = "${{ matrix.os }}" != "osx" || "${{ matrix.arch }}" != "arm64"; | |
| static void CheckDnn() | |
| { | |
| using Mat image = new Mat(32, 32, MatType.CV_8UC3, Scalar.All(1)); | |
| using Net net = new Net(); | |
| if (!net.Empty()) | |
| throw new Exception("New DNN Net should be empty."); | |
| using Mat blob = CvDnn.BlobFromImage(image, 1.0, new Size(16, 16), Scalar.All(0), false, false); | |
| if (blob.Dims != 4 || | |
| blob.Size(0) != 1 || | |
| blob.Size(1) != 3 || | |
| blob.Size(2) != 16 || | |
| blob.Size(3) != 16) | |
| { | |
| throw new Exception($"Unexpected DNN blob shape: {blob.Size(0)}x{blob.Size(1)}x{blob.Size(2)}x{blob.Size(3)}"); | |
| } | |
| } | |
| } | |
| EOF | |
| - name: Build | |
| run: | | |
| cd TestApp | |
| dotnet build --configuration Release | |
| - name: Run | |
| run: | | |
| cd TestApp | |
| dotnet run --configuration Release --no-build | |
| test-nuget-netfx: | |
| name: Test NuGet (NetFX) | |
| needs: make-nuget | |
| runs-on: windows-2022 | |
| strategy: | |
| matrix: | |
| include: | |
| - { os: win, arch: x64 } | |
| - { os: win, arch: x86 } | |
| steps: | |
| - name: Download NuGet artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: nuget-${{ matrix.os }}-${{ matrix.arch }} | |
| path: ./nupkg | |
| - name: Create .NET Framework 4.8 test project | |
| run: | | |
| mkdir TestApp && cd TestApp | |
| # 手写 SDK 风格 net48 csproj | |
| New-Item -Name "TestApp.csproj" -ItemType "file" -Value @" | |
| <Project Sdk="Microsoft.NET.Sdk"> | |
| <PropertyGroup> | |
| <OutputType>Exe</OutputType> | |
| <TargetFramework>net48</TargetFramework> | |
| </PropertyGroup> | |
| </Project> | |
| "@ | |
| dotnet add package OpenCvSharp4 | |
| dotnet nuget add source ../nupkg --name local | |
| dotnet add package Sdcb.OpenCvSharp4.mini.runtime.${{ matrix.os }}-${{ matrix.arch }} --source ../nupkg | |
| # 写测试代码 | |
| New-Item -Name "Program.cs" -ItemType "file" -Value @" | |
| using OpenCvSharp; | |
| using OpenCvSharp.Dnn; | |
| using System; | |
| class Program | |
| { | |
| static void Main() | |
| { | |
| using (Mat mat = new Mat(rows: 3, cols: 4, type: MatType.CV_8SC4)) | |
| { | |
| } | |
| CheckDnn(); | |
| Console.WriteLine("OpenCvSharp nuget test good! (.NET Framework)"); | |
| } | |
| static void CheckDnn() | |
| { | |
| using (Mat image = new Mat(32, 32, MatType.CV_8UC3, Scalar.All(1))) | |
| using (Net net = new Net()) | |
| { | |
| if (!net.Empty()) | |
| throw new Exception("New DNN Net should be empty."); | |
| using (Mat blob = CvDnn.BlobFromImage(image, 1.0, new Size(16, 16), Scalar.All(0), false, false)) | |
| { | |
| if (blob.Dims != 4 || | |
| blob.Size(0) != 1 || | |
| blob.Size(1) != 3 || | |
| blob.Size(2) != 16 || | |
| blob.Size(3) != 16) | |
| { | |
| throw new Exception($"Unexpected DNN blob shape: {blob.Size(0)}x{blob.Size(1)}x{blob.Size(2)}x{blob.Size(3)}"); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| "@ | |
| - name: Build (.NET Framework 4.8) | |
| run: | | |
| cd TestApp | |
| dotnet build --configuration Release --arch ${{ matrix.arch }} | |
| - name: Show build output | |
| shell: bash | |
| run: | | |
| cd TestApp | |
| ls -lR bin/Release/net48 | |
| - name: Run (.NET Framework 4.8) | |
| run: | | |
| cd TestApp | |
| ./bin/Release/net48/${{ matrix.os }}-${{ matrix.arch }}/TestApp.exe | |
| upload-nuget: | |
| name: Upload NuGet | |
| needs: [make-nuget, test-nuget, test-nuget-netfx] | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Download nupkg artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| merge-multiple: true | |
| path: nupkgs | |
| - name: List nupkgs | |
| run: | | |
| echo "::group::nupkgs" | |
| ls -lR nupkgs | |
| echo "::endgroup::" | |
| - name: Upload to NuGet | |
| run: | | |
| set -euo pipefail | |
| echo "Uploading to NuGet..." | |
| for nupkg in nupkgs/*.nupkg; do | |
| echo "Uploading $nupkg" | |
| dotnet nuget push "$nupkg" --source "https://nuget.pkg.github.com/${{ github.repository_owner }}" --api-key "${{ secrets.GITHUB_TOKEN }}" --skip-duplicate | |
| done | |
| echo "Upload completed." | |
| - name: Bundle upload | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: nuget-bundle | |
| path: nupkgs/*.nupkg | |
| if-no-files-found: error |