Skip to content

Release 0.13.0-rc.1 #82

Release 0.13.0-rc.1

Release 0.13.0-rc.1 #82

Workflow file for this run

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