Poppler.Net 0.13.0 #87
Workflow file for this run
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: CI | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| release: | |
| types: | |
| - published | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event_name == 'release' && github.event.release.tag_name || github.ref }} | |
| cancel-in-progress: ${{ github.event_name != 'release' }} | |
| env: | |
| DOTNET_CLI_TELEMETRY_OPTOUT: "1" | |
| DOTNET_NOLOGO: "1" | |
| jobs: | |
| build-and-test: | |
| name: Build and test (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-latest | |
| - windows-latest | |
| - macos-latest | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v6 | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Restore | |
| run: dotnet restore Poppler.Net.sln --configfile NuGet.Config | |
| - name: Build | |
| run: dotnet build Poppler.Net.sln --configuration Release --no-restore | |
| - name: Verify managed-only dependencies | |
| run: >- | |
| dotnet run | |
| --project eng/Poppler.Net.ManagedOnlyVerifier/Poppler.Net.ManagedOnlyVerifier.csproj | |
| --configuration Release | |
| --no-build | |
| -- | |
| "${{ github.workspace }}" | |
| - name: Test | |
| run: >- | |
| dotnet run | |
| --project tests/Poppler.Net.Tests/Poppler.Net.Tests.csproj | |
| --configuration Release | |
| --no-build | |
| -- | |
| --noresult | |
| package: | |
| name: Pack NuGet packages | |
| needs: build-and-test | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| outputs: | |
| package-version: ${{ steps.package-version.outputs.value }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v6 | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Restore | |
| run: dotnet restore Poppler.Net.sln --configfile NuGet.Config | |
| - name: Build | |
| run: dotnet build Poppler.Net.sln --configuration Release --no-restore | |
| - name: Read package version | |
| id: package-version | |
| shell: bash | |
| run: | | |
| library_version="$(dotnet msbuild src/Poppler.Net/Poppler.Net.csproj -nologo -getProperty:Version)" | |
| tool_version="$(dotnet msbuild src/Poppler.Net.Cli/Poppler.Net.Cli.csproj -nologo -getProperty:Version)" | |
| if [[ "${library_version}" != "${tool_version}" ]]; then | |
| echo "Library version ${library_version} does not match CLI tool version ${tool_version}." >&2 | |
| exit 1 | |
| fi | |
| echo "value=${library_version}" >> "${GITHUB_OUTPUT}" | |
| - name: Verify release tag guard | |
| shell: bash | |
| run: | | |
| package_version="$(dotnet msbuild src/Poppler.Net/Poppler.Net.csproj -nologo -getProperty:Version)" | |
| dotnet msbuild \ | |
| src/Poppler.Net/Poppler.Net.csproj \ | |
| -nologo \ | |
| -target:ValidateReleaseTag \ | |
| -property:ReleaseTag="v${package_version}" | |
| dotnet msbuild \ | |
| src/Poppler.Net/Poppler.Net.csproj \ | |
| -nologo \ | |
| -target:ValidateReleaseTag \ | |
| -property:ReleaseTag="v0.0.0-invalid" \ | |
| -property:ExpectedReleaseTagMatch=false | |
| - name: Verify release tag matches package version | |
| if: github.event_name == 'release' | |
| shell: bash | |
| env: | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| run: >- | |
| dotnet msbuild | |
| src/Poppler.Net/Poppler.Net.csproj | |
| -nologo | |
| -target:ValidateReleaseTag | |
| -property:ReleaseTag="${RELEASE_TAG}" | |
| - name: Pack | |
| run: | | |
| dotnet pack \ | |
| src/Poppler.Net/Poppler.Net.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| --output artifacts | |
| dotnet pack \ | |
| src/Poppler.Net.Cli/Poppler.Net.Cli.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| --output artifacts | |
| - name: Verify package content and metadata | |
| shell: bash | |
| run: | | |
| dotnet run \ | |
| --project eng/Poppler.Net.PackageVerifier/Poppler.Net.PackageVerifier.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -- \ | |
| "artifacts/Poppler.Net.${{ steps.package-version.outputs.value }}.nupkg" \ | |
| "${{ steps.package-version.outputs.value }}" | |
| dotnet run \ | |
| --project eng/Poppler.Net.PackageVerifier/Poppler.Net.PackageVerifier.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -- \ | |
| "artifacts/Poppler.Net.Cli.${{ steps.package-version.outputs.value }}.nupkg" \ | |
| "${{ steps.package-version.outputs.value }}" | |
| - name: Create source archive | |
| shell: bash | |
| run: >- | |
| git archive | |
| --format=tar.gz | |
| --prefix=Poppler.Net/ | |
| --output="artifacts/Poppler.Net.${{ steps.package-version.outputs.value }}.tar.gz" | |
| HEAD | |
| - name: Verify extracted source archive | |
| shell: bash | |
| env: | |
| PACKAGE_VERSION: ${{ steps.package-version.outputs.value }} | |
| run: | | |
| source_root="$(mktemp -d)" | |
| tar -xzf "${GITHUB_WORKSPACE}/artifacts/Poppler.Net.${PACKAGE_VERSION}.tar.gz" -C "${source_root}" | |
| cd "${source_root}/Poppler.Net" | |
| dotnet restore Poppler.Net.sln --configfile NuGet.Config | |
| dotnet build Poppler.Net.sln \ | |
| --configuration Release \ | |
| --no-restore \ | |
| -p:SourceArchiveBuild=true \ | |
| -p:SourceRevisionId="${GITHUB_SHA}" | |
| dotnet run \ | |
| --project eng/Poppler.Net.ManagedOnlyVerifier/Poppler.Net.ManagedOnlyVerifier.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -- "${source_root}/Poppler.Net" | |
| dotnet run \ | |
| --project tests/Poppler.Net.Tests/Poppler.Net.Tests.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -- --noresult | |
| dotnet pack \ | |
| src/Poppler.Net/Poppler.Net.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -p:SourceRevisionId="${GITHUB_SHA}" \ | |
| --output "${source_root}/package" | |
| dotnet run \ | |
| --project eng/Poppler.Net.PackageVerifier/Poppler.Net.PackageVerifier.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -- \ | |
| "${source_root}/package/Poppler.Net.${PACKAGE_VERSION}.nupkg" \ | |
| "${PACKAGE_VERSION}" | |
| dotnet pack \ | |
| src/Poppler.Net.Cli/Poppler.Net.Cli.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -p:SourceRevisionId="${GITHUB_SHA}" \ | |
| --output "${source_root}/package" | |
| dotnet run \ | |
| --project eng/Poppler.Net.PackageVerifier/Poppler.Net.PackageVerifier.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| -- \ | |
| "${source_root}/package/Poppler.Net.Cli.${PACKAGE_VERSION}.nupkg" \ | |
| "${PACKAGE_VERSION}" | |
| - name: Upload NuGet package | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: nuget-package | |
| path: artifacts/*.nupkg | |
| if-no-files-found: error | |
| retention-days: 14 | |
| - name: Upload source archive | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: source-archive | |
| path: artifacts/*.tar.gz | |
| if-no-files-found: error | |
| retention-days: 14 | |
| package-consumer: | |
| name: Package consumer (${{ matrix.os }}, ${{ matrix.framework }}) | |
| needs: package | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-latest | |
| - windows-latest | |
| - macos-latest | |
| framework: | |
| - net8.0 | |
| - net10.0 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v6 | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Download NuGet package | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: nuget-package | |
| path: artifacts | |
| - name: Restore clean package consumer | |
| run: >- | |
| dotnet restore | |
| eng/Poppler.Net.PackageSmoke/Poppler.Net.PackageSmoke.csproj | |
| --configfile NuGet.Config | |
| -p:RestoreAdditionalProjectSources="${{ github.workspace }}/artifacts" | |
| -p:PopplerPackageVersion=${{ needs.package.outputs.package-version }} | |
| - name: Build and render from package | |
| run: >- | |
| dotnet run | |
| --project eng/Poppler.Net.PackageSmoke/Poppler.Net.PackageSmoke.csproj | |
| --configuration Release | |
| --framework ${{ matrix.framework }} | |
| --no-restore | |
| -p:PopplerPackageVersion=${{ needs.package.outputs.package-version }} | |
| -- | |
| tests/fixtures/rendering-beta2.pdf | |
| ${{ needs.package.outputs.package-version }} | |
| tool-consumer: | |
| name: CLI tool consumer (${{ matrix.os }}) | |
| needs: package | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-latest | |
| - windows-latest | |
| - macos-latest | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v6 | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Download NuGet packages | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: nuget-package | |
| path: artifacts | |
| - name: Install and run packaged CLI tool | |
| shell: pwsh | |
| run: | | |
| $toolPath = Join-Path "${{ github.workspace }}" "artifacts/tools" | |
| dotnet tool install Poppler.Net.Cli ` | |
| --tool-path $toolPath ` | |
| --version "${{ needs.package.outputs.package-version }}" ` | |
| --add-source "${{ github.workspace }}/artifacts" ` | |
| --ignore-failed-sources | |
| $command = Join-Path $toolPath $(if ($IsWindows) { "poppler-net.exe" } else { "poppler-net" }) | |
| & $command version | |
| $html = Join-Path "${{ runner.temp }}" "poppler-net-tool-smoke.html" | |
| & $command html ` | |
| "tests/fixtures/truetype-format0-subset.pdf" ` | |
| $html | |
| if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $html)) { | |
| throw "The packaged CLI did not create HTML output." | |
| } | |
| $content = Get-Content -Raw -LiteralPath $html | |
| if ($content.IndexOf("class=`"pdf-glyph ", [StringComparison]::Ordinal) -lt 0 -or | |
| $content.IndexOf("pdf-managed-", [StringComparison]::Ordinal) -lt 0 -or | |
| $content.IndexOf("<text ", [StringComparison]::Ordinal) -ge 0 -or | |
| $content.IndexOf("ABCDEF+DejaVuSans", [StringComparison]::Ordinal) -ge 0) { | |
| throw "The packaged CLI HTML smoke output is invalid." | |
| } | |
| $separate = Join-Path "${{ runner.temp }}" "poppler-net-separated" | |
| & $command separate ` | |
| "tests/fixtures/truetype-format0-subset.pdf" ` | |
| $separate | |
| $page = Join-Path $separate "truetype-format0-subset-page-0001.pdf" | |
| if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $page)) { | |
| throw "The packaged CLI did not create standalone PDF output." | |
| } | |
| $info = (& $command info $page | Out-String) | |
| if ($LASTEXITCODE -ne 0 -or | |
| $info.IndexOf("Pages: 1", [StringComparison]::Ordinal) -lt 0 -or | |
| $info.IndexOf("Encrypted: no", [StringComparison]::Ordinal) -lt 0) { | |
| throw "The packaged CLI standalone PDF smoke output is invalid." | |
| } | |
| & $command separate ` | |
| "tests/fixtures/truetype-format0-subset.pdf" ` | |
| $separate | |
| $collision = Join-Path $separate "truetype-format0-subset-page-0001-2.pdf" | |
| if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $collision)) { | |
| throw "The packaged CLI did not choose a collision-free PDF name." | |
| } | |
| $structuredJson = Join-Path "${{ runner.temp }}" "poppler-net-structured.json" | |
| & $command json ` | |
| "tests/fixtures/truetype-format0-subset.pdf" ` | |
| $structuredJson ` | |
| --page 1 | |
| $structured = Get-Content -Raw -LiteralPath $structuredJson | |
| if ($LASTEXITCODE -ne 0 -or | |
| $structured.IndexOf('"schemaVersion": "1.0"', [StringComparison]::Ordinal) -lt 0 -or | |
| $structured.IndexOf('"name": "DejaVuSans"', [StringComparison]::Ordinal) -lt 0 -or | |
| $structured.IndexOf('"rawName": "ABCDEF+DejaVuSans"', [StringComparison]::Ordinal) -lt 0) { | |
| throw "The packaged CLI structured JSON output is invalid." | |
| } | |
| $structuredRoot = Join-Path "${{ runner.temp }}" "poppler-net-structured-bundle" | |
| & $command export ` | |
| "tests/fixtures/images-and-color.pdf" ` | |
| $structuredRoot ` | |
| --page 1 | |
| if ($LASTEXITCODE -ne 0 -or | |
| -not (Test-Path -LiteralPath (Join-Path $structuredRoot "manifest.json")) -or | |
| -not (Test-Path -LiteralPath (Join-Path $structuredRoot "document.xml")) -or | |
| -not (Test-Path -LiteralPath (Join-Path $structuredRoot "document.xhtml"))) { | |
| throw "The packaged CLI structured bundle output is invalid." | |
| } | |
| $rangeHtml = Join-Path "${{ runner.temp }}" "poppler-net-range.html" | |
| & $command html ` | |
| "tests/fixtures/compatibility-beta1.pdf" ` | |
| $rangeHtml ` | |
| --first-page 2 ` | |
| --last-page 3 | |
| $rangeHtmlContent = Get-Content -Raw -LiteralPath $rangeHtml | |
| if ($LASTEXITCODE -ne 0 -or | |
| $rangeHtmlContent.IndexOf('id="page-1"', [StringComparison]::Ordinal) -ge 0 -or | |
| $rangeHtmlContent.IndexOf('id="page-2"', [StringComparison]::Ordinal) -lt 0 -or | |
| $rangeHtmlContent.IndexOf('id="page-3"', [StringComparison]::Ordinal) -lt 0) { | |
| throw "The packaged CLI HTML page range is invalid." | |
| } | |
| $rangeJson = Join-Path "${{ runner.temp }}" "poppler-net-range.json" | |
| & $command json ` | |
| "tests/fixtures/compatibility-beta1.pdf" ` | |
| $rangeJson ` | |
| --first-page 2 ` | |
| --last-page 3 ` | |
| --no-images | |
| $rangePages = @((Get-Content -Raw -LiteralPath $rangeJson | ConvertFrom-Json).pages) | |
| if ($LASTEXITCODE -ne 0 -or | |
| $rangePages.Count -ne 2 -or | |
| $rangePages[0].index -ne 1 -or | |
| $rangePages[1].index -ne 2) { | |
| throw "The packaged CLI structured page range is invalid." | |
| } | |
| $limitedHtml = Join-Path "${{ runner.temp }}" "poppler-net-limited.html" | |
| $nativeErrorPreference = $PSNativeCommandUseErrorActionPreference | |
| $errorPreference = $ErrorActionPreference | |
| try { | |
| $PSNativeCommandUseErrorActionPreference = $false | |
| $ErrorActionPreference = "Continue" | |
| & $command html ` | |
| "tests/fixtures/compatibility-beta1.pdf" ` | |
| $limitedHtml ` | |
| --first-page 1 ` | |
| --last-page 2 ` | |
| --max-pages 1 2>$null | |
| $limitedHtmlExitCode = $LASTEXITCODE | |
| } | |
| finally { | |
| $PSNativeCommandUseErrorActionPreference = $nativeErrorPreference | |
| $ErrorActionPreference = $errorPreference | |
| } | |
| if ($limitedHtmlExitCode -eq 0 -or (Test-Path -LiteralPath $limitedHtml)) { | |
| throw "The packaged CLI did not enforce the HTML page limit." | |
| } | |
| $limitedJson = Join-Path "${{ runner.temp }}" "poppler-net-limited.json" | |
| try { | |
| $PSNativeCommandUseErrorActionPreference = $false | |
| $ErrorActionPreference = "Continue" | |
| & $command json ` | |
| "tests/fixtures/compatibility-beta1.pdf" ` | |
| $limitedJson ` | |
| --max-nodes 1 2>$null | |
| $limitedJsonExitCode = $LASTEXITCODE | |
| } | |
| finally { | |
| $PSNativeCommandUseErrorActionPreference = $nativeErrorPreference | |
| $ErrorActionPreference = $errorPreference | |
| } | |
| if ($limitedJsonExitCode -eq 0 -or (Test-Path -LiteralPath $limitedJson)) { | |
| throw "The packaged CLI did not enforce the structured node limit." | |
| } | |
| $limitedPages = Join-Path "${{ runner.temp }}" "poppler-net-limited-pages" | |
| try { | |
| $PSNativeCommandUseErrorActionPreference = $false | |
| $ErrorActionPreference = "Continue" | |
| & $command separate ` | |
| "tests/fixtures/compatibility-beta1.pdf" ` | |
| $limitedPages ` | |
| --first-page 1 ` | |
| --last-page 2 ` | |
| --max-pages 1 2>$null | |
| $limitedPagesExitCode = $LASTEXITCODE | |
| } | |
| finally { | |
| $PSNativeCommandUseErrorActionPreference = $nativeErrorPreference | |
| $ErrorActionPreference = $errorPreference | |
| } | |
| if ($limitedPagesExitCode -eq 0) { | |
| throw "The packaged CLI did not enforce the separated-page limit." | |
| } | |
| # The expected native failure remains in PowerShell's automatic | |
| # exit-code variable even after the assertion succeeds. | |
| $global:LASTEXITCODE = 0 | |
| publish: | |
| name: Publish to NuGet.org | |
| if: github.event_name == 'release' && github.event.action == 'published' | |
| needs: | |
| - package | |
| - package-consumer | |
| - tool-consumer | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| environment: nuget.org | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: 10.0.302 | |
| - name: Download NuGet package | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: nuget-package | |
| path: artifacts | |
| - name: Log in to NuGet.org | |
| id: nuget-login | |
| uses: NuGet/login@v1 | |
| with: | |
| user: ${{ secrets.NUGET_USER }} | |
| - name: Publish to NuGet.org | |
| run: >- | |
| dotnet nuget push "artifacts/*.nupkg" | |
| --api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" | |
| --source https://api.nuget.org/v3/index.json | |
| --skip-duplicate | |
| deploy-playground: | |
| name: Deploy playground to GitHub Pages | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| needs: build-and-test | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v6 | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Restore playground | |
| run: >- | |
| dotnet restore | |
| samples/Poppler.Net.Playground/Poppler.Net.Playground.csproj | |
| --configfile NuGet.Config | |
| - name: Publish playground | |
| run: >- | |
| dotnet publish | |
| samples/Poppler.Net.Playground/Poppler.Net.Playground.csproj | |
| --configuration Release | |
| --no-restore | |
| --output artifacts/playground | |
| - name: Prepare static site | |
| shell: bash | |
| env: | |
| REPOSITORY_NAME: ${{ github.event.repository.name }} | |
| run: | | |
| site_root="artifacts/playground/wwwroot" | |
| sed -i "s|<base href=\"/\" />|<base href=\"/${REPOSITORY_NAME}/\" />|" "${site_root}/index.html" | |
| cp "${site_root}/index.html" "${site_root}/404.html" | |
| touch "${site_root}/.nojekyll" | |
| - name: Configure GitHub Pages | |
| uses: actions/configure-pages@v5 | |
| - name: Upload GitHub Pages artifact | |
| uses: actions/upload-pages-artifact@v4 | |
| with: | |
| path: artifacts/playground/wwwroot | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 |