Skip to content

Add licence, CI, changelog and screenshots; fix a source-build OpenCV install - #1

Open
killerwolf wants to merge 7 commits into
mainfrom
chore/discoverability
Open

killerwolf wants to merge 7 commits into
mainfrom
chore/discoverability

Conversation

@killerwolf

@killerwolf killerwolf commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Why

A visitor landing on the repo today gets no licence, no CI signal, no history, no screenshots, and no way to judge whether the claims in the README are real. This closes the mechanical gaps and fixes two real bugs — one in the environment spec, two in the CI workflow itself.

The tagline, the topic choices and the scope were agreed with the maintainer; the mechanical parts below are the agent-authored part.

What changed

Legality & signal

  • LICENSE — MIT, Hamdi LAADHARI, 2026.
  • CHANGELOG.md — Keep a Changelog format, with an [Unreleased] section recording the fixes below.
  • CONTRIBUTING.md — dev setup, the conda env create flow, and a short PR checklist.

README

  • Badge row: CI, licence, Python version, topic-consistent keywords.
  • Before/after screenshots from a real 10-page conversion.
  • Replaced adjectives with measured numbers: 2147 kB → 310 kB (ratio 0.145) on a 10-page document, 6761 words, mean confidence 95, 258.1 s, page geometry preserved exactly (593×841 pt).
  • An "if you want X instead" section naming the tools this is not a replacement for.
  • Setup docs for the conda flow, and a pip snippet.

Repo listing — 13 topics and the existing description, applied via the API. Home page left unset (no live URL).

CI — .github/workflows/ci.yml on push/PR to main, Ubuntu, Python 3.11: installs the project, then smoke-tests an actual conversion end to end and asserts the output PDF has selectable text.

The workflow failed twice on first push

Worth recording, because both causes are easy to hit again:

  1. condarc-file takes a path, not inline YAML. The action copied the literal string name: base\nchannels:\n - conda-forge… to ~/.condarc and then tried to open it as a filename — no such file or directory, before the smoke test was ever reached. Fixed by switching to Miniforge, which resolves only from conda-forge and so has no defaults channels and no Anaconda ToS prompt to abort on — the same reasoning the local docs give. That also makes use-mamba: true actually take effect; it was silently ignored before, because the action only enables mamba when the installer ships it and current Miniconda does not.

  2. The env was never activated. GitHub's default Ubuntu shell is bash --noprofile --norc, which does not source the profile conda init writes, so tesseract --version died with command not found even though pdf-ocr had installed fine. Fixed with jobs.smoke.defaults.run.shell: bash -el {0} — set once at job level rather than per step, so a step added later can't silently reintroduce it. This is the action's documented requirement, not a quirk.

  3. Minor: auto-activate-base → auto-activate (deprecated), clearing the last warning.

Bug fixed: conda env create compiled OpenCV from source

opencv-python-headless stopped publishing macosx_13_0_x86_64 wheels after 4.12 — 5.x is macOS 14+ only, and 4.13/4.14 ship only macosx_13_0_arm64 for macOS 13. On a macOS 13 Intel machine pip found no wheel and silently fell back to a source build that took over four minutes and required Xcode CLT. Bounding to <4.13.0 resolves to a real wheel:

opencv_python_headless-4.12.0.88-cp37-abi3-macosx_13_0_x86_64.whl

Verified end to end: a fresh conda env create from the corrected file installs every dependency from a wheel, then converts page 1 successfully (378 words, confidence 95).

The first attempt at this fix pinned <5.0.0, which was insufficient — pip then resolved to 4.14.0.94, which is sdist-only for that platform. <4.13.0 is the correct bound.

Also corrected: the documented ToS workaround did not work

The docs described a conda env create --override-channels invocation that conda rejects outright (that flag belongs to conda create). Neither the nodefaults channel entry nor a .condarc in the working directory prevents the ToS abort — conda runs that check before either takes effect. Only the CONDARC environment variable is honoured early enough. The docs now show the approach that is verified to work.

Verification

  • CI is green — run 36892160409, all 8 steps passing, no warnings.
  • On the runner: tesseract 5.x on PATH, 379 words extracted at confidence 95, size ratio 0.024 against a 0.6 threshold.
  • Locally: conda env create from the corrected environment.yml exits 0 with all wheels and no compiler, and the full pipeline runs in that fresh environment.

Known, deliberately not fixed here

pdfclean/reconstruct.py and pdfclean/pipeline.py still import fitz, which prints The 'fitz' API is deprecated on every invocation. It works today and is outside the scope of a discoverability pass, but it will break when pymupdf removes the alias — worth a follow-up. The CI smoke test above would not catch that; it only checks output text, not stderr.

Note for the reviewer

The first four commits were re-authored with killerwolf@users.noreply.github.com because GitHub rejected the original push (GH007, private email). The tree content is byte-identical to what was reviewed before the rewrite. The local git identity is now set to that address too, so this should not recur.

🤖 Generated with Copilot

killerwolf and others added 4 commits October 1, 2026 05:42
The repo had no licence, which reads as "do not use this" to anyone at a
company. MIT, (c) 2026 Hamdi LAADHARI.

CHANGELOG follows Keep a Changelog and leads with 0.1.0 (matching
pdfclean.__version__), describing what a user gets rather than which files
moved.

CONTRIBUTING documents the conda setup, the project layout, and the
environment traps actually hit: the Anaconda ToS prompt that blocks
`conda env create`, and the incomplete pip section in environment.yml.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
A stranger decides in about thirty seconds whether this is a maintained
thing. The README was thorough but gave no visual proof, no licence, no
build signal, and named no competitors.

- Badge row: CI, MIT, Python 3.11, changelog — each answers a question a
  reader actually has.
- Before/after image of page 1 of the bundled sample, as a full-width
  comparison rather than a thumbnail nobody clicks.
- Every performance claim is now a measured number from a real run of the
  bundled sample: 2147 kB -> 310 kB (0.145), 6761 words, 95 mean
  confidence, 258s for 10 pages, identical 593x841 pt page geometry.
- A "Yes, if / No, if" section naming ocrmypdf, pdfplumber and pypdf as
  the tools to reach for instead, so the right reader self-selects out.
- Setup uses conda, documents the ToS workaround, and keeps a pip route.
- Exit codes, CJK limitation, and links to CONTRIBUTING and LICENSE.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
… images

A badge pointing at a red X is worse than no badge. The workflow installs
the environment, converts page 1 of the bundled sample, and then asserts
the two properties the tool actually promises: more than 200 words of
extractable text (OCR really ran) and an output under 60% of the input
size (the page photo was really discarded). Both assertions were run
locally before being committed.

Images:
- .github/assets/before-after.png — page 1 of the sample, scan vs output.
- .github/assets/social-preview.png — 2560x1280 card for link previews.
  GitHub only accepts this through the web UI, so it still needs uploading.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…source build

`conda env create` stalled for tens of minutes on macOS 13 Intel and then
needed Xcode CLT. opencv-python-headless dropped macosx_13_0_x86_64 wheels
after 4.12 — 5.x is macosx_14_0+ only, and 4.13/4.14 publish only arm64 for
macOS 13 — so pip found no wheel and silently fell back to compiling
OpenCV from source via scikit-build. Verified: the pin resolves to
opencv_python_headless-4.12.0.88-cp37-abi3-macosx_13_0_x86_64.whl, and a
fresh `conda env create` from the corrected file installs every dependency
from a wheel and then converts page 1 successfully.

Also corrects the setup docs, which described a workaround that does not
work. `conda env create` rejects `--override-channels` outright (that flag
belongs to `conda create`), and neither the `nodefaults` channel entry nor
a `.condarc` in the working directory prevents the ToS abort — conda runs
that check before either is applied. Only the CONDARC environment variable
is honoured early enough, so that is what the docs now use. Verified that
a full `conda env create` succeeds with it and without accepting the ToS.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 1, 2026 16:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

killerwolf and others added 3 commits October 1, 2026 18:24
The workflow never passed on GitHub. `setup-miniconda`'s `condarc-file` takes
a *path* to a config file, not inline YAML — the action copied the literal
string "name: base\nchannels:\n  - conda-forge..." and then tried to open it
as a filename, so every run died with `no such file or directory` before
reaching the smoke test.

Rather than commit a throwaway .condarc to route around the Anaconda ToS
prompt, use Miniforge. It only ever resolves packages from conda-forge, so
there are no `defaults` channels in play and no ToS check to fail — the same
reasoning the local docs already give. This also makes `use-mamba: true`
mean something: it was silently ignored before, because the action only
enables mamba when the installer ships it, and current Miniconda does not.

Adds a `tesseract --version` step so a missing OCR engine fails with a clear
message at the install point rather than as a confusing "no words
extracted" assertion at the end.

Verified locally against the real sample scan: tesseract 5.5.3 resolves on
PATH, the conversion yields 379 words at confidence 95, and the size ratio is
0.024 against a 0.6 threshold.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Second failure in a row, same workflow, different cause. Miniforge installed
the `pdf-ocr` environment successfully — but GitHub's default Ubuntu shell is
`bash --noprofile --norc`, which never sources the profile `conda init` writes,
so the first step to use the environment died with `tesseract: command not
found` while `CONDA` pointed at a base prefix that was never activated.

This is the action's documented requirement, not a quirk: every step that
needs the environment must declare `shell: bash -el {0}`. Setting it once as
`jobs.smoke.defaults.run.shell` rather than per step means a step added later
cannot silently forget it and reintroduce this exact failure.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants