• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thumbor / thumbor-plugins / 40602191909
99%

Build:
DEFAULT BRANCH: master
Ran 27 Oct 2026 11:27PM UTC
Jobs 7
Files 14
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

27 Oct 2026 11:26PM UTC coverage: 99.254% (-0.7%) from 100.0%
40602191909

push

github

web-flow
fix(optipng): run optipng without a shell, coerce the level, add a timeout (#121)

The optimizer ran optipng through subprocess.call(shell=True) with a
formatted string and ignored the exit status. Nothing from the request
reaches that string (thumbor supplies the temp file names and the rest
comes from thumbor.conf), but the shell was unnecessary, a failure left
output_file empty, and thumbor turns an empty output into a 500 instead of
serving the unoptimized PNG. OPTIPNG_LEVEL was formatted with %d, so the
string value that a thumbor.conf written like the README examples produces
raised TypeError on every PNG request. There was no timeout either, and
with the default ENGINE_THREADPOOL_SIZE of 0 a slow run blocks the event
loop.

optipng now runs as an argument list under OPTIPNG_TIMEOUT (default 30 seconds,
0 disables). A non-zero exit, an empty output or a timeout logs a warning and
copies the input over the output so thumbor serves the original. OPTIPNG_LEVEL
and OPTIPNG_TIMEOUT are converted when the optimizer is built, since both can
arrive as strings from thumbor.conf or --use-environment. A level that is not
an integer of at least 1 (-o0 with -force exits 1) or a timeout that is
negative, infinite or not a number disables the optimizer with an error, like a
missing binary does; levels above 7 are passed as 7, which optipng treats
identically. -quiet is gone so the warning carries optipng's diagnostics, and
the <output>.bak copy that -keep left behind on every request is removed. Unit
tests use a real temp directory and a fake subprocess.run instead of patching
os.path.isfile and os.access; tearDown stopped the os.access mock rather than
its patcher, so that patch was never undone.

34 of 34 new or added lines in 2 files covered. (100.0%)

266 of 268 relevant lines covered (99.25%)

0.99 hits per line

Jobs
ID Job ID Ran Files Coverage
1 run-optimizers/optipng - 40602191909.1 27 Oct 2026 11:27PM UTC 2
100.0
GitHub Action Run
2 run-optimizers/mozjpeg - 40602191909.2 27 Oct 2026 11:28PM UTC 2
100.0
GitHub Action Run
3 run-optimizers/jp2 - 40602191909.3 27 Oct 2026 11:27PM UTC 2
91.67
GitHub Action Run
4 run-optimizers/pngcrush - 40602191909.4 27 Oct 2026 11:27PM UTC 2
100.0
GitHub Action Run
5 run-optimizers/gifv - 40602191909.5 27 Oct 2026 11:27PM UTC 2
100.0
GitHub Action Run
6 run-optimizers/jpegrecompress - 40602191909.6 27 Oct 2026 11:27PM UTC 2
100.0
GitHub Action Run
7 run-optimizers/pngquant - 40602191909.7 27 Oct 2026 11:27PM UTC 2
100.0
GitHub Action Run
Source Files on build 40602191909
  • Tree
  • List 14
  • Changed 0
  • Source Changed 0
  • Coverage Changed 0
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #40602191909
  • f5a03198 on github
  • Prev Build on master (#40602141291)
  • Next Build on master (#40602420937)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc