Skip to content

Commit 7bf7f0e

Browse files
kdroidFilterclaude
andcommitted
ci: auto-release pdfium when bblanchon ships new binaries
Daily cron polls bblanchon/pdfium-binaries releases, bumps the libs.versions.toml pin on a temporary branch, runs the full multiplatform native build + :pdfium:check on that branch, then fast-forwards master, pushes the v<version> tag and publishes to Maven Central inline. If any stage fails the bump branch stays for debugging and nothing reaches Maven. build-natives.yaml gains a `ref` input so the reusable workflow can target the bump branch instead of the triggering ref. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7ccd22f commit 7bf7f0e

2 files changed

Lines changed: 237 additions & 0 deletions

File tree

.github/workflows/build-natives.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ name: Build PDFium JNI Natives
22

33
on:
44
workflow_call:
5+
inputs:
6+
ref:
7+
description: Git ref to check out. Defaults to the workflow's triggering ref.
8+
type: string
9+
required: false
10+
default: ''
511

612
jobs:
713
linux:
@@ -17,6 +23,8 @@ jobs:
1723
steps:
1824
- name: Checkout repo
1925
uses: actions/checkout@v4
26+
with:
27+
ref: ${{ inputs.ref }}
2028

2129
- name: Setup JDK 21
2230
uses: actions/setup-java@v4
@@ -61,6 +69,8 @@ jobs:
6169
steps:
6270
- name: Checkout repo
6371
uses: actions/checkout@v4
72+
with:
73+
ref: ${{ inputs.ref }}
6474

6575
- name: Setup JDK 21
6676
uses: actions/setup-java@v4
@@ -95,6 +105,8 @@ jobs:
95105
steps:
96106
- name: Checkout repo
97107
uses: actions/checkout@v4
108+
with:
109+
ref: ${{ inputs.ref }}
98110

99111
- name: Setup JDK 21
100112
uses: actions/setup-java@v4
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
name: Auto-release PDFium
2+
3+
on:
4+
schedule:
5+
- cron: '0 3 * * *' # daily 03:00 UTC
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
11+
concurrency:
12+
group: pdfium-auto-release
13+
cancel-in-progress: false
14+
15+
jobs:
16+
detect:
17+
runs-on: ubuntu-latest
18+
outputs:
19+
needs_bump: ${{ steps.compare.outputs.needs_bump }}
20+
chromium_tag: ${{ steps.upstream.outputs.tag_name }}
21+
full_version: ${{ steps.upstream.outputs.full_version }}
22+
branch: ${{ steps.push.outputs.branch }}
23+
steps:
24+
- name: Checkout repo
25+
uses: actions/checkout@v4
26+
27+
- name: Resolve latest bblanchon release
28+
id: upstream
29+
env:
30+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
run: |
32+
set -euo pipefail
33+
release=$(gh api repos/bblanchon/pdfium-binaries/releases/latest)
34+
tag_name=$(echo "$release" | jq -r .tag_name)
35+
name=$(echo "$release" | jq -r .name)
36+
chromium_branch=${tag_name#chromium/}
37+
full_version=$(echo "$name" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1)
38+
if [ -z "$full_version" ]; then
39+
echo "::error::Could not parse full version from release name: $name"
40+
exit 1
41+
fi
42+
echo "tag_name=$tag_name" >> "$GITHUB_OUTPUT"
43+
echo "chromium_branch=$chromium_branch" >> "$GITHUB_OUTPUT"
44+
echo "full_version=$full_version" >> "$GITHUB_OUTPUT"
45+
echo "Latest upstream: $tag_name ($full_version)"
46+
47+
- name: Compare with current pin
48+
id: compare
49+
run: |
50+
set -euo pipefail
51+
current=$(grep '^pdfium-bblanchon' gradle/libs.versions.toml | sed -E 's/.*"([^"]+)".*/\1/')
52+
echo "Current pin: $current"
53+
if [ "$current" = "${{ steps.upstream.outputs.tag_name }}" ]; then
54+
echo "needs_bump=false" >> "$GITHUB_OUTPUT"
55+
echo "Already up-to-date — nothing to do."
56+
else
57+
echo "needs_bump=true" >> "$GITHUB_OUTPUT"
58+
fi
59+
60+
- name: Check tag does not already exist
61+
if: steps.compare.outputs.needs_bump == 'true'
62+
run: |
63+
set -euo pipefail
64+
tag="v${{ steps.upstream.outputs.full_version }}"
65+
if git ls-remote --tags origin "refs/tags/$tag" | grep -q "$tag"; then
66+
echo "::error::Tag $tag already exists. Refusing to re-release. Use a manual suffix (e.g. ${tag}b) if a re-publish is needed."
67+
exit 1
68+
fi
69+
70+
- name: Push bump branch
71+
if: steps.compare.outputs.needs_bump == 'true'
72+
id: push
73+
run: |
74+
set -euo pipefail
75+
branch="bump/pdfium-${{ steps.upstream.outputs.chromium_branch }}"
76+
echo "branch=$branch" >> "$GITHUB_OUTPUT"
77+
git config user.name "github-actions[bot]"
78+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
79+
git checkout -B "$branch"
80+
sed -i -E "s|^pdfium-bblanchon = .*|pdfium-bblanchon = \"${{ steps.upstream.outputs.tag_name }}\"|" gradle/libs.versions.toml
81+
git add gradle/libs.versions.toml
82+
git commit -m "chore(pdfium): bump to ${{ steps.upstream.outputs.tag_name }} (${{ steps.upstream.outputs.full_version }})"
83+
git push --force origin "$branch"
84+
85+
build-natives:
86+
needs: detect
87+
if: needs.detect.outputs.needs_bump == 'true'
88+
uses: ./.github/workflows/build-natives.yaml
89+
with:
90+
ref: ${{ needs.detect.outputs.branch }}
91+
92+
check:
93+
needs: [detect, build-natives]
94+
if: needs.detect.outputs.needs_bump == 'true'
95+
runs-on: ubuntu-latest
96+
steps:
97+
- name: Checkout bump branch
98+
uses: actions/checkout@v4
99+
with:
100+
ref: ${{ needs.detect.outputs.branch }}
101+
102+
- name: Download PDFium JNI natives
103+
uses: actions/download-artifact@v4
104+
with:
105+
path: pdfium/src/jvmMain/resources/pdfium/native/
106+
pattern: 'pdfium-jni-*'
107+
merge-multiple: true
108+
109+
- name: Verify all JNI natives present
110+
run: |
111+
EXPECTED=(
112+
"pdfium/src/jvmMain/resources/pdfium/native/linux-x86-64/libpdfiumjni.so"
113+
"pdfium/src/jvmMain/resources/pdfium/native/linux-aarch64/libpdfiumjni.so"
114+
"pdfium/src/jvmMain/resources/pdfium/native/darwin-aarch64/libpdfiumjni.dylib"
115+
"pdfium/src/jvmMain/resources/pdfium/native/darwin-x86-64/libpdfiumjni.dylib"
116+
"pdfium/src/jvmMain/resources/pdfium/native/win32-x86-64/pdfiumjni.dll"
117+
"pdfium/src/jvmMain/resources/pdfium/native/win32-arm64/pdfiumjni.dll"
118+
)
119+
MISSING=0
120+
for f in "${EXPECTED[@]}"; do
121+
if [ -f "$f" ]; then
122+
echo "OK: $f ($(wc -c < "$f") bytes)"
123+
else
124+
echo "MISSING: $f" >&2
125+
MISSING=1
126+
fi
127+
done
128+
if [ "$MISSING" = "1" ]; then exit 1; fi
129+
130+
- name: Setup JDK 21
131+
uses: actions/setup-java@v4
132+
with:
133+
distribution: 'temurin'
134+
java-version: '21'
135+
136+
- name: Setup Gradle
137+
uses: gradle/actions/setup-gradle@v5
138+
139+
- name: Run :pdfium:check
140+
run: ./gradlew :pdfium:check --continue
141+
142+
publish:
143+
needs: [detect, check]
144+
if: needs.detect.outputs.needs_bump == 'true'
145+
# macOS runner builds darwin JNI inline; Linux/Windows JNI come from artefacts.
146+
# Same setup as publish-maven.yaml so the published artefact set is identical.
147+
runs-on: macos-latest
148+
steps:
149+
- name: Checkout bump branch
150+
uses: actions/checkout@v4
151+
with:
152+
ref: ${{ needs.detect.outputs.branch }}
153+
fetch-depth: 0
154+
155+
- name: Fast-forward master to bump branch
156+
run: |
157+
set -euo pipefail
158+
git config user.name "github-actions[bot]"
159+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
160+
if ! git merge-base --is-ancestor origin/master HEAD; then
161+
echo "::error::Bump branch diverged from master since CI started. Aborting; the next cron run will retry from current master."
162+
exit 1
163+
fi
164+
git push origin HEAD:master
165+
166+
- name: Create and push release tag
167+
run: |
168+
set -euo pipefail
169+
tag="v${{ needs.detect.outputs.full_version }}"
170+
git tag "$tag"
171+
git push origin "$tag"
172+
173+
- name: Delete bump branch
174+
run: git push origin --delete "${{ needs.detect.outputs.branch }}" || true
175+
176+
- name: Download PDFium JNI natives
177+
uses: actions/download-artifact@v4
178+
with:
179+
path: pdfium/src/jvmMain/resources/pdfium/native/
180+
pattern: 'pdfium-jni-*'
181+
merge-multiple: true
182+
183+
- name: Verify all JNI natives present
184+
run: |
185+
EXPECTED=(
186+
"pdfium/src/jvmMain/resources/pdfium/native/linux-x86-64/libpdfiumjni.so"
187+
"pdfium/src/jvmMain/resources/pdfium/native/linux-aarch64/libpdfiumjni.so"
188+
"pdfium/src/jvmMain/resources/pdfium/native/darwin-aarch64/libpdfiumjni.dylib"
189+
"pdfium/src/jvmMain/resources/pdfium/native/darwin-x86-64/libpdfiumjni.dylib"
190+
"pdfium/src/jvmMain/resources/pdfium/native/win32-x86-64/pdfiumjni.dll"
191+
"pdfium/src/jvmMain/resources/pdfium/native/win32-arm64/pdfiumjni.dll"
192+
)
193+
MISSING=0
194+
for f in "${EXPECTED[@]}"; do
195+
if [ -f "$f" ]; then
196+
echo "OK: $f ($(wc -c < "$f") bytes)"
197+
else
198+
echo "MISSING: $f" >&2
199+
MISSING=1
200+
fi
201+
done
202+
if [ "$MISSING" = "1" ]; then exit 1; fi
203+
204+
- name: Setup JDK 21
205+
uses: actions/setup-java@v4
206+
with:
207+
distribution: 'temurin'
208+
java-version: '21'
209+
210+
- name: Setup Gradle
211+
uses: gradle/actions/setup-gradle@v5
212+
213+
- name: Publish to Maven Central
214+
# GITHUB_REF override drives pdfium/build.gradle.kts publishVersion (reads
215+
# GITHUB_REF and strips refs/tags/v). The tag was pushed by GITHUB_TOKEN
216+
# so publish-maven.yaml will not fire — publishing inline avoids the
217+
# recursive-trigger gap and keeps everything in one run.
218+
env:
219+
GITHUB_REF: refs/tags/v${{ needs.detect.outputs.full_version }}
220+
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVENCENTRALUSERNAME }}
221+
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVENCENTRALPASSWORD }}
222+
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNINGINMEMORYKEY }}
223+
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNINGKEYID }}
224+
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNINGPASSWORD }}
225+
run: ./gradlew :pdfium:publishAndReleaseToMavenCentral --no-configuration-cache

0 commit comments

Comments
 (0)