Iminify GitHub Action
Compress the images a pull request adds with the Iminify GitHub Action: it commits the smaller files to the branch and comments with what each one saved.
The Iminify GitHub Action compresses the images a pull request adds or changes, commits the smaller files to the pull request's branch and leaves a comment with what each one saved. It runs on GitHub, calls this API with your token, and is open source at mozex/iminify-action.
Setting it up
- Create an API token in Settings, API Tokens.
- In your repository on GitHub, open Settings, then Secrets and variables, then Actions, and add the token as a secret named
IMINIFY_TOKEN. - Add a workflow to the repository, for example
.github/workflows/images.yml:
name: Images
on:
pull_request:
permissions:
contents: write
pull-requests: write
concurrency:
group: images-${{ github.head_ref }}
cancel-in-progress: true
jobs:
compress:
runs-on: ubuntu-latest
steps:
- uses: mozex/iminify-action@v1
with:
token: ${{ secrets.IMINIFY_TOKEN }}
The job needs no checkout step, because the action reads the files through GitHub's API. Keep the permissions block: many repositories give a workflow a read-only token, and the action has to push a commit and write a comment. The concurrency group cancels a run when a newer push to the same branch arrives.
What it does
On every push to a pull request, the action:
- Lists the PNG, JPG, WebP and GIF files the pull request adds or changes. A file only moved or copied, with the same bytes, is skipped. HEIC and TIFF files are left alone, because Iminify returns them in another format and a new extension would break every reference to the file. So is a file whose bytes don't match its extension, and a file stored in Git LFS, since the action reads only what's in Git itself.
- Sends each one to Iminify with the level you choose, in its own format and with alt text off.
- Commits the files that came back smaller to the pull request's branch, in one commit, made with the workflow's own token as
github-actions[bot]. - Writes a comment with a table of each file's size before and after, and updates that same comment on later pushes.
A later push sends only what's new: the action's commits name the files they wrote, and its comment remembers the images Iminify couldn't make smaller and the files it left alone. An image that failed is sent again, and so, with the comment turned off, is an image Iminify couldn't make smaller. With commit and comment both off, every image is sent again on every push.
Settings
| Input | Default | What it does |
|---|---|---|
token |
Your API token. Pass it from a secret, never write it into the workflow. | |
github-token |
the workflow's token | Reads the pull request, commits to its branch and writes the comment. |
level |
smart |
smart, ultra or lossless, as in Compression settings. |
keep-metadata |
false |
Keep the EXIF metadata (camera, date, location). |
commit |
true |
Commit the smaller files. With false, the action only reports what it would save. |
comment |
true |
Write the savings in a pull request comment. |
ignore |
Paths to leave alone, one pattern a line, read like .gitignore patterns without ! or [...]: *.gif or fixtures match in any folder, tests/fixtures only from the repository's root, and a folder covers everything in it. |
Its outputs are compressed (how many images came back smaller), saved-bytes and commit, the commit with the smaller files, for a later step of the same job.
What it counts against
Each image the action sends is one of your plan's daily images, the same count the website and the API spend, and the action's API calls count toward your plan's requests a minute. Limits and quotas explains both, and the plans list each plan's numbers. When the day's images run out partway through, the action commits what it finished, lists the rest in its comment, and sends them on the next push.
The images also appear on your account like any other upload, where you can download or delete them.
Forks and Dependabot
GitHub gives a pull request from a fork neither your secrets nor a token that can push to its branch, and a Dependabot pull request gets none of your Actions secrets. The action skips both with a notice and the check still passes. Compress those images from a branch of your own repository, or after merging.
Don't move the workflow to pull_request_target to get around it: that event runs with your secrets for anyone's pull request, so the action refuses it.
Required checks
GitHub doesn't run workflows on a commit made with the workflow's own token by itself: it holds those runs until someone with write access approves them on the pull request, so the checks a branch protection rule requires wait for that approval or for the next push. The approved run of the action finds nothing new and sends nothing. To have the checks start on their own, pass a personal access token or a GitHub App token as github-token.