mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-10 17:14:34 +01:00
ci: gate builds on the test suite and automate engine bumps
Runs typecheck and tests on every push and before publishing. A daily job rebuilds both vendored tarballs from one commit of the engine fork, verifies a single wasm ends up on disk, and opens a pull request.
This commit is contained in:
1 parent
aee3e0a65a
commit
c72185ed0b
3 files changed
+177
-83
No files matched your search
@@ -29,6 +29,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test:run
|
||||
|
||||
- name: Build distribution
|
||||
run: npm run build
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: tests-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
HUSKY: 0
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Typecheck
|
||||
run: npx tsc --noEmit
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test:run
|
||||
@@ -1,60 +1,54 @@
|
||||
name: Update BentoPDF Viewer
|
||||
name: Update PDF Engine and Viewer
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '17 4 * * *'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: update-engine
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
FORK_URL: https://github.com/alam00000/bentopdf-pdfium-viewer
|
||||
HUSKY: 0
|
||||
|
||||
jobs:
|
||||
update-snippet:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'alam00000/bentopdf'
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Read current upstream version marker
|
||||
id: current-version
|
||||
- name: Read current upstream marker
|
||||
id: current
|
||||
run: |
|
||||
if [ -f vendor/bentopdf-viewer/.upstream-version ]; then
|
||||
CUR=$(cat vendor/bentopdf-viewer/.upstream-version)
|
||||
echo "version=$(cat vendor/bentopdf-viewer/.upstream-version)" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
CUR=""
|
||||
echo "version=" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
echo "version=$CUR" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Read latest commit from our viewer fork
|
||||
id: upstream-version
|
||||
run: |
|
||||
LATEST=$(git ls-remote https://github.com/alam00000/bentopdf-pdfium-viewer refs/heads/main | cut -c1-12)
|
||||
echo "version=$LATEST" >> "$GITHUB_OUTPUT"
|
||||
- name: Read fork HEAD
|
||||
id: upstream
|
||||
run: echo "version=$(git ls-remote "$FORK_URL" refs/heads/main | cut -c1-12)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Should update?
|
||||
id: gate
|
||||
run: |
|
||||
if [ "${{ steps.upstream-version.outputs.version }}" = "${{ steps.current-version.outputs.version }}" ]; then
|
||||
if [ "${{ steps.upstream.outputs.version }}" = "${{ steps.current.outputs.version }}" ]; then
|
||||
echo "run=false" >> "$GITHUB_OUTPUT"
|
||||
echo "No upstream version change detected."
|
||||
echo "Already on ${{ steps.current.outputs.version }}."
|
||||
else
|
||||
echo "run=true" >> "$GITHUB_OUTPUT"
|
||||
echo "Updating from '${{ steps.current-version.outputs.version }}' to '${{ steps.upstream-version.outputs.version }}'"
|
||||
echo "Updating ${{ steps.current.outputs.version }} -> ${{ steps.upstream.outputs.version }}"
|
||||
fi
|
||||
|
||||
- name: Enable corepack (pnpm)
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: corepack enable
|
||||
|
||||
- name: Prepare workspace
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: |
|
||||
mkdir -p vendor/bentopdf-viewer
|
||||
npm config set cache ./\.npm-cache
|
||||
|
||||
- name: Clone our viewer fork
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: git clone --depth 1 --branch main https://github.com/alam00000/bentopdf-pdfium-viewer ./_fork/bentopdf-pdfium-viewer
|
||||
|
||||
- name: Setup Node
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
uses: actions/setup-node@v4
|
||||
@@ -62,82 +56,143 @@ jobs:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
|
||||
- name: Install upstream deps
|
||||
- name: Enable corepack (pnpm)
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
working-directory: ./_fork/bentopdf-pdfium-viewer
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
run: corepack enable
|
||||
|
||||
- name: Build snippet
|
||||
- name: Clone the viewer fork
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
working-directory: ./_fork/bentopdf-pdfium-viewer
|
||||
run: pnpm run build:snippet
|
||||
run: git clone --depth 1 --branch main "$FORK_URL" ./_fork
|
||||
|
||||
- name: Pack snippet tarball
|
||||
- name: Require a published engine
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
working-directory: ./_fork/bentopdf-pdfium-viewer
|
||||
run: |
|
||||
npm pack ./viewers/snippet --pack-destination ../../vendor/bentopdf-viewer
|
||||
ls -l ../../vendor/bentopdf-viewer
|
||||
test -s ./_fork/packages/pdfium/src/vendor/pdfium.wasm
|
||||
test -s ./_fork/packages/pdfium/src/vendor/pdfium.js
|
||||
|
||||
- name: Sanitize tarball (rename pkg and pin deps)
|
||||
- name: Pack the engine
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
env:
|
||||
UPSTREAM_VERSION: ${{ steps.upstream-version.outputs.version }}
|
||||
id: engine
|
||||
run: |
|
||||
TARBALL=$(ls vendor/bentopdf-viewer/*.tgz | sort | tail -n1)
|
||||
set -euo pipefail
|
||||
SHA=${{ steps.upstream.outputs.version }}
|
||||
VENDOR=./_fork/packages/pdfium/src/vendor
|
||||
STAGE=$(mktemp -d)/package
|
||||
mkdir -p "$STAGE"
|
||||
cp "$VENDOR/pdfium.js" "$STAGE/editcore.js"
|
||||
cp "$VENDOR/pdfium.wasm" "$STAGE/editcore.wasm"
|
||||
cat > "$STAGE/package.json" <<JSON
|
||||
{
|
||||
"name": "bentopdf-pdfium",
|
||||
"version": "0.0.0-$SHA",
|
||||
"type": "module",
|
||||
"main": "editcore.js",
|
||||
"exports": { ".": "./editcore.js", "./editcore.wasm": "./editcore.wasm" },
|
||||
"license": "AGPL-3.0"
|
||||
}
|
||||
JSON
|
||||
mkdir -p vendor/bentopdf-pdfium
|
||||
OUT="vendor/bentopdf-pdfium/bentopdf-pdfium-$SHA.tgz"
|
||||
tar -czf "$OUT" -C "$(dirname "$STAGE")" package
|
||||
find vendor/bentopdf-pdfium -maxdepth 1 -name 'bentopdf-pdfium*.tgz' ! -name "$(basename "$OUT")" -delete
|
||||
echo "tarball=$OUT" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build the viewer
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
working-directory: ./_fork
|
||||
run: |
|
||||
pnpm install --no-frozen-lockfile
|
||||
pnpm run build:snippet
|
||||
|
||||
- name: Pack the viewer without a second engine
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
id: viewer
|
||||
run: |
|
||||
set -euo pipefail
|
||||
SHA=${{ steps.upstream.outputs.version }}
|
||||
WORK=$(mktemp -d)
|
||||
(cd ./_fork && npm pack ./viewers/snippet --pack-destination "$WORK" >/dev/null)
|
||||
TMP=$(mktemp -d)
|
||||
tar -xzf "$TARBALL" -C "$TMP"
|
||||
PKG="$TMP/package/package.json"
|
||||
PKG="$PKG" node - <<'NODE'
|
||||
const fs = require("fs");
|
||||
const path = process.env.PKG;
|
||||
const pkg = JSON.parse(fs.readFileSync(path, "utf8"));
|
||||
pkg.name = "bentopdf-viewer";
|
||||
pkg.dependencies = pkg.dependencies || {};
|
||||
// The rollup bundle inlines every @embedpdf/* package, so these
|
||||
// declared deps would only pull unused copies from upstream npm.
|
||||
for (const k of Object.keys(pkg.dependencies)) {
|
||||
if (k.startsWith("@embedpdf/")) delete pkg.dependencies[k];
|
||||
if (k === "preact") pkg.dependencies[k] = "^10.17.0";
|
||||
}
|
||||
fs.writeFileSync(path, JSON.stringify(pkg, null, 2) + "\n");
|
||||
tar -xzf "$WORK"/*.tgz -C "$TMP"
|
||||
rm -f "$TMP/package/dist/pdfium.wasm"
|
||||
PKG="$TMP/package/package.json" node - <<'NODE'
|
||||
const fs = require('fs');
|
||||
const p = process.env.PKG;
|
||||
const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
|
||||
pkg.name = 'bentopdf-viewer';
|
||||
pkg.dependencies = pkg.dependencies || {};
|
||||
// The rollup bundle inlines every @embedpdf/* package, so these
|
||||
// declared deps would only pull unused copies from upstream npm.
|
||||
for (const k of Object.keys(pkg.dependencies)) {
|
||||
if (k.startsWith('@embedpdf/')) delete pkg.dependencies[k];
|
||||
if (k === 'preact') pkg.dependencies[k] = '^10.17.0';
|
||||
}
|
||||
fs.writeFileSync(p, JSON.stringify(pkg, null, 2) + '\n');
|
||||
NODE
|
||||
PKG_VERSION=$(node -p "require('./$TMP/package/package.json').version" 2>/dev/null || node -p "require('$TMP/package/package.json').version")
|
||||
NEW=vendor/bentopdf-viewer/bentopdf-viewer-${PKG_VERSION}.tgz
|
||||
tar -czf "$NEW" -C "$TMP" package
|
||||
# Remove any older snippet tarballs, keep only the new one
|
||||
find vendor/bentopdf-viewer -maxdepth 1 -name 'bentopdf-viewer-*.tgz' ! -name "$(basename "$NEW")" -delete
|
||||
rm -rf "$TMP"
|
||||
ls -l vendor/bentopdf-viewer
|
||||
mkdir -p vendor/bentopdf-viewer
|
||||
OUT="vendor/bentopdf-viewer/bentopdf-viewer-$SHA.tgz"
|
||||
tar -czf "$OUT" -C "$TMP" package
|
||||
find vendor/bentopdf-viewer -maxdepth 1 -name 'bentopdf-viewer-*.tgz' ! -name "$(basename "$OUT")" -delete
|
||||
echo "tarball=$OUT" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Update package.json dependency path
|
||||
- name: Point dependencies at the new tarballs
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: |
|
||||
TARBALL=$(ls vendor/bentopdf-viewer/bentopdf-viewer-*.tgz | sort | tail -n1)
|
||||
node -e "const fs=require('fs');const pkg=require('./package.json');const tar=process.argv[1];pkg.dependencies['bentopdf-viewer']='file:'+tar;fs.writeFileSync('package.json',JSON.stringify(pkg,null,2)+'\n');" "$TARBALL"
|
||||
|
||||
- name: Refresh lockfile
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: npm install --package-lock-only --ignore-scripts
|
||||
|
||||
- name: Write upstream version marker
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: |
|
||||
echo "${{ steps.upstream-version.outputs.version }}" > vendor/bentopdf-viewer/.upstream-version
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
||||
pkg.dependencies['bentopdf-pdfium'] = 'file:' + process.argv[1];
|
||||
pkg.dependencies['bentopdf-viewer'] = 'file:' + process.argv[2];
|
||||
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
|
||||
" "${{ steps.engine.outputs.tarball }}" "${{ steps.viewer.outputs.tarball }}"
|
||||
|
||||
- name: Cleanup upstream clone
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: rm -rf ./_fork
|
||||
|
||||
- name: Install and verify one shared engine
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm install
|
||||
test -s node_modules/bentopdf-pdfium/editcore.wasm
|
||||
if find node_modules/bentopdf-viewer -name '*.wasm' | grep -q .; then
|
||||
echo "::error::viewer package still ships a wasm; the engine would be duplicated"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "bentopdf-pdfium/editcore.wasm" src/js/logic/edit-pdf-page.ts; then
|
||||
echo "::error::the PDF editor no longer points at the shared engine"
|
||||
exit 1
|
||||
fi
|
||||
echo "engine sha256: $(sha256sum node_modules/bentopdf-pdfium/editcore.wasm | cut -c1-16)"
|
||||
|
||||
- name: Typecheck and test
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: |
|
||||
npx tsc --noEmit
|
||||
npm run test:run
|
||||
|
||||
- name: Write upstream marker
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
run: |
|
||||
echo "${{ steps.upstream.outputs.version }}" > vendor/bentopdf-viewer/.upstream-version
|
||||
echo "${{ steps.upstream.outputs.version }}" > vendor/bentopdf-pdfium/.upstream-version
|
||||
|
||||
- name: Create Pull Request
|
||||
if: steps.gate.outputs.run == 'true'
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
commit-message: "build(deps): bump bentopdf-viewer from ${{ steps.current-version.outputs.version }} to ${{ steps.upstream-version.outputs.version }}"
|
||||
title: "build(deps): bump bentopdf-viewer from ${{ steps.current-version.outputs.version }} to ${{ steps.upstream-version.outputs.version }}"
|
||||
commit-message: 'build(deps): bump PDF engine and viewer to ${{ steps.upstream.outputs.version }}'
|
||||
title: 'build(deps): bump PDF engine and viewer to ${{ steps.upstream.outputs.version }}'
|
||||
body: |
|
||||
- Build snippet from the BentoPDF viewer fork via `pnpm run build:snippet`
|
||||
- Pack tarball into `vendor/bentopdf-viewer/` and point dependency to it
|
||||
- Refresh package-lock.json
|
||||
branch: chore/update-bentopdf-viewer
|
||||
Both vendored packages built from one clone of the viewer fork at
|
||||
`${{ steps.upstream.outputs.version }}`, so the text editor and the
|
||||
PDF editor run the same engine.
|
||||
|
||||
- `bentopdf-pdfium` — the engine wasm, packed from the fork's published `src/vendor`
|
||||
- `bentopdf-viewer` — the snippet bundle, packed **without** `dist/pdfium.wasm`
|
||||
|
||||
The viewer loads the shared engine through `EmbedPDF.init({ wasmUrl })`.
|
||||
CI verified a single wasm on disk, typecheck, and the test suite.
|
||||
branch: chore/update-pdf-engine
|
||||
delete-branch: true
|
||||
Reference in new issue
Block a user