diff --git a/.github/workflows/check-update.yml b/.github/workflows/check-update.yml new file mode 100644 index 0000000..04078bd --- /dev/null +++ b/.github/workflows/check-update.yml @@ -0,0 +1,167 @@ +name: Check PDFium Update + +on: + schedule: + # 1st and 15th of each month at 08:00 UTC + - cron: '0 8 1,15 * *' + workflow_dispatch: + inputs: + force_update: + description: 'Force update even if version matches' + type: boolean + default: false + target_version: + description: 'Specific bblanchon version to target (e.g. 134.0.6996.0). Leave empty for latest.' + type: string + default: '' + +permissions: + contents: write + +jobs: + check-and-update: + runs-on: ubuntu-latest + + steps: + - name: Detect upstream release + id: upstream + run: | + TARGET_VERSION="${{ github.event.inputs.target_version }}" + + if [ -n "$TARGET_VERSION" ]; then + # Fetch all releases and find the one matching the requested version + PAGE=1 + FOUND=false + while [ "$FOUND" = "false" ] && [ "$PAGE" -le 10 ]; do + RELEASES=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/bblanchon/pdfium-binaries/releases?per_page=30&page=$PAGE") + + MATCH=$(echo "$RELEASES" | jq -r --arg v "$TARGET_VERSION" \ + '.[] | select(.name | test($v)) | @json' | head -1) + + if [ -n "$MATCH" ]; then + RELEASE_JSON="$MATCH" + FOUND=true + else + COUNT=$(echo "$RELEASES" | jq length) + if [ "$COUNT" -lt 30 ]; then break; fi + PAGE=$((PAGE + 1)) + fi + done + + if [ "$FOUND" = "false" ]; then + echo "::error::Could not find release matching version $TARGET_VERSION" + exit 1 + fi + else + # Fetch latest release + RELEASE_JSON=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + https://api.github.com/repos/bblanchon/pdfium-binaries/releases/latest) + fi + + RELEASE_NAME=$(echo "$RELEASE_JSON" | jq -r '.name') + RELEASE_ID=$(echo "$RELEASE_JSON" | jq -r '.id') + TAG_NAME=$(echo "$RELEASE_JSON" | jq -r '.tag_name') + + # Extract version from name like "PDFium v134.0.6996.0" or "PDFium 134.0.6996.0" + UPSTREAM_VERSION=$(echo "$RELEASE_NAME" | grep -oP '\d+\.\d+\.\d+\.\d+') + + if [ -z "$UPSTREAM_VERSION" ]; then + echo "::error::Could not parse version from release name: $RELEASE_NAME" + exit 1 + fi + + echo "version=$UPSTREAM_VERSION" >> "$GITHUB_OUTPUT" + echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" + echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT" + echo "Upstream: $UPSTREAM_VERSION (release ID: $RELEASE_ID, tag: $TAG_NAME)" + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true + ref: master + + - name: Read current version + id: current + run: | + CURRENT_VERSION=$(grep -oP '(?<=).*(?=)' src/Directory.Build.props) + echo "version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT" + echo "Current version: $CURRENT_VERSION" + + - name: Compare versions + id: compare + run: | + UPSTREAM="${{ steps.upstream.outputs.version }}" + CURRENT="${{ steps.current.outputs.version }}" + FORCE="${{ github.event.inputs.force_update }}" + + if [ "$UPSTREAM" = "$CURRENT" ] && [ "$FORCE" != "true" ]; then + echo "No update needed. Upstream ($UPSTREAM) matches current ($CURRENT)." + echo "needs_update=false" >> "$GITHUB_OUTPUT" + else + echo "Update available: $CURRENT -> $UPSTREAM (force=$FORCE)" + echo "needs_update=true" >> "$GITHUB_OUTPUT" + fi + + - name: Verify NuGet package exists + if: steps.compare.outputs.needs_update == 'true' + run: | + VERSION="${{ steps.upstream.outputs.version }}" + PACKAGE="bblanchon.PDFium.Win32" + URL="https://api.nuget.org/v3-flatcontainer/${PACKAGE,,}/index.json" + + echo "Checking NuGet for $PACKAGE version $VERSION..." + VERSIONS=$(curl -s "$URL" | jq -r '.versions[]') + + if echo "$VERSIONS" | grep -qx "$VERSION"; then + echo "$PACKAGE $VERSION found on NuGet." + else + echo "::error::$PACKAGE $VERSION not found on NuGet. The upstream GitHub release may have been published before NuGet packages. Try again later." + exit 1 + fi + + - name: Install .NET + if: steps.compare.outputs.needs_update == 'true' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.* + + - name: Install native dependencies + if: steps.compare.outputs.needs_update == 'true' + run: sudo apt-get update && sudo apt-get install -y libc6-dev + + - name: Build bindings generator + if: steps.compare.outputs.needs_update == 'true' + run: dotnet build src/PDFiumCoreBindingsGenerator/PDFiumCoreBindingsGenerator.csproj -c Release + + - name: Generate bindings + if: steps.compare.outputs.needs_update == 'true' + run: | + dotnet src/PDFiumCoreBindingsGenerator/bin/Release/net8.0/PDFiumCoreBindingsGenerator.dll \ + ${{ steps.upstream.outputs.release_id }} true 0 + + - name: Build PDFiumCore + if: steps.compare.outputs.needs_update == 'true' + run: | + dotnet build src/PDFiumCore -c Release + + - name: Run tests + if: steps.compare.outputs.needs_update == 'true' + run: dotnet test src/PDFiumCore.Tests -c Release + + - name: Commit, tag and push + if: steps.compare.outputs.needs_update == 'true' + run: | + VERSION="${{ steps.upstream.outputs.version }}" + TAG_NAME="${{ steps.upstream.outputs.tag_name }}" + TAG="v${VERSION}" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git add -A + git commit -m "PDFium version v${VERSION} ${TAG_NAME} [master]" + git tag "$TAG" + git push origin master "$TAG" diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index bc0be2d..f8be16e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -3,20 +3,20 @@ name: Build, Pack & Publish on: push: branches: - - '*' + - master tags: - 'v*' pull_request: branches: - - '*' + - master jobs: build: runs-on: ubuntu-latest - + steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true @@ -28,40 +28,42 @@ jobs: source-url: https://api.nuget.org/v3/index.json env: NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} - + - name: Download libraries - run: ./download_package.sh + run: | + dotnet build src/PDFiumCoreBindingsGenerator/PDFiumCoreBindingsGenerator.csproj -c Release + dotnet src/PDFiumCoreBindingsGenerator/bin/Release/net8.0/PDFiumCoreBindingsGenerator.dll latest true - name: Build run: dotnet build src/PDFiumCore -c Release - + - name: Pack run: dotnet pack src/PDFiumCore -c Release -o ./artifacts - + - name: Unit tests run: dotnet test src/PDFiumCore.Tests -c Release - + - name: Export artifacts uses: actions/upload-artifact@v4 with: path: | artifacts/*.nupkg artifacts/*.snupkg - + - name: Get tag name if: startsWith(github.ref, 'refs/tags/') - uses: olegtarasov/get-tag@v2.1 id: tagName + run: echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" - name: Create release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/') with: name: "PDFiumCore ${{ steps.tagName.outputs.tag }} Released" files: | artifacts/*.nupkg artifacts/*.snupkg - + - name: Push Nuget packages if: startsWith(github.ref, 'refs/tags/') - run: dotnet nuget push artifacts/*.nupkg --api-key ${{ secrets.ORG_NUGET_AUTH_TOKEN }} --skip-duplicate \ No newline at end of file + run: dotnet nuget push artifacts/*.nupkg --api-key ${{ secrets.ORG_NUGET_AUTH_TOKEN }} --skip-duplicate diff --git a/src/PDFiumCoreBindingsGenerator/PDFiumCoreLibrary.cs b/src/PDFiumCoreBindingsGenerator/PDFiumCoreLibrary.cs index 5aefa2b..284a216 100644 --- a/src/PDFiumCoreBindingsGenerator/PDFiumCoreLibrary.cs +++ b/src/PDFiumCoreBindingsGenerator/PDFiumCoreLibrary.cs @@ -1,5 +1,6 @@ using System.IO; using System.Linq; +using System.Runtime.InteropServices; using CppSharp; using CppSharp.AST; using CppSharp.Generators; @@ -34,7 +35,12 @@ public void Postprocess(Driver driver, ASTContext ctx) public void Setup(Driver driver) { var includeDirectory = Path.Combine(_directoryName, "include"); - driver.ParserOptions.SetupMSVC(VisualStudioVersion.Latest); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + driver.ParserOptions.SetupMSVC(VisualStudioVersion.Latest); + } + var options = driver.Options; options.GeneratorKind = GeneratorKind.CSharp; //options.Verbose = true;