Skip to content
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

Add compressOnly mode and also update README to discuss forks #54

Merged
merged 8 commits into from
Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 68 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Image Actions

<<<<<<< HEAD
Image Actions automatically compress JPEG, PNG and WebP images in GitHub Pull Requests within the same repository.

It can also run in "Compress Only" mode to allow this to be used for non-Pull Requests, and also for Pull Requests from forks.
=======
Image Actions automatically compresses JPEG, PNG and WebP images in GitHub Pull Requests.
>>>>>>> upstream/master
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved

- **Fast, efficient and near-lossless compression**
- Uses the best image compression algorithms available: [mozjpeg](https://github.com/mozilla/mozjpeg) and [libvips](https://github.com/libvips/libvips)
Expand Down Expand Up @@ -37,6 +43,8 @@ on:
- "**.webp"
jobs:
build:
# Only run on Pull Requests within the same repository, and not from forks
if: github.event.pull_request.head.repo.full_name == github.repository
name: calibreapp/image-actions
runs-on: ubuntu-latest
steps:
Expand All @@ -49,7 +57,7 @@ jobs:
githubToken: ${{ secrets.GITHUB_TOKEN }}
```

_The `GITHUB_TOKEN` secret is [automatically generated by GitHub](https://help.github.com/en/articles/virtual-environments-for-github-actions#github_token-secret). This automatic token is [scoped only to the repository that is currently running the action.](https://help.github.com/en/articles/virtual-environments-for-github-actions#token-permissions)_
_The `GITHUB_TOKEN` secret is [automatically generated by GitHub](https://help.github.com/en/articles/virtual-environments-for-github-actions#github_token-secret). This automatic token is [scoped only to the repository that is currently running the action.](https://help.github.com/en/articles/virtual-environments-for-github-actions#token-permissions). What this means is that by default the Action cannot update pull requests initiated from forked repositories._

## Configuration

Expand All @@ -73,6 +81,7 @@ Set custom configuration by adding arguments to the action workflow definition:
webpQuality: "80"
ignorePaths: "node_modules/**,build"
# No spaces allowed
compressOnly: "false"
```

Options:
Expand All @@ -82,8 +91,66 @@ Options:
- [webpQuality](http://sharp.pixelplumbing.com/en/stable/api-output/#webp): Number, integer 1-100, default 80 stored in a string
- [jpegProgressive](http://sharp.pixelplumbing.com/en/stable/api-output/#jpeg): Boolean, true or false, default false
- `ignorePaths`: a comma separated string with [globbing](https://www.npmjs.com/package/glob) support of paths to ignore when looking for images to compress
- `compressOnly`: Boolean, true or false, default false


## Running just the compression

By default this Action will add the updated image to the current pull request. It is also possible to set the `compressOnly` option to `true` to skip the commit, if you want to handle this separately - including for forks - see below.

```yml
- name: Compress Images
uses: calibreapp/image-actions@master
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
compressOnly: "true"
```

## Handling pull requests from forked repos

GitHub actions, by default, do not have permission to alter forked repositories. This means this action, by default, only works for pull requests from branches in the same repository as the destination branch.

You can replace the default `GITHUB_TOKEN` with a [personal access token (PAT)](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#permissions-for-the-github_token) which does have permission for forked repositaries, but this introduces other security considerations (which is why it not available by default).

Alternatively you can run this action only for Pull Requests for the current repo, which is advised when not using PATs to avoid wasting time and compute for compressions that will not be committed using the following syntax (as shown in the example yml files in this README):

```
if: github.event.pull_request.head.repo.full_name == github.repository
```

It is also possible to run an addition instance of this action in `compressOnly` mode on pushes to master, and then raise a new pull request for any images commited from a forked repositary pull request as shown in the below example which uses the [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub Action to open this new Pull Request (note this only raises a Pull Request if any fules are changed).


```yml
name: Compress images on Push to Master
on:
push:
branches:
- master
jobs:
build:
name: calibreapp/image-actions
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@master

- name: Compress Images
id: calibre
uses: calibreapp/image-actions@master
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
compressOnly: "true"

- name: Create New Pull Request
uses: peter-evans/create-pull-request@master
with:
title: Compressed Images
branch-suffix: timestamp
commit-message: Compressed Images
body: ${{ steps.calibre.outputs.markdown }}
```

## Migrate legacy configuration

- uses: docker://calibreapp/github-image-actions
Expand Down
9 changes: 9 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ inputs:
required: false
default: "node_modules/**"

compressOnly:
description: "Only runs the compression, without adding to Pull Request"
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
required: false
default: "false"

outputs:
markdown:
description: "Output param used to store the Markdown summary for subsequent actions to use"

runs:
using: "docker"
image: "docker://calibreapp/github-image-actions"
Expand Down
34 changes: 19 additions & 15 deletions entrypoint.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env node

const { GITHUB_TOKEN, GITHUB_EVENT_NAME } = require("./src/constants");
const { GITHUB_TOKEN, GITHUB_EVENT_NAME, COMPRESS_ONLY } = require("./src/constants");

const githubEvent = require("./src/github-event");
const run = require("./src/index.js");
Expand All @@ -11,21 +11,25 @@ if (!GITHUB_TOKEN) {
}

const main = async () => {
// Bail out if the event that executed the action wasn’t a pull_request
if (GITHUB_EVENT_NAME !== "pull_request") {
console.log("::error:: This action only runs for pushes to PRs");
process.exit(78);
}

// Bail out if the pull_request event wasn't synchronize or opened
const event = await githubEvent();
if (event.action !== "synchronize" && event.action !== "opened") {
console.log(
"::error:: Check run has action",
event.action,
". Wants: synchronize or opened"
);
process.exit(78);
if (!COMPRESS_ONLY) {

// Bail out if the event that executed the action wasn’t a pull_request
if (GITHUB_EVENT_NAME !== "pull_request") {
console.log("::error:: This action only runs for pushes to PRs");
process.exit(78);
}

// Bail out if the pull_request event wasn't synchronize or opened
const event = await githubEvent();
if (event.action !== "synchronize" && event.action !== "opened") {
console.log(
"::error:: Check run has action",
event.action,
". Wants: synchronize or opened"
);
process.exit(78);
}
}

await run();
Expand Down
6 changes: 4 additions & 2 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const {
JPEG_PROGRESSIVE,
PNG_QUALITY,
WEBP_QUALITY,
IGNORE_PATHS
IGNORE_PATHS,
COMPRESS_ONLY
} = require("./constants");

// Deprecated configuration method
Expand All @@ -26,7 +27,8 @@ const getConfig = async () => {
jpeg: { quality: JPEG_QUALITY, progressive: JPEG_PROGRESSIVE },
png: { quality: PNG_QUALITY },
webp: { quality: WEBP_QUALITY },
ignorePaths: IGNORE_PATHS
ignorePaths: IGNORE_PATHS,
compressOnly: COMPRESS_ONLY
};

const ymlConfig = await getYamlConfig();
Expand Down
4 changes: 3 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const WEBP_QUALITY = parseInt(process.env["INPUT_WEBPQUALITY"]) || 80;
const IGNORE_PATHS = process.env["INPUT_IGNOREPATHS"]
? process.env["INPUT_IGNOREPATHS"].split(",")
: ["node_modules/**"];
const COMPRESS_ONLY = process.env["INPUT_COMPRESSONLY"] === "true";

const JPEG_PROGRESSIVE = process.env["INPUT_JPEGPROGRESSIVE"] === "true";

Expand Down Expand Up @@ -57,5 +58,6 @@ module.exports = {
JPEG_QUALITY,
PNG_QUALITY,
WEBP_QUALITY,
IGNORE_PATHS
IGNORE_PATHS,
COMPRESS_ONLY
};
5 changes: 1 addition & 4 deletions src/image-processing.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ const path = require("path");
const glob = util.promisify(require("glob"));
const sharp = require("sharp");

const getConfig = require("./config");

const {
REPO_DIRECTORY,
EXTENSION_TO_SHARP_FORMAT_MAPPING,
Expand All @@ -19,10 +17,9 @@ const printSharpInfo = () => {
console.log("=== Sharp library info ===");
};

const processImages = async () => {
const processImages = async (config) => {
printSharpInfo();

const config = await getConfig();
const globPaths = `${REPO_DIRECTORY}/**/*.{${FILE_EXTENSIONS_TO_PROCESS.join(
","
)}}`;
Expand Down
16 changes: 15 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ const generateMarkdownReport = require("./github-markdown");
const processImages = require("./image-processing");
const createComment = require("./github-pr-comment");
const createCommit = require("./github-commit");
const getConfig = require("./config");

const run = async () => {
const config = await getConfig();

console.log("->> Locating images…");

const results = await processImages();
const results = await processImages(config);

const optimisedImages = results.images.filter(
img => img.compressionWasSignificant
Expand All @@ -21,6 +24,17 @@ const run = async () => {
console.log("->> Generating markdown…");
const markdown = await generateMarkdownReport(results);

// Expose the markdown to an Action output
// https://github.community/t/set-output-truncates-multiline-strings/16852
const escaped_markdown = markdown.replace(/\%/g,'%25').replace(/\n/g,'%0A').replace(/\r/g,'%0D')
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
console.log("::set-output name=markdown::" + escaped_markdown)

// If compress only mode, then we're done
if (config.compressOnly) {
console.log("->> compressOnly was set. Stopping.");
return results;
}

console.log("->> Committing files…");
await createCommit(optimisedImages);

Expand Down