Skip to content

Modernize the environment and add the new minPctChange option. #324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

alexdupre
Copy link
Contributor

Changes:

  • switch docker image from Ubuntu 20 to lightweight Alpine
  • switch from Node 12 to Node 22
  • use the latest sharp release (0.34.2) with built-in vips library
  • use 'npm ci' instead of 'npm install'
  • replace the deprecated set-output console log
  • fix octokit deprecation and import
  • add new minPctChange option to control the minimum saving to commit optimized images

The very old sharp/vips versions together with the fixed 1% size change were causing webp images to be continuosly optimized until the actual quality became very low.

Changes:
- switch docker image from Ubuntu 20 to lightweight Alpine
- switch from Node 12 to Node 22
- use the latest sharp release (0.34.2) with built-in vips library
- use 'npm ci' instead of 'npm install'
- replace the deprecated set-output console log
- fix octokit deprecation and import
- add new minPctChange option to control the minimum saving to
  commit optimized images

The very old sharp/vips versions together with the fixed 1% size
change were causing webp images to be continuosly optimized until
the actual quality became very low.
@CLAassistant
Copy link

CLAassistant commented Jun 20, 2025

CLA assistant check
All committers have signed the CLA.

@benschwarz
Copy link
Member

Hey @alexdupre! Great PR, thanks so much for your efforts so far.

Mozjpeg hasn't needed to be compiled for a while now, so it's long been on my mind to circle back and update image-actions. Thanks again for taking on this work.

I can see atm the docker build is failing, once you've had the chance to fix I'll be happy to do a full review and get this released 🛳️

Given that the Dockerfile is currently standard node alpine with no other additions, I think we can convert the action to be JS based, removing the need for docker all together. Are you happy to incorporate that into your changeset too?

@alexdupre
Copy link
Contributor Author

The Docker image works, the old tests are now broken. I cannot have a look before a couple of weeks, perhaps you can fix them in the meanwhile?

I tried to create a JS only action, but I wasn't successful, given that it requires the native component for vips and 'ncc' wasn't able to package it.

@benschwarz
Copy link
Member

The Docker image works, the old tests are now broken.

In checking I can see that the test that failed is caused by an unexpected write to GITHUB_OUTPUT:

TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined

How did you test your changes?

I tried to create a JS only action, but I wasn't successful, given that it requires the native component for vips and 'ncc' wasn't able to package it.

As far as I am aware, vips will automatically get installed for the correct architecture, as provided by NPM. I don't think this will be a blocker for marking as a JS only option.

In checking the JS action docs, it looks we will need to update actions.yml to replace the existing docker stanza with JS.

Copy link
Member

@benschwarz benschwarz left a comment

Choose a reason for hiding this comment

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

Added queries around minimum percent change threshold

minPctChange:
description: "Minimun percentage reduction to be committed"
required: false
default: "1"
Copy link
Member

Choose a reason for hiding this comment

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

Seeing as you've reported that 1% causes issues with webp, it might be worth considering changing to a higher default value. Should the value be numeric or a string?

Suggested change
default: "1"
default: "2"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm currently using 5% and still many webp images are optimized more than once.

The underlying value is a float, but in this file all values are strings.

Copy link
Member

Choose a reason for hiding this comment

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

I'm currently using 5% and still many webp images are optimized more than once.

Damn… that does not sound ideal. Early on when I built image-actions I recall that 1% was about right… but that was before it supported webp. A higher single digit default might be required. Maybe 5% is a good starting place?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess something between 5% and 10% is a good value, with a tradeoff between compression (5%) and single run (10%).
An idea that I had was to iterate the optimization step within a single action run, until the saving was below the threshold, to reach the best/final size in a single commit, but I wasn't sure if it was a good idea.

minPctChange: '2.5'
```

`minPctChange` accepts a numerical value and defaults to '1'.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
`minPctChange` accepts a numerical value and defaults to '1'.
`minPctChange` accepts a numerical value represented as a string. `Default = '2'`.

@@ -115,6 +115,20 @@ with:

`compressOnly` accepts a Boolean value (true or false) and defaults to false.

### Minimum percentage change

By default, Image Actions commits optimised images if the new size is at least 1% smaller than the original one.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
By default, Image Actions commits optimised images if the new size is at least 1% smaller than the original one.
By default, Image Actions commits optimised images if the new size is at least 2% smaller than the original one.

@@ -21,6 +22,7 @@ const IGNORE_PATHS = process.env['INPUT_IGNOREPATHS']
: ['node_modules/**']
const COMPRESS_ONLY = process.env['INPUT_COMPRESSONLY'] === 'true'
const JPEG_PROGRESSIVE = process.env['INPUT_JPEGPROGRESSIVE'] === 'true'
const MIN_PCT_CHANGE = parseFloat(process.env['INPUT_MINPCTCHANGE']) || 1
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const MIN_PCT_CHANGE = parseFloat(process.env['INPUT_MINPCTCHANGE']) || 1
const MIN_PCT_CHANGE = parseFloat(process.env['INPUT_MINPCTCHANGE']) || 2

@alexdupre
Copy link
Contributor Author

To test it, I switched to build the docker image:
9a31636

I'm using the action in some of my projects successfully.

A JS action cannot install npm dependencies, either you have to commit the node_modules or use a bundler (but this doesn't seem to work with native deps).

@benschwarz
Copy link
Member

A JS action cannot install npm dependencies, either you have to commit the node_modules or use a bundler (but this doesn't seem to work with native deps).

Thanks for the clarification, it's been a long time since I looked at action packaging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants