jekyll-imgflow 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +609 -0
- data/README.md +26 -0
- data/interface.yml +1 -1
- data/lib/jekyll-imgflow/version.rb +1 -1
- metadata +25 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 378cd2bfd613a2de7d046e60c069d1aee35f7863b4ea3dc203dd2a5eba24d33d
|
|
4
|
+
data.tar.gz: 6f0dbfbfdede93e1831d405ed6b6aaf8f337f55a14187c7c11a05e7dcaf29e29
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 717eb16a4931a2b72dd2bee755711e9b867ab47ee2f49059e7cab0f3ecc67446a535ebfae427c8bc4859957e247eacb8c81b26d74a5099d9f72f154ef487c994
|
|
7
|
+
data.tar.gz: ca5979aa3aaa7810260227c821ce2346433723268a75487d563857bed9d977ac0c6ea79ef10d79670010fea8fd133c392a7e8c8d764f4f7a611f7f7649ccaae1
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.4.5] - 2026-11-10
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `rake docs:demo` — captures the checked-in illustrative overview as
|
|
8
|
+
animated AVIF + WebP + static PNG (headless Chrome + ffmpeg + img2webp;
|
|
9
|
+
build-host tools), embedded in README via `<picture>`. Examples are
|
|
10
|
+
schematic, not generated from a live Jekyll build.
|
|
11
|
+
|
|
12
|
+
### Security
|
|
13
|
+
|
|
14
|
+
- `.audit-allow.json`: allowlisted two dev-only npm advisories with no
|
|
15
|
+
in-range fix — `glob` (GHSA-3g3m-2fjr-6pw4, patched only in 14.x while
|
|
16
|
+
sharp-cli pins ^13) and `minimatch` (GHSA-g3hv-75wg-m249, patched only
|
|
17
|
+
in 11.x while consumers pin ^10), both expiring 2027-02-09. Dev tooling
|
|
18
|
+
only — the gem is pure Ruby.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Gemspec description rewritten in RDoc markup (`==` heading at column 0)
|
|
23
|
+
so rubygems.org renders it as structured markup instead of a single
|
|
24
|
+
paragraph, and now mentions the jekyll-imgflow-vscode companion
|
|
25
|
+
extension.
|
|
26
|
+
- Gemspec metadata links completed: `homepage_uri`, `source_code_uri`,
|
|
27
|
+
`changelog_uri`, and `bug_tracker_uri` for the rubygems.org link panel.
|
|
28
|
+
- `CHANGELOG.md` added to `spec.files` so it ships inside the packaged gem.
|
|
29
|
+
- `jekyll` runtime dependency now bounded `< 5.0` (was unbounded `>= 4.0`).
|
|
30
|
+
|
|
31
|
+
- **Docker test service lifecycle** — service-dependent rake tasks
|
|
32
|
+
(`test_http_providers`, `test_jekyll`, `test_picture`, `test_integration`,
|
|
33
|
+
`test_comprehensive`, `test_all`, `performance_benchmark`, `parallel:slow`)
|
|
34
|
+
now start the Docker test services automatically if they are not running
|
|
35
|
+
and always stop them when the run finishes (pass or fail). Containers no
|
|
36
|
+
longer linger after test runs or pre-push. `start_services`/`stop_services`
|
|
37
|
+
remain for keeping services up across repeated test runs.
|
|
38
|
+
- **Docker daemon auto-start** — `start_docker_services` now launches Docker
|
|
39
|
+
Desktop on macOS when the daemon is down, waiting up to
|
|
40
|
+
`DOCKER_DAEMON_TIMEOUT` (default 120s); on other platforms it aborts with a
|
|
41
|
+
clear message instead of a cryptic `docker-compose` failure. The pre-push
|
|
42
|
+
hook prints the last 20 lines of the HTTP provider lanes on failure instead
|
|
43
|
+
of discarding the output.
|
|
44
|
+
- **Test containers no longer restart automatically** — `docker-compose.test.yml`
|
|
45
|
+
overrides the `restart: unless-stopped` policy inherited from
|
|
46
|
+
`docker-compose.base.yml` with `restart: "no"`, so test containers no longer
|
|
47
|
+
survive Docker daemon or host restarts. The production compose file keeps
|
|
48
|
+
`restart: unless-stopped`.
|
|
49
|
+
- Dev-tooling bump: `webmock` `~> 3.30.0` → `~> 3.34.0` (test-only gem).
|
|
50
|
+
|
|
51
|
+
- CI: Semgrep moved from an inline `pip3 install semgrep==1.177.0` pin to hashed `.github/requirements-ci.txt` (compiled from `requirements-ci.in`, Python 3.12), installed with `--require-hashes`. Bumped Semgrep to 1.180.0. Added `.github/dependabot.yml` covering github-actions, bundler, npm, and the new `/.github` pip requirements.
|
|
52
|
+
|
|
53
|
+
### Dependency updates
|
|
54
|
+
|
|
55
|
+
- Ruby: `rubocop` 1.92.0 → 1.92.2 (patch).
|
|
56
|
+
- npm: `markdownlint-cli2` 0.23.3 → 0.24.0; added `re2js` `^2.9.1`
|
|
57
|
+
override to fix GHSA-gg6h-894w-4m9c (ReDoS in lookbehind matching,
|
|
58
|
+
transitive via markdownlint ≥ 0.42.0).
|
|
59
|
+
- GitHub Actions: `SonarSource/sonarqube-scan-action` v8.3.0 → v8.4.0;
|
|
60
|
+
`DavidAnson/markdownlint-cli2-action` v24.2.0 → v25.0.0;
|
|
61
|
+
Semgrep container 1.182.0 → 1.183.0.
|
|
62
|
+
- Docker image pins: `flyimg/flyimg` 1.12.6 → 1.12.12 → 1.12.13;
|
|
63
|
+
`ghcr.io/imgproxy/imgproxy` v4.0.14 → v4.0.20.
|
|
64
|
+
`docs/docker.md` image table updated to match.
|
|
65
|
+
- Gem updates: `fastimage` 2.4.1 → 2.4.3, `sass-embedded` 1.105.1 → 1.107.1,
|
|
66
|
+
`addressable` 2.9.0 → 2.9.2, `csv` 3.3.6 → 3.3.7, `io-console` 0.9.4 → 0.9.5,
|
|
67
|
+
`mime-types-data` → 3.2026.1027, `parallel_tests` 5.8.0 → 5.9.0.
|
|
68
|
+
- Gem updates: `sass-embedded` 1.107.1 → 1.108.1, `irb` 1.18.0 → 1.19.0,
|
|
69
|
+
`mime-types-data` → 3.2026.1103, `rspec-*` 3.13.x patches;
|
|
70
|
+
`BUNDLED WITH` 2.7.2 → 4.0.24.
|
|
71
|
+
- GitHub Actions: `ruby/setup-ruby` v1.335.0 → v1.338.0.
|
|
72
|
+
|
|
73
|
+
## [0.4.4] - 2026-11-07
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- **Intrinsic `width`/`height` on `<img>`** — the emitted `<img>` (and the
|
|
78
|
+
`<picture>` fallback) now carries the generated file's pixel dimensions,
|
|
79
|
+
read via `FastImage`, so browsers reserve the correct aspect-ratio box
|
|
80
|
+
before download. Fixes layout shift (CLS) / Lighthouse "unsized images".
|
|
81
|
+
User-supplied `img-width:`/`img-height:` always win; dimensions are
|
|
82
|
+
skipped when the file can't be read. Implemented in a new
|
|
83
|
+
`JekyllImgFlow::IntrinsicDimensions` module included by `HtmlGenerator`.
|
|
84
|
+
|
|
85
|
+
## [0.4.3] - 2026-10-06
|
|
86
|
+
|
|
87
|
+
### Security
|
|
88
|
+
|
|
89
|
+
- `sharp` forced to 0.35.5 via npm `overrides` — sharp-cli 6.1.0 pins
|
|
90
|
+
exactly 0.35.4, which the audit gate flags for a use-after-free in
|
|
91
|
+
bundled librsvg (GHSA-wq5f-xc86-pv6w / CVE-2026-96889). The override
|
|
92
|
+
ships libvips with the patched librsvg 2.63.2; remove it once
|
|
93
|
+
sharp-cli bumps its pin. Dev tooling only — the gem is pure Ruby.
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
|
|
97
|
+
- `rake test_http_providers` — runs `provider_meta_testing_spec.rb` once per
|
|
98
|
+
HTTP provider (`IMGFLOW_TEST_PROVIDER` lane: imgproxy, weserv, flyimg),
|
|
99
|
+
giving each its WEBrick source server reachable via host.docker.internal.
|
|
100
|
+
Wired into the local pre-push hook (services auto-start if down); kept out
|
|
101
|
+
of GitHub CI to save runner resources. Without the env var the aggregate
|
|
102
|
+
suite only exercised CLI providers end-to-end.
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- flyimg test image pin bumped 1.12.5 to 1.12.6.
|
|
107
|
+
|
|
108
|
+
## [0.4.2] - 2026-10-06
|
|
109
|
+
|
|
110
|
+
### Security
|
|
111
|
+
|
|
112
|
+
- Dev-tooling audit gate: `scripts/npm-audit.mjs` + `.audit-allow.json`
|
|
113
|
+
wired as the `audit` npm script — patchable transitive deps forced via
|
|
114
|
+
`overrides` (smol-toml 1.9.0, katex 0.18.2); the unpatched braces
|
|
115
|
+
advisory is allowlisted with reason + expiry (dev-only linting).
|
|
116
|
+
- Rakefile `ci` markdownlint pin corrected 0.23.2 to 0.23.3 (matches
|
|
117
|
+
`package.json`).
|
|
118
|
+
|
|
119
|
+
### Added
|
|
120
|
+
|
|
121
|
+
- `JekyllImgFlow::Interface.to_h` — the public `{% imgflow %}` surface
|
|
122
|
+
(operation params, HTML attributes, `markup:` formats, config keys)
|
|
123
|
+
derived from `Parser`/`HtmlGenerator`/`Configuration` constants,
|
|
124
|
+
serialized to a committed `interface.yml` by `rake interface` for
|
|
125
|
+
downstream tooling (e.g. the jekyll-imgflow-vscode parity spec).
|
|
126
|
+
- `spec/interface_spec.rb` pins code ↔ manifest ↔ docs: a stale
|
|
127
|
+
`interface.yml` or undocumented declared item fails the suite.
|
|
128
|
+
- `docs/usage/tag-options.md` — the complete `{% imgflow %}` parameter
|
|
129
|
+
reference (operations, HTML attributes including `link:`/`modal:`, and
|
|
130
|
+
`markup:` output formats); linked from the README docs index and from
|
|
131
|
+
the provider-interface page that previously looked like tag docs.
|
|
132
|
+
|
|
133
|
+
### Changed
|
|
134
|
+
|
|
135
|
+
- The `:site, :post_write` manifest hook is explicitly `priority: :normal`
|
|
136
|
+
(20) — ordinary post-write transforms run first, then
|
|
137
|
+
jekyll-fingerprint-flow (default 12), then jekyll-compress-flow (default
|
|
138
|
+
10) generates compressed siblings from the final fingerprinted HTML.
|
|
139
|
+
- `.ruby-version` is now the single source for the Ruby version: the
|
|
140
|
+
Gemfile reads it directly and the gemspec derives
|
|
141
|
+
`required_ruby_version` from it, joining CI which already did.
|
|
142
|
+
- Added `rake version:check_consistency` (flags Ruby literals that
|
|
143
|
+
drift from `.ruby-version`, including `.rubocop.yml`'s
|
|
144
|
+
`TargetRubyVersion`) and `rake version:pre_release`, which runs it
|
|
145
|
+
together with `version:check_changelog` before tagging.
|
|
146
|
+
- Removed the stale "980 examples" test count from agent steering
|
|
147
|
+
files — counts that change on their own shouldn't be restated.
|
|
148
|
+
|
|
149
|
+
### Fixed
|
|
150
|
+
|
|
151
|
+
- `markup:` was parsed into `raw_options` but never surfaced as
|
|
152
|
+
`markup_format`, so `{% imgflow x.jpg markup:direct_url %}` silently
|
|
153
|
+
rendered the default markup. The parser now maps `markup:`/
|
|
154
|
+
`markup_format:` through, covered by end-to-end tag specs. An explicit
|
|
155
|
+
`markup:` also takes precedence over the automatic `<picture>` upgrade
|
|
156
|
+
for multi-format output.
|
|
157
|
+
- Moved git hooks into `bin/hooks/` as tracked files and switched
|
|
158
|
+
`bin/install-hooks.sh` to set `core.hooksPath` instead of generating
|
|
159
|
+
copies into `.git/hooks/` — the generated `pre-commit` (with
|
|
160
|
+
`semgrep --pro`) had drifted from the installed hook (without it).
|
|
161
|
+
- Corrected hook documentation: `pre-commit` has always run RuboCop +
|
|
162
|
+
Semgrep, not RuboCop alone (AGENTS.md, docs/development.md,
|
|
163
|
+
docs/scripts.md).
|
|
164
|
+
|
|
165
|
+
## [0.4.1] - 2026-09-18
|
|
166
|
+
|
|
167
|
+
### Added
|
|
168
|
+
|
|
169
|
+
- Added Codecov coverage reporting: CI uploads Cobertura XML (via
|
|
170
|
+
`simplecov-cobertura`) after the test suite, with `codecov.yml` status
|
|
171
|
+
checks tracking project and patch coverage.
|
|
172
|
+
- Added SonarCloud quality gate badge to the README.
|
|
173
|
+
|
|
174
|
+
### Changed
|
|
175
|
+
|
|
176
|
+
- Decomposed CodeFactor-flagged complex methods into focused helpers:
|
|
177
|
+
`crop_coords`/`relative_file_path` extracted in `BaseProvider`,
|
|
178
|
+
`prepare_manifest`/`queue_default_tasks`/`queue_tasks_for`/
|
|
179
|
+
`find_default_version` in `BuildTimeProcessor`, per-operation merge
|
|
180
|
+
helpers in `PresetManager`, `matching_variant_path` in `ModalAssets`,
|
|
181
|
+
`build_resize_data` in `ResizeTag`, status/count helpers in
|
|
182
|
+
`TestLogger`, `print_result_counts`/`print_individual_results` in
|
|
183
|
+
`ParallelProviderRunner`, and discovery/validation/output-info helpers
|
|
184
|
+
in `provider_test_helper.rb`, `provider_capabilities_spec.rb`, and
|
|
185
|
+
`TestEnvironment.site_url`.
|
|
186
|
+
- `Config#assign_core_config` now iterates a `CORE_CONFIG_DEFAULTS`
|
|
187
|
+
key→default map instead of repeating `@x = cfg[...] || DEFAULT` lines.
|
|
188
|
+
|
|
189
|
+
### Fixed
|
|
190
|
+
|
|
191
|
+
- Resolved SonarQube analysis findings: pinned `semgrep==1.177.0` with
|
|
192
|
+
`--only-binary :all:` in CI, replaced `[` with `[[` in
|
|
193
|
+
`scripts/run_tests.sh`, and replaced raw `ENV[...]` access with
|
|
194
|
+
`ENV.fetch` defaults in `spec/spec_helper.rb` and
|
|
195
|
+
`spec/support/test_pictures.rb`.
|
|
196
|
+
- `TestLogger.show_status` was unreachable — `def self.` inside
|
|
197
|
+
`class << self` defined it on the singleton-of-singleton, so
|
|
198
|
+
`rake test_status` and `scripts/run_tests.sh status` raised
|
|
199
|
+
`NoMethodError`. The status methods are now regular public class
|
|
200
|
+
methods.
|
|
201
|
+
- `ProviderTestHelper.print_summary` computed a provider summary but
|
|
202
|
+
discarded it; it now logs the summary via `Jekyll.logger`.
|
|
203
|
+
- `ProviderTestHelper.test_single_provider` referenced an undefined
|
|
204
|
+
`context` variable that only worked by accident through RSpec's
|
|
205
|
+
top-level DSL; the caller's context is now passed through explicitly.
|
|
206
|
+
|
|
207
|
+
## [0.4.0] - 2026-09-12
|
|
208
|
+
|
|
209
|
+
### Changed
|
|
210
|
+
|
|
211
|
+
- Extracted shared provider behavior into `BaseProvider` helpers
|
|
212
|
+
(`find_op`, `op?`, `crop_geometry`, `watermark_parts`, `compass_to_short`,
|
|
213
|
+
`input_format_ext`) to eliminate duplicated operation lookups, crop
|
|
214
|
+
parsing, watermark extraction, and compass-position translation across all
|
|
215
|
+
six providers.
|
|
216
|
+
- Introduced `Providers::HttpBase < BaseProvider` to centralize HTTP-provider
|
|
217
|
+
availability checks, request execution, fetching with timeout, and error
|
|
218
|
+
handling. `imgproxy`, `weserv`, and `flyimg` now inherit this scaffolding
|
|
219
|
+
and only provide their service URL and URL-building logic.
|
|
220
|
+
- Introduced `Providers::CliBase < BaseProvider` to centralize the shared
|
|
221
|
+
CLI-provider `execute` skeleton (empty-operations guard, build, run,
|
|
222
|
+
reset). `sharp`, `imagemagick`, and `libvips` now inherit it and only
|
|
223
|
+
provide `build_commands` and optional `before_execute`/`run_command`
|
|
224
|
+
overrides.
|
|
225
|
+
- Added `cli_available?(*commands)`, `temp_path(input_path, suffix)`,
|
|
226
|
+
`alpha_byte_value(opacity)`, and `smartcrop_interestingness(keep)`
|
|
227
|
+
helpers to `BaseProvider`, eliminating repeated `Open3.capture3("which",
|
|
228
|
+
…)` calls, temp-file path `gsub` patterns, `* 255).round` calculations,
|
|
229
|
+
and smartcrop interestingness mappings across all six providers.
|
|
230
|
+
- Moved duplicated `validate_quality`, `valid_numeric?`, and
|
|
231
|
+
`validate_opacity` methods from individual tag classes into `BaseTag`.
|
|
232
|
+
`validate_opacity` is now parameterized by `min:`/`max:` so both
|
|
233
|
+
`OpacityTag` (0.01–0.99) and `WatermarkTag` (0.0–1.0) share one
|
|
234
|
+
implementation.
|
|
235
|
+
- Consolidated `CropTag#get_original_dimensions` into `BaseTag` as a
|
|
236
|
+
raising variant of the existing `get_image_dimensions` helper.
|
|
237
|
+
- Refactored `sharp`, `imagemagick`, and `libvips` to use the shared
|
|
238
|
+
`crop_geometry`, `watermark_parts`, and `op?` helpers, removing the
|
|
239
|
+
repeated crop-parsing block and operation lookups.
|
|
240
|
+
- Removed no-op `translate_quality_to_*` methods from the HTTP providers;
|
|
241
|
+
they returned the input quality unchanged.
|
|
242
|
+
- Decomposed `Parser.detect_operations`, `PresetManager.yaml_to_tags`,
|
|
243
|
+
`TagScanner#parse_tag_markup_simple`, `PictureTagPresetMigrator`
|
|
244
|
+
conversion/description, `CropTag#process`, and `ResizeTag#process` into
|
|
245
|
+
smaller focused helper methods without changing behavior.
|
|
246
|
+
|
|
247
|
+
### Fixed
|
|
248
|
+
|
|
249
|
+
- Weserv provider now handles SVG files without explicit pixel dimensions
|
|
250
|
+
(e.g. `width="100%"` with a large `viewBox`). When no resize or crop
|
|
251
|
+
operation is present, a default `w=2000` parameter is added so librsvg
|
|
252
|
+
rasterizes at a reasonable size instead of the full viewBox dimensions
|
|
253
|
+
(which could exceed 85 megapixels and cause memory exhaustion or
|
|
254
|
+
connection drops).
|
|
255
|
+
- Removed the duplicate `show_status` definition in `scripts/test_logger.rb`
|
|
256
|
+
that shadowed the canonical implementation in `class << self`.
|
|
257
|
+
|
|
258
|
+
## [0.3.3] - 2026-09-11
|
|
259
|
+
|
|
260
|
+
### Added
|
|
261
|
+
|
|
262
|
+
- Added Semgrep and CodeFactor status badges to the README.
|
|
263
|
+
- Documented local Semgrep Pro scans and `semgrep ci` dashboard
|
|
264
|
+
synchronization. GitHub Actions continues to publish CI findings through
|
|
265
|
+
`SEMGREP_APP_TOKEN`, while CodeFactor analyzes the repository through its
|
|
266
|
+
GitHub integration.
|
|
267
|
+
|
|
268
|
+
### Fixed
|
|
269
|
+
|
|
270
|
+
- Replaced shell-interpolated cleanup and test-helper commands with argument
|
|
271
|
+
arrays and process APIs where possible.
|
|
272
|
+
- Added explicit Semgrep suppressions for intentional Jekyll Picture Tag MD5
|
|
273
|
+
compatibility hashes and provider commands that use safe argument arrays or
|
|
274
|
+
shell-escaped paths.
|
|
275
|
+
- Refactored complex test helpers, performance-report helpers, configuration,
|
|
276
|
+
Picture Tag translation, manifest registration, provider pipelines, and
|
|
277
|
+
ImgFlow operation processing without changing behavior.
|
|
278
|
+
- Corrected chained collection-method alignment and shell argument display in
|
|
279
|
+
test utilities.
|
|
280
|
+
- Prevented unchanged rebuilds from persisting the transient manifest state
|
|
281
|
+
created while specialized page usage is reset, keeping the final manifest
|
|
282
|
+
timestamp stable when its content is unchanged.
|
|
283
|
+
- Increased the Flyimg request timeout for large PNG/TIFF processing and
|
|
284
|
+
reduced default slow-test concurrency to avoid exhausting local Docker
|
|
285
|
+
resources during comprehensive provider runs.
|
|
286
|
+
|
|
287
|
+
### Changed
|
|
288
|
+
|
|
289
|
+
- Updated the checked-in performance benchmark report and JSON results from the
|
|
290
|
+
full local provider test run.
|
|
291
|
+
|
|
292
|
+
### Security
|
|
293
|
+
|
|
294
|
+
- Pinned all GitHub Actions used by CI and release workflows to immutable
|
|
295
|
+
commit SHAs to prevent mutable-tag supply-chain changes.
|
|
296
|
+
|
|
297
|
+
## [0.3.2] - 2026-09-09
|
|
298
|
+
|
|
299
|
+
### Fixed
|
|
300
|
+
|
|
301
|
+
- **Modal full-size variants** — modal links now generate optimized variants at
|
|
302
|
+
the smaller of the original image width and configured maximum size, avoiding
|
|
303
|
+
upscaled 2000px outputs for originals such as 1680px images.
|
|
304
|
+
- **Modal format negotiation** — the modal now opens a `<picture>` element with
|
|
305
|
+
AVIF/WebP/PNG sources and the configured fallback format, instead of always
|
|
306
|
+
loading the fallback file directly.
|
|
307
|
+
|
|
308
|
+
### Added
|
|
309
|
+
|
|
310
|
+
- Regression coverage for original-width modal generation and optimized modal
|
|
311
|
+
format selection.
|
|
312
|
+
|
|
313
|
+
## [0.3.1] - 2026-09-09
|
|
314
|
+
|
|
315
|
+
### Fixed
|
|
316
|
+
|
|
317
|
+
- **Sharp CLI format compatibility** — the Sharp provider now translates
|
|
318
|
+
ImgFlow's public `jpg` format name to Sharp CLI's required `jpeg` argument,
|
|
319
|
+
preserving `.jpg` output filenames while supporting Sharp CLI 6.x.
|
|
320
|
+
|
|
321
|
+
### Changed
|
|
322
|
+
|
|
323
|
+
- Development and CI tooling now pins Sharp CLI to `6.1.0`, with Dependabot
|
|
324
|
+
coverage for the npm development dependency tree.
|
|
325
|
+
- CI and local development now share the committed Ruby version from
|
|
326
|
+
`.ruby-version`; `rake ci` mirrors the GitHub Actions checks and runs
|
|
327
|
+
automatically from the pre-push hook.
|
|
328
|
+
- CI uses Ubuntu 26.04 with the required libvips/ImageMagick and AVIF codec
|
|
329
|
+
packages, while Docker-backed HTTP provider tests remain local-only.
|
|
330
|
+
|
|
331
|
+
### Security
|
|
332
|
+
|
|
333
|
+
- Fixed incomplete escaping of backslashes in preset image paths.
|
|
334
|
+
- Replaced the Picture Tag adaptor's backtracking regex with indexed parsing to
|
|
335
|
+
remove the CodeQL polynomial-ReDoS finding.
|
|
336
|
+
|
|
337
|
+
## [0.3.0] - 2026-09-09
|
|
338
|
+
|
|
339
|
+
### Added
|
|
340
|
+
|
|
341
|
+
- **Image modal/lightbox by default** — clicking an `{% imgflow %}` image now opens a full-size modal popup showing the largest generated version. The modal is enabled by default (`image_modal: true` in config) and requires no user setup — CSS and JS are automatically injected into pages that contain modal-enabled images via a `post_render` hook. Disable globally in `_config.yml` with `image_modal: false`. Per-image overrides: `modal:true` forces the modal on (even when config is `false`), `modal:false` forces it off. Images with an explicit `link:` attribute use that link instead (modal is skipped). The modal supports keyboard navigation (Escape to close) and click-outside-to-close.
|
|
342
|
+
|
|
343
|
+
## [0.2.0] - 2026-09-08
|
|
344
|
+
|
|
345
|
+
### Fixed
|
|
346
|
+
|
|
347
|
+
- **Specialized and default versions only produced a single format** — `{% imgflow %}` tags without an explicit `format:`/`formats:` parameter generated only one output file (falling back to the original extension, e.g. `.jpg`) and rendered a simple `<img>` tag instead of a `<picture>` element. `process_variants` now expands to all configured formats (`avif`, `webp`, `png`, `jpg`) when no format is specified, so both default-width and specialized versions produce a `<picture>` with `<source>` tags for modern formats and an `<img>` fallback. Explicit `format:` and `formats:` selections (e.g. `format:avif`, `formats:avif,png`, `formats:webp,jpg`) are respected for both default and specialized widths.
|
|
348
|
+
|
|
349
|
+
### Added
|
|
350
|
+
|
|
351
|
+
- Unit and integration tests verifying explicit format selection: single format (`format:avif`), multiple formats (`formats:avif,png`, `formats:webp,jpg`), and no-format expansion for both default and specialized widths.
|
|
352
|
+
- Tests verifying format config change lifecycle: obsolete default format files are deleted when formats shrink (e.g. `avif,webp,png,jpg` → `avif,png`), missing formats are detected for regeneration when formats grow (e.g. `avif,png` → `avif,png,jpg`), and specialized versions are preserved during default cleanup.
|
|
353
|
+
|
|
354
|
+
## [0.1.11] - 2026-09-07
|
|
355
|
+
|
|
356
|
+
### Added
|
|
357
|
+
|
|
358
|
+
- Rake task `check_docker_images` queries upstream registries (GHCR, Docker Hub) for the latest version tags and compares against the pins in `docker-compose.base.yml`. Use `STRICT=true` to fail the task when any pin is outdated — run before releasing.
|
|
359
|
+
- Rake tasks `start_services` and `stop_services` for starting and stopping test Docker services. `start_services` pulls the latest pinned images before starting containers.
|
|
360
|
+
- Pre-push git hook now runs `check_docker_images` when pushing a `v*` tag, blocking releases with stale Docker image pins.
|
|
361
|
+
- Release workflow (`release.yml`) now verifies Docker image pins are current before building and publishing the gem.
|
|
362
|
+
- Rake tasks `imgflow:presets` and `imgflow:install_presets` for listing and installing built-in YAML presets in consuming sites that load `jekyll-imgflow/tasks` from their Rakefile.
|
|
363
|
+
- Built-in YAML presets `gallery`, `hero`, and `thumbnail` shipped under `lib/jekyll-imgflow/presets/`; user presets in `_data/imgflow/presets/*.yml` override built-ins.
|
|
364
|
+
- `{% imgflow ... preset:NAME %}` tags now expand YAML presets through `PresetManager`, with user tag values overriding preset values and multi-format presets rendering `<picture>` sources plus a fallback image.
|
|
365
|
+
- Rake task `parallel:slow` runs slow tests in parallel using a dynamic work queue across providers, cross-provider comparisons, manifest changes, error handling, and performance benchmarks, utilizing available CPU cores.
|
|
366
|
+
- `TestEnvironment` module (`spec/support/test_environment.rb`) centralizes provider lists, port allocation, and test configuration previously inlined in `spec_helper.rb`, eliminating duplicated constants and port-collision bugs in parallel test runs.
|
|
367
|
+
- `spec/support/provider_integration_helper.rb` extracted shared provider integration test setup (prebuilt sites, server lifecycle, fixture selection) from `spec_helper.rb`.
|
|
368
|
+
- `spec/docker_service_status_spec.rb` adds 23 unit tests for `DockerServiceStatus` covering service path mapping, readiness/failed state detection, compose record parsing (single/array/newline-delimited/invalid JSON), HTTP status (200/503/connection refused/EOF/timeout), container status, and wait/timeout behavior.
|
|
369
|
+
|
|
370
|
+
### Fixed
|
|
371
|
+
|
|
372
|
+
- **Manifest wiped on every server restart** — the manifest now persists under the configured `cache_dir` instead of `_site/`, so Jekyll destination cleanup cannot remove it. The cache directory is excluded from Jekyll watch processing, unchanged manifests are not rewritten, and updates use an atomic temporary-file rename.
|
|
373
|
+
- **Persisted operation comparison** — manifest operations are recursively normalized after JSON persistence, preventing duplicate versions when in-memory symbol keys or values are compared with persisted strings.
|
|
374
|
+
- **Unwritten `.cache_key` dependency** — cache checks no longer require sidecar files that no code path created. Every generated version stores the SHA-256 digest of its source bytes, so changed content is regenerated even when `mtime` is preserved, while timestamp-only changes remain cached.
|
|
375
|
+
- **Incomplete cache checks** — every configured default size/format/quality combination must have a matching manifest entry, current provider, current source digest, and existing output file before an original is skipped. Missing default or specialized outputs and newly configured defaults are regenerated.
|
|
376
|
+
- **Stale generated files** — deleted originals now remove their default and specialized outputs from both source and destination. Defaults removed from configured sizes/formats are pruned with path-safe deletion and empty-directory cleanup.
|
|
377
|
+
- **Deleted-original matching** — cleanup compares complete paths relative to the originals directory instead of extensionless basenames. Animated GIFs remain part of discovery and are no longer mistaken for deleted originals when default conversion is skipped.
|
|
378
|
+
- **Specialized orphan cleanup** — specialized page usage is reset before rendering, rebuilt by rendered tags, cleaned in non-development builds, and saved through the shared manifest.
|
|
379
|
+
- **Double registration** — processed versions remain registered by `OperationProcessor`; only existing outputs skipped while rebuilding a missing manifest are registered by `BuildTimeProcessor`.
|
|
380
|
+
- **Deep permalink and `baseurl` paths** — generated `<img>` and `<source>` paths are root-absolute and include Jekyll's configured `baseurl` without duplicating it. Absolute URLs use the same normalized path.
|
|
381
|
+
- **Stale watch components** — each build refreshes the shared config, manifest, provider, and processor used by Liquid tags, allowing new originals and changed tag operations to use current state.
|
|
382
|
+
- **Legacy manifest migration (v0.1.10 → v0.1.11)** — manifests from v0.1.10 stored operations without `format`/`quality` and had no `file_digest`. These entries are now detected and cleared on load so existing optimized files are re-registered from disk without reprocessing.
|
|
383
|
+
- **Unnecessary reprocessing on render** — `OperationProcessor#process_operation` now checks if the output file already exists and is up-to-date before invoking the provider, preventing redundant Sharp/ImageMagick calls when the manifest is out of sync.
|
|
384
|
+
- **ReDoS in Picture Tag adaptor** — the `{% picture ... %}` extraction regex no longer has polynomial backtracking from redundant `\s*` before `%}`.
|
|
385
|
+
- **ReDoS in opacity validation** — `OpacityTag` and `WatermarkTag` replaced the `\A\d*\.?\d+\z` regex with `Float()` + rescue, eliminating polynomial backtracking on malformed input.
|
|
386
|
+
- **Shell injection in Libvips provider** — all `build_*` methods now return command arrays executed via `Open3.capture3(*array)` (no shell). Chained `&&` commands run as separate Ruby steps, `$(vips header ...)` substitutions are pre-computed in Ruby, and `rm -f` cleanup uses `FileUtils.rm_f`.
|
|
387
|
+
- `preset_manager` is now initialized in `site.imgflow_components` for both `BuildTimeProcessor` and `ImgflowTag`, fixing `undefined method 'build_markup_from_preset' for nil` errors.
|
|
388
|
+
- Preset tag expansion now uses `Shellwords` to correctly parse quoted image paths and preserves quoted option values containing spaces or Danish characters.
|
|
389
|
+
- `BuildTimeProcessor` no longer resets specialized-image `used_on` metadata during incremental builds, preventing deletion of images still used by unrendered pages.
|
|
390
|
+
- `post_write` hook now runs specialized-image cleanup only in non-development, non-incremental builds and saves the manifest afterward.
|
|
391
|
+
- `ImgflowTag` now checks both manifest existence and the actual output file on disk before reusing a version.
|
|
392
|
+
- Default-version up-to-date checks now use source SHA-256 digests and verify the output file exists, regenerating missing or stale versions.
|
|
393
|
+
- **SVG processing with libvips** — the libvips provider now uses `vips thumbnail` (the recommended high-level resize API) instead of `vips VipsResize` for all resize operations. `thumbnail` bounds the SVG render size during load, preventing "image too large" errors on SVGs with large viewBoxes (e.g. 10000x8500). This also improves JPEG performance via shrink-on-load. SVG crop operations use `thumbnail --crop` to avoid coordinate mismatches.
|
|
394
|
+
- **SVG processing with ImageMagick** — the ImageMagick provider now sets `-density` before SVG input files, telling the rsvg delegate to rasterize at a reasonable resolution instead of the full viewBox (10000x8500 = 85M pixels). This gives ~5x speedup (10s → 2s per conversion) with no quality loss since the image is resized afterward. A warning is logged on the first SVG conversion: if the rsvg delegate is not installed, users are advised to install `librsvg` (macOS: `brew install librsvg`, Ubuntu: `apt install librsvg2-bin`) or use a different provider (sharp/libvips) for SVGs.
|
|
395
|
+
- **SVG output filename** — `FilenameGenerator` no longer produces `.svg` as an output format. SVG is a vector input format; image providers always produce raster output. When no format is specified for a specialized version, SVG inputs now fall back to `jpg` (the universal `<img>` fallback).
|
|
396
|
+
- **Nil provider crash** — `ProviderRegistry#current_provider` now logs a single centralized warning when no provider is available and returns `nil` instead of raising, eliminating duplicated warning messages in `BuildTimeProcessor` and `ImgflowTag`. Callers check for `nil` and degrade gracefully (rendering the original image without optimization).
|
|
397
|
+
- **Unknown operation capability check** — `BaseProvider.supports_operation?` now returns `false` for operations not in the `KNOWN_OPERATIONS` whitelist, preventing providers from claiming support for unrecognized operation types.
|
|
398
|
+
- **Provider operation accumulation on failure** — all six providers (`sharp`, `libvips`, `imagemagick`, `imgproxy`, `weserv`, `flyimg`) now reset their operation queue in an `ensure` block. Previously `reset_operations` ran after the provider call, so if the call raised (e.g. an HTTP timeout), operations accumulated across invocations, producing malformed Weserv/Imgproxy/Flyimg URLs with duplicated parameters (`&w=400...&w=800...&output=jpg...&output=avif`) that returned empty responses.
|
|
399
|
+
- **Weserv `/dev/shm` exhaustion** — the Weserv nginx proxy_cache stores up to 250MB in `/dev/shm`, but the Docker default 64MB `/dev/shm` filled during bulk test processing, causing `No space left on device` errors that returned empty responses (`EOFError`). The test container now sets `shm_size: 512mb`.
|
|
400
|
+
- **Weserv nginx directive duplication on restart** — the startup `sed` command appended `weserv_limit_input_pixels` on every container restart, eventually triggering `nginx: [emerg] "weserv_limit_input_pixels" directive is duplicate`. The command now deletes any existing directive before inserting exactly one.
|
|
401
|
+
- **Weserv read timeout** — `Weserv::TIMEOUT` increased from 10 to 30 seconds. The 10s `read_timeout` was too tight under heavy load, causing `EOFError` when the server closed the connection before the response body was fully read.
|
|
402
|
+
- **Docker service startup reliability** — `start_services` now uses `docker compose up -d --pull missing --force-recreate --remove-orphans` instead of an unconditional `docker-compose pull` followed by `up -d`. This avoids redundant image pulls, recreates stale containers that reference removed networks, and removes orphaned containers. On failure, recent container logs are dumped automatically. `stop_services` now passes `--remove-orphans` to clean up stale containers on shutdown.
|
|
403
|
+
- **Docker status helper HTTP rescue** — `DockerServiceStatus.http_status` now rescues `StandardError` instead of a narrow list, catching `EOFError`/`IOError` that occur when a service closes the connection during startup (previously crashed `start_services` with `EOFError: end of file reached`).
|
|
404
|
+
|
|
405
|
+
### Changed
|
|
406
|
+
|
|
407
|
+
- Pinned Docker image tags in `docker-compose.base.yml` for reproducible builds: imgproxy moved from `darthsim/imgproxy:latest` (deprecated Docker Hub location) to `ghcr.io/imgproxy/imgproxy:v4.0.14`; flyimg pinned from `:latest` to `:1.12.5`. Weserv remains on `ghcr.io/weserv/images:5.x` (upstream-recommended branch tag).
|
|
408
|
+
- Removed broken `image_compressor` service from `docker-compose.yml` (had no `image:` key, could never start; no provider implementation existed).
|
|
409
|
+
- Removed dead `image_compressor_url` config plumbing from `Config`, `test_config.rb`, and `parallel_provider_test_helper.rb` — no provider ever consumed it.
|
|
410
|
+
- `docs/docker.md` and `docs/rake.md` updated to reflect new image tags and removed ImageCompressor references.
|
|
411
|
+
- Release process in `AGENTS.md` now starts with `rake check_docker_images` to verify image pins are current before releasing.
|
|
412
|
+
- The manifest is cache metadata and is no longer published into `_site`; legacy source and destination manifests migrate automatically to `cache_dir` and are removed after a successful save.
|
|
413
|
+
- Manifest operation hashes are stored in canonical JSON-compatible form.
|
|
414
|
+
- Generated file cleanup extracted into `GeneratedFileCleaner` for path-safe deletion from both source and destination.
|
|
415
|
+
- `.gitignore` excludes `.cache/imgflow/`; `docs/installation.md` and `docs/ARCHITECTURE.md` document the `cache_dir` option and updated manifest location.
|
|
416
|
+
- Replaced `push_gem.yml` with `release.yml` using official trusted publishing pattern (`rubygems/release-gem@v1`)
|
|
417
|
+
- Removed `continue-on-error: true` from CI workflow so tests and style actually gate
|
|
418
|
+
- Added `rake version:show`, `rake version:bump`, and `rake version:check_changelog` tasks
|
|
419
|
+
- Added CHANGELOG gate to release workflow (fails if entry missing for the version)
|
|
420
|
+
- Dropped reek from Gemfile, gemspec, Rakefile, and deleted `.reek.yml` (KISS)
|
|
421
|
+
- Deleted `bump_version.sh` and `release.sh` — replaced by rake tasks and release workflow
|
|
422
|
+
- Added `bin/install-hooks.sh` for pre-commit (rubocop) and pre-push (rubocop + rspec) hooks
|
|
423
|
+
- Removed dead code: `FilenameGenerator#generate_cache_key` (orphaned by the digest-based cache rewrite), unused `require "shellwords"` in libvips (orphaned by the shell-injection fix), unused `require "English"` in base_provider, and the unused `MARKUP_FORMATS` constant in `HtmlGenerator`.
|
|
424
|
+
- Added `benchmark ~> 0.5.0` as a runtime dependency because processing metrics require it and Ruby warns it will no longer be a default gem in Ruby 4.0.
|
|
425
|
+
- Updated development dependencies: `rubocop` 1.89 → 1.90, `simplecov` 1.1 → 1.2, `parallel` 2.1 → 2.2, `webmock` 3.26.2 → 3.26.4; transitive updates for `commonmarker`, `google-protobuf`, `rbs`, `ruby-lsp`, `sass-embedded`. Remaining outdated gems (`liquid`, `rouge`, `terminal-table`, `unicode-display_width`, `objective_elements`, `diff-lcs`, `json`) are blocked by Jekyll 4.x dependency constraints.
|
|
426
|
+
- Gemspec `icon_uri` updated from `v0.1.10` to `v0.1.11`; gemspec description now lists all six providers; `.DS_Store` files excluded from the packaged gem.
|
|
427
|
+
- README and docs updated: Docker service ports corrected to the new `.env.test` allocation (4022/4026/4030), `cache_dir` and preset usage documented, `parallel:slow` description corrected to reflect the dynamic work queue.
|
|
428
|
+
- **Gemfile/gemspec DRY refactor** — development dependencies are now declared only in the `Gemfile`, not duplicated in the gemspec. The Gemfile uses the `gemspec` directive to pull in runtime dependencies automatically, eliminating version drift between the two files. The gemspec retains only runtime dependencies (`benchmark`, `fastimage`, `jekyll`) and metadata. This follows the [rubygems guide](https://github.com/rubygems/guides/blob/main/gemfile-and-gemspec.md) best practice: runtime deps in gemspec (wide constraints), dev deps in Gemfile (tight constraints, groups, `require: false`).
|
|
429
|
+
- `docs/development.md` updated: release process rewritten to reflect the rake-task/GitHub-Actions workflow (was still describing deleted shell scripts); "Adding Dependencies" section documents the Gemfile/gemspec split; configuration files section describes the new `gemspec` directive pattern.
|
|
430
|
+
- `docs/installation.md` updated: publishing section rewritten to describe the trusted-publishing workflow instead of manual `gem push`; development installation section updated with current version and `gemspec` directive note; stale `0.1.0` version references updated to `0.1.11`.
|
|
431
|
+
- **Documentation DRY consolidation** — eliminated content duplication across docs to prevent drift:
|
|
432
|
+
- Deleted stale `docs/template/{tags,presets,preset-examples}.md` (the template→usage copy system was unmaintained; `presets.md` template documented an obsolete `_IF*.html` mechanism). Removed the `rake generate_docs` task and all references to it.
|
|
433
|
+
- Rewrote `docs/development.md` to link to canonical sources instead of duplicating rake tasks (3×), Docker commands (3×), testing commands (2×), the file tree (duplicates ARCHITECTURE.md), and the release process (duplicates AGENTS.md). Reduced from 297 to 118 lines.
|
|
434
|
+
- Rewrote `docs/README.md` as a lean documentation index — removed duplicated quick-reference blocks, key files list, and architecture summary. Links to canonical docs instead.
|
|
435
|
+
- Trimmed `docs/installation.md`: backend priority list now links to `providers.md` instead of duplicating benchmark numbers; publishing section links to `AGENTS.md` instead of duplicating the release procedure.
|
|
436
|
+
- Trimmed `README.md`: removed duplicated benchmark table (links to `providers.md`); consolidated the two config blocks into one.
|
|
437
|
+
- Trimmed `docs/ARCHITECTURE.md`: config example replaced with a pointer to `installation.md`; fixed `picture_tag_adapter.rb` → `picture_tag_adaptor.rb` spelling.
|
|
438
|
+
- Trimmed `docs/scripts.md`: removed duplicated rake task listing (links to `rake.md`).
|
|
439
|
+
- Fixed broken links: `PARALLEL_TESTING.md` → `parallel_testing.md` in `docs/testing.md`.
|
|
440
|
+
- **Performance benchmark metrics** — added `ProcessingStats` class (`lib/jekyll-imgflow/processing_stats.rb`) that tracks build-level cache hit/miss counts, wall-clock timing grouped by primary operation, and compression ratios per format. The benchmark now compares clean and cached builds for every provider and reports cache performance, operation timing, and compression ratios in JSON and markdown. Deleted `docs/PERFORMANCE_BENCHMARK_ARCHITECTURE.md` after implementing the relevant enhancements; parallel processing metrics were removed because production processing remains sequential.
|
|
441
|
+
|
|
442
|
+
## [0.1.10] - 2026-08-18
|
|
443
|
+
|
|
444
|
+
### Added
|
|
445
|
+
|
|
446
|
+
- **Project branding assets** — moved the full logo and icon to `docs/assets/images/` with project-specific names for GitHub documentation and the next RubyGems release.
|
|
447
|
+
- README branding now uses the repository logo, and the gemspec defines a stable `icon_uri` for the `0.1.10` release.
|
|
448
|
+
|
|
449
|
+
### Fixed
|
|
450
|
+
|
|
451
|
+
- Release script now stages tracked changes only, preventing unrelated untracked files from being included in a release commit.
|
|
452
|
+
- Version bumping now synchronizes `Gemfile.lock` and carries `[Unreleased]` notes into the new version section.
|
|
453
|
+
|
|
454
|
+
### Changed
|
|
455
|
+
|
|
456
|
+
- Release script now creates the GitHub Release page and tag together through `gh release create`, avoiding tag-without-release failures.
|
|
457
|
+
- Renamed `AI_INSTRUCTIONS.md` to `AGENTS.md` and updated tool-specific instruction references.
|
|
458
|
+
- Updated release documentation with the single-command release workflow and GitHub CLI prerequisite.
|
|
459
|
+
- Improved `AGENTS.md` with non-hardcoded test guidance, explicit release prerequisites, a manual-tag prohibition, and supplemental DeepWiki/GitHub resource links.
|
|
460
|
+
|
|
461
|
+
## [0.1.9] - 2026-08-18
|
|
462
|
+
|
|
463
|
+
### Added
|
|
464
|
+
|
|
465
|
+
- Tests for quoted image paths, site-root paths, and exact originals-relative path resolution.
|
|
466
|
+
- Real-world integration coverage for preserving nested output directories and validating generated HTML paths.
|
|
467
|
+
|
|
468
|
+
### Fixed
|
|
469
|
+
|
|
470
|
+
- **Generated post path compatibility** — image references that already include the configured originals directory, such as `assets/images/originals/subdir/photo.jpg`, are now resolved as site-root paths instead of incorrectly prepending the originals directory a second time.
|
|
471
|
+
- **Canonical image path documentation** — user-facing examples now use paths relative to `imgflow.originals`, such as `subdir/more_subdir/photo.jpg`, without exposing the `assets/` directory.
|
|
472
|
+
- **Release tooling** — version consistency checks and release-note extraction now work correctly with an `[Unreleased]` section on macOS and Linux.
|
|
473
|
+
|
|
474
|
+
## [0.1.8] - 2026-08-17
|
|
475
|
+
|
|
476
|
+
### Added
|
|
477
|
+
|
|
478
|
+
- **VS Code companion extension** — added the `jekyll-imgflow-vscode` companion extension. It provides image filename autocomplete for `{% imgflow %}` tags in Markdown and Liquid files, auto-discovers `imgflow.originals` from `_config.yml`, and watches the originals directory for changes.
|
|
479
|
+
- Tests for nested original image resolution, custom `originals` directories, and preserved output directory structure.
|
|
480
|
+
|
|
481
|
+
### Fixed
|
|
482
|
+
|
|
483
|
+
- **Nested original image resolution** — `{% imgflow valdemar/photo.jpg %}` now correctly resolves to `assets/images/originals/valdemar/photo.jpg` instead of `assets/images/valdemar/photo.jpg`. Previously any path containing `/` was joined directly to the site source, ignoring the configured `originals` directory.
|
|
484
|
+
- **Output directory structure preservation** — optimized images now mirror the original directory structure under `assets/images/optimized/`. This prevents name collisions when two different folders contain images with the same basename (e.g. `valdemar/photo.jpg` vs `familie/photo.jpg`).
|
|
485
|
+
- **Build-time manifest path storage** — default versions are written to the source directory, but the manifest relative path was computed against `site.dest`, producing incorrect `/_site/...` entries. Now computed against `site.source` so manifest URLs are correct.
|
|
486
|
+
- **Parallel test race condition in temp file cleanup** — `cleanup_temp_output_files` in `spec_helper.rb` deleted ALL `imgflow-out-*` files in `Dir.tmpdir` with no age check. In parallel mode, process 0's pre-suite cleanup could delete temp files being actively used by other processes, causing sharp to fail with "No input files". Fixed by only deleting files older than 1 hour.
|
|
487
|
+
- **Parallel test race condition in temp file counting test** — `operation_processor_spec.rb` "cleans up temporary files" test compared global `imgflow-out-*` counts before/after processing. In parallel mode, other processes create/delete temp files between snapshots, causing false failures. Fixed by stubbing `PathResolver#temp_output_path` with a test-specific prefix so only this test's temp files are counted.
|
|
488
|
+
|
|
489
|
+
## [0.1.7] - 2026-08-16
|
|
490
|
+
|
|
491
|
+
### Added
|
|
492
|
+
|
|
493
|
+
- **Minimal config support** — users only need to specify `originals` and `output` in `_config.yml`. All other settings (`quality`, `formats`, `sizes`, `backend_priority`, `input_formats`) now have sensible defaults built into the `Config` class. An empty `imgflow:` block works out of the box.
|
|
494
|
+
- **`fallback_format` config option** — controls which format is used for the `<img>` fallback in `<picture>` elements (default: `jpg`). All other formats get `<source>` tags for browsers that support them.
|
|
495
|
+
- **End-to-end regression test** (`spec/realworld_build_spec.rb`) — builds a real Jekyll site with the plugin, runs `jekyll build` twice, and verifies optimized images survive in `_site/` across rebuilds. Uses 12 real-world fixture images (6 JPG, 6 GIF including 1 animated). Tagged `:slow`.
|
|
496
|
+
- **Format priority ordering** — `<source>` tags in `<picture>` elements are now emitted in config format priority order (avif → webp → png → jpg), so the browser picks the best format it supports.
|
|
497
|
+
- Documentation for image referencing limitations (no fuzzy matching/autocomplete yet).
|
|
498
|
+
|
|
499
|
+
### Changed
|
|
500
|
+
|
|
501
|
+
- **`DEFAULT_FORMATS` reordered** from `[webp, avif, jpg, png]` to `[avif, webp, png, jpg]` — AVIF is served first (best compression), WebP as fallback for AVIF, PNG for transparency, JPG as universal `<img>` fallback.
|
|
502
|
+
- **`DEFAULT_BACKEND_PRIORITY` reordered** by benchmark speed: `sharp` (14s) → `libvips` (22s) → `imagemagick` (31s) → `imgproxy` (31s) → `weserv` (30s) → `flyimg`. Previous order had `imgproxy` second despite being slower.
|
|
503
|
+
- **Removed required-field validation** from `Config#initialize` — `originals`, `output`, `input_formats`, `formats`, and `sizes` now fall back to defaults instead of raising `ArgumentError`.
|
|
504
|
+
- **Fixed `HtmlGenerator` fallback logic** — previously all configured formats were treated as "fallback formats", causing all `<source>` tags to be skipped. Only the configured `fallback_format` is now skipped in the `<source>` loop.
|
|
505
|
+
- Updated `benchmark` gem 0.4.1 → 0.5.0 and `rubocop-performance` 1.26.1 → 1.27.0.
|
|
506
|
+
- Updated README.md, docs/installation.md, docs/ARCHITECTURE.md, docs/usage/tags.md with new config format, defaults table, and format priority documentation.
|
|
507
|
+
- Removed 113 unused test fixture images (9.6 MB → 352 KB), keeping only the 12 used by the regression test.
|
|
508
|
+
|
|
509
|
+
### Fixed
|
|
510
|
+
|
|
511
|
+
- **Optimized images wiped from `_site` on rebuild (v0.1.6 bug)** — images were written directly to `_site/` which Jekyll clears at the start of each build. Fixed by writing to the source directory and registering generated files as `Jekyll::StaticFile` objects during the `pre_render` hook, so Jekyll copies them to `_site` during its write phase. This works on the first build (previously required two builds).
|
|
512
|
+
- **`keep_files: ["assets"]` removed from spec_helper.rb** — this setting masked the v0.1.6 wipe bug by preventing Jekyll from cleaning `_site/assets/` between builds. All 1064 tests pass without it.
|
|
513
|
+
- **Manifest path storage** — manifest now stores relative paths with leading slash (`/assets/images/optimized/...`) for consistency with Jekyll conventions.
|
|
514
|
+
|
|
515
|
+
### Improved
|
|
516
|
+
|
|
517
|
+
- Test suite expanded from 1052 to 1064 examples with 0 failures.
|
|
518
|
+
- Line coverage: 97.97%.
|
|
519
|
+
- RuboCop: 0 offenses across all files.
|
|
520
|
+
- `AI_INSTRUCTIONS.md` updated with test infrastructure lessons documenting why the v0.1.6 bug went undetected.
|
|
521
|
+
|
|
522
|
+
## [0.1.6] - 2026-08-15
|
|
523
|
+
|
|
524
|
+
### Added
|
|
525
|
+
|
|
526
|
+
- `AnimatedGifDetector` — pure-Ruby GIF frame counter that detects animated GIFs (multiple Image Descriptor blocks) without any new gem dependencies. Supports both GIF87a and GIF89a.
|
|
527
|
+
- Animated GIFs are now preserved as-is during image processing: `OperationProcessor` copies the original file byte-for-byte instead of resizing or format-converting, which would destroy the animation. A warning is logged so users know the image was skipped.
|
|
528
|
+
- `BuildTimeProcessor` now filters out animated GIFs early in `find_original_images`, so no default versions are queued for them — avoiding unnecessary work and manifest clutter.
|
|
529
|
+
- Test fixtures for animated GIF (`ang-head-animation.gif`) and static single-frame GIF (`static-single-frame.gif`).
|
|
530
|
+
- Test coverage for the animated GIF detection and skip behavior (11 new examples).
|
|
531
|
+
|
|
532
|
+
### Fixed
|
|
533
|
+
|
|
534
|
+
- Animated GIFs were being resized and format-converted, destroying their animation. They are now copied unchanged to the output path while still being tracked in the manifest.
|
|
535
|
+
- Security: updated `json` gem 2.21.1 → 2.21.2 to fix CVE-2026-71847 (crash on truncated duplicate-key streams).
|
|
536
|
+
- Fixed gemspec version mismatch (was still 0.1.5 after bump).
|
|
537
|
+
- Fixed SimpleCov deprecation warning (`add_filter` → `skip`) and removed duplicate `SimpleCov.start` call.
|
|
538
|
+
|
|
539
|
+
### Changed
|
|
540
|
+
|
|
541
|
+
- **Minimum Ruby version bumped from 3.3.0 to 3.4.0.** Tested with Ruby 3.4.10.
|
|
542
|
+
- Updated `.ruby-version` to 3.4.10, `TargetRubyVersion` in `.rubocop.yml` to 3.4, CI matrix to test Ruby 3.4 only.
|
|
543
|
+
- Added `ostruct` and `benchmark` gems to Gemfile to silence Ruby 4.0 stdlib removal warnings.
|
|
544
|
+
- Updated gemspec dev dependency versions to match pinned Gemfile versions.
|
|
545
|
+
|
|
546
|
+
### Improved
|
|
547
|
+
|
|
548
|
+
- Test suite expanded from 1005 to 1052 examples with 0 failures.
|
|
549
|
+
- Line coverage increased to 98.23%.
|
|
550
|
+
- RuboCop: fixed all 19 pre-existing offenses (global variables in `spec_helper.rb`, identical conditional branches in `imgproxy.rb`, `receive_messages` consolidation in test specs). RuboCop now passes with 0 offenses across all 102 files.
|
|
551
|
+
- Pinned all Gemfile dependencies to the newest verified working versions (e.g., `jekyll ~> 4.4.1`, `rubocop ~> 1.89.0`, `simplecov ~> 1.1.1`).
|
|
552
|
+
- Updated transitive dependencies: `csv` 3.3.5 → 3.3.6, `erb` 6.0.6 → 6.0.7, `sass-embedded` 1.101.6 → 1.102.0, `zeitwerk` 2.8.2 → 2.8.3, `rbs` 4.0.3 → 4.1.3, `dry-configurable` 1.3.0 → 1.4.0, `reline` 0.6.3 → 0.7.0, `io-console` 0.8.2 → 0.9.2.
|
|
553
|
+
- Remaining outdated gems (`liquid`, `rouge`, `terminal-table`, `objective_elements`, `diff-lcs`, `unicode-display_width`) are blocked by Jekyll 4.x dependency constraints and cannot be updated until Jekyll 5.x.
|
|
554
|
+
|
|
555
|
+
## [0.1.5] - 2026-07-28
|
|
556
|
+
|
|
557
|
+
### Added
|
|
558
|
+
|
|
559
|
+
- Unique millisecond-precision and random-suffixed temporary directories for provider and test helper output, eliminating flaky filesystem collisions.
|
|
560
|
+
- Explicit format-continuity inference to imgproxy, weserv, and flyimg provider URLs so chained operations preserve output formats.
|
|
561
|
+
|
|
562
|
+
### Changed
|
|
563
|
+
|
|
564
|
+
- `provider_implementation_coverage_spec.rb` now builds `all_providers` from the full provider registry instead of `backend_priority`, so installed CLI tools (Sharp, ImageMagick, Libvips) are tested even when an HTTP provider is selected.
|
|
565
|
+
- Tightened provider URL generation for resize, crop, and smartcrop operations across imgproxy, weserv, and flyimg.
|
|
566
|
+
|
|
567
|
+
### Fixed
|
|
568
|
+
|
|
569
|
+
- imgproxy resize now allows upscaling (`enlarge=1`) and preserves exact-fill dimensions.
|
|
570
|
+
- weserv source URL is now correctly URL-encoded and exact-fill resize is forced with `fit=fill`.
|
|
571
|
+
- weserv Docker test container SSRF policy and DNS resolver relaxed so `host.docker.internal` is reachable.
|
|
572
|
+
- flyimg crop and smartcrop parameter formats now match the Flyimg API (`e_1`, `p1x_...`, `p2x_...`, `smc_1`).
|
|
573
|
+
- flyimg `pns_1` default blocking upscaling is now overridden with `pns_0` for resize operations.
|
|
574
|
+
- flyimg shared memory allocation increased to `1gb` to avoid ImageMagick out-of-memory failures.
|
|
575
|
+
- Provider test suite now passes with 0 failures for default CLI, imgproxy, weserv, and flyimg configurations.
|
|
576
|
+
|
|
577
|
+
### Improved
|
|
578
|
+
|
|
579
|
+
- Overall test reliability and code-coverage reporting (line coverage ~95-96%).
|
|
580
|
+
|
|
581
|
+
## [0.1.1] - 2026-03-12
|
|
582
|
+
|
|
583
|
+
### Added
|
|
584
|
+
|
|
585
|
+
- Comprehensive testing and quality assurance framework
|
|
586
|
+
- Automated release scripts with validation
|
|
587
|
+
- RuboCop code style checking
|
|
588
|
+
- Reek code smell detection
|
|
589
|
+
- Bundler audit security scanning
|
|
590
|
+
- RSpec test framework with coverage reporting
|
|
591
|
+
- Version bumping automation
|
|
592
|
+
- CHANGELOG template generation
|
|
593
|
+
|
|
594
|
+
### Changed
|
|
595
|
+
|
|
596
|
+
- Improved code style with 128+ auto-corrections
|
|
597
|
+
- Standardized project structure and configuration
|
|
598
|
+
- Enhanced development workflow with quality gates
|
|
599
|
+
|
|
600
|
+
### Fixed
|
|
601
|
+
|
|
602
|
+
- Test framework setup and module loading issues
|
|
603
|
+
- Version file path configuration in release scripts
|
|
604
|
+
- RSpec configuration and test dependencies
|
|
605
|
+
|
|
606
|
+
All notable changes to this project will be documented in this file.
|
|
607
|
+
|
|
608
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
609
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
data/README.md
CHANGED
|
@@ -15,6 +15,19 @@ A [Jekyll](https://jekyllrb.com/) plugin for automatic image optimization with m
|
|
|
15
15
|
[](https://github.com/gundestrup/jekyll-imgflow-vscode)
|
|
16
16
|
[](LICENSE)
|
|
17
17
|
|
|
18
|
+
<!-- markdownlint-disable MD033 -->
|
|
19
|
+
<picture>
|
|
20
|
+
<source
|
|
21
|
+
srcset="docs/assets/jekyll-imgflow-demo.avif"
|
|
22
|
+
type="image/avif">
|
|
23
|
+
<source
|
|
24
|
+
srcset="docs/assets/jekyll-imgflow-demo.webp"
|
|
25
|
+
type="image/webp">
|
|
26
|
+
<img src="docs/assets/jekyll-imgflow-demo.png"
|
|
27
|
+
alt="jekyll-imgflow demo">
|
|
28
|
+
</picture>
|
|
29
|
+
<!-- markdownlint-enable MD033 -->
|
|
30
|
+
|
|
18
31
|
## 🚀 Quick Start
|
|
19
32
|
|
|
20
33
|
```bash
|
|
@@ -45,6 +58,19 @@ imgflow:
|
|
|
45
58
|
> For editor autocomplete while writing `{% imgflow %}` tags, install the
|
|
46
59
|
> [VS Code companion extension](https://github.com/gundestrup/jekyll-imgflow-vscode).
|
|
47
60
|
|
|
61
|
+
<!-- markdownlint-disable MD033 -->
|
|
62
|
+
<picture>
|
|
63
|
+
<source
|
|
64
|
+
srcset="https://raw.githubusercontent.com/gundestrup/jekyll-imgflow-vscode/main/docs/assets/image-flow.avif"
|
|
65
|
+
type="image/avif">
|
|
66
|
+
<source
|
|
67
|
+
srcset="https://raw.githubusercontent.com/gundestrup/jekyll-imgflow-vscode/main/docs/assets/image-flow.webp"
|
|
68
|
+
type="image/webp">
|
|
69
|
+
<img src="https://raw.githubusercontent.com/gundestrup/jekyll-imgflow-vscode/main/docs/assets/image-flow.png"
|
|
70
|
+
alt="jekyll-imgflow-vscode: filename, width/format and markup parameter autocomplete">
|
|
71
|
+
</picture>
|
|
72
|
+
<!-- markdownlint-enable MD033 -->
|
|
73
|
+
|
|
48
74
|
## ✨ Key Features
|
|
49
75
|
|
|
50
76
|
- **Multiple Providers**: [Sharp](https://github.com/lovell/sharp), [ImageMagick](https://github.com/ImageMagick/ImageMagick), [LibVips](https://github.com/libvips/libvips), [Imgproxy](https://github.com/imgproxy/imgproxy), [Weserv](https://github.com/weserv/images), [Flyimg](https://github.com/flyimg/flyimg)
|
data/interface.yml
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-imgflow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Svend Gundestrup
|
|
@@ -44,6 +44,9 @@ dependencies:
|
|
|
44
44
|
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
46
|
version: '4.0'
|
|
47
|
+
- - "<"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '5.0'
|
|
47
50
|
type: :runtime
|
|
48
51
|
prerelease: false
|
|
49
52
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -51,15 +54,28 @@ dependencies:
|
|
|
51
54
|
- - ">="
|
|
52
55
|
- !ruby/object:Gem::Version
|
|
53
56
|
version: '4.0'
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
- - "<"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '5.0'
|
|
60
|
+
description: |
|
|
61
|
+
== Jekyll image optimization
|
|
62
|
+
|
|
63
|
+
ImgFlow provides automatic image optimization for Jekyll with multiple
|
|
64
|
+
providers (Sharp, ImageMagick, LibVips, Imgproxy, Weserv, Flyimg) and
|
|
65
|
+
formats (AVIF, WebP, PNG, JPG).
|
|
66
|
+
|
|
67
|
+
* Responsive picture-tag output with automatic format fallbacks
|
|
68
|
+
* Build-time pre-generation and on-demand specialized versions
|
|
69
|
+
* Presets, crop, watermark and size parameters
|
|
70
|
+
|
|
71
|
+
A companion VS Code extension (jekyll-imgflow-vscode) provides tag
|
|
72
|
+
autocomplete: https://github.com/gundestrup/jekyll-imgflow-vscode
|
|
58
73
|
email: svend@gundestrup.dk
|
|
59
74
|
executables: []
|
|
60
75
|
extensions: []
|
|
61
76
|
extra_rdoc_files: []
|
|
62
77
|
files:
|
|
78
|
+
- CHANGELOG.md
|
|
63
79
|
- LICENSE
|
|
64
80
|
- README.md
|
|
65
81
|
- interface.yml
|
|
@@ -113,6 +129,10 @@ licenses:
|
|
|
113
129
|
- AGPL-3.0-or-later
|
|
114
130
|
metadata:
|
|
115
131
|
rubygems_mfa_required: 'true'
|
|
132
|
+
homepage_uri: https://github.com/gundestrup/jekyll-imgflow
|
|
133
|
+
source_code_uri: https://github.com/gundestrup/jekyll-imgflow
|
|
134
|
+
changelog_uri: https://github.com/gundestrup/jekyll-imgflow/blob/main/CHANGELOG.md
|
|
135
|
+
bug_tracker_uri: https://github.com/gundestrup/jekyll-imgflow/issues
|
|
116
136
|
icon_uri: https://raw.githubusercontent.com/gundestrup/jekyll-imgflow/v0.1.11/docs/assets/images/jekyll-imgflow-icon.png
|
|
117
137
|
rdoc_options: []
|
|
118
138
|
require_paths:
|