リポジトリ内の画像を自動圧縮するGitHub Actionsを作りました

本記事では、[GitHub Actions](https://github.com/features/actions)を用いてリポジトリ内の画像を自動圧縮する方法を紹介します。

なお、GitHub Actionsにまだ申し込んでいない方は[こちら](https://github.com/features/actions)から申し込んでください。


# imgcmp

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185511/7fce21a4-d39c-1b7b-9fb8-5682d0ce9cbe.png" width="40%">

- [9sako6/imgcmp](https://github.com/9sako6/imgcmp)



> This GitHub action optimizes images in your repository

imgcmpはリポジトリ内の画像を自動圧縮するbotです。現在JPEG、PNG、GIF、SVGに対応しています。`git push`したタイミングで走り、圧縮可能な画像があるなら圧縮して以下のようなpull requestを送ってきます。

![sample_pull_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185511/3fe77c88-8b99-87e2-9852-7f6a37e67100.png)


# 使い方
以下の`.github/workflows/imgcmp.yml`を作るだけです。

```yml:imgcmp.yml
name: imgcmp
on: push
jobs:
  build:
    name: imgcmp
    runs-on: ubuntu-latest    
    steps:
    - uses: 9sako6/imgcmp@master
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

もしリポジトリ内に画像ファイルがあり、それらが圧縮可能なら、`git push`した後に冒頭で述べたようなプルリクエストが届きます。

## 圧縮しない画像ファイルの設定
環境変数`IGNORED_FILES`を指定することで、圧縮しないファイルを指定することもできます。

```yml:imgcmp.yml
name: imgcmp
on: push
jobs:
  build:
    name: imgcmp
    runs-on: ubuntu-latest    
    steps:
    - uses: 9sako6/imgcmp@master
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        IGNORED_FILES: "public/*:posts/*.svg"
```

# ImgBotとの主な違い
画像自動圧縮botの先駆者として、[dabutvin/ImgBot](https://github.com/dabutvin/ImgBot)が存在します。
imgcmpはImgBotにインスパイアされて作ったものです。両者の大きな違いは、`pull request`のタイミングです。
ImgBotは実行頻度を`daily`、`weekly`、`monthly`から選べます。
imgbotは`git push`後に毎回リポジトリをチェックし、必要があればpull requestを送ります。

# GitHub Actionsを作るには
GitHub Actionsを作るのは難しくなく、だいたい`Dockerfile`と`entrypoint.sh`を作るだけです（たぶん）。Learning Labのチュートリアル、[Hello, GitHub Actions!](https://lab.github.com/github/hello-github-actions!)がわかりやすかったです。

imgcmpの中身は非常に簡単な作りになっています。

<details><summary>Dockerfile</summary><div>

```Dockerfile:Dockerfile
FROM golang:latest

RUN apt-get update -qq && apt-get install -y \
    bash \
    gifsicle \
    git \
    jpegoptim \
    optipng

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs
RUN npm install -g svgo

ADD entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```

</div></details>


<details><summary>entrypoint.sh</summary><div>

```shell:entrypoint.sh
#!/bin/bash

set -e

# utils
function print_error() {
    echo -e "\e[31mERROR: ${1}\e[m"
}

echo "imgcmp:"

# check envs
if [ -z "${GITHUB_TOKEN}" ]; then
    print_error "not found GITHUB_TOKEN"
    exit 1
fi

# install hub & imgcmp
go get github.com/github/hub
go get github.com/9sako6/imgcmp

# setting for git
git config --global user.name "${GITHUB_ACTOR}"
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
REMOTE_REPO="https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
export REMOTE_BRANCH="imgcmp-${GITHUB_SHA}"

# clone & checkout new branch
git clone "${REMOTE_REPO}" local_repo
cd local_repo
git checkout -b "${REMOTE_BRANCH}"

# main flow
imgcmp

```

</div></details>

<!--
## 余談：デバッグがつらい（個人の主観）

### 時間
動作確認のためには実際にactionを走らせ、コンテナのビルドとその他処理のために数分待つ必要があります。
もしバグがあったら、デバッグして最初から実行し直しです。

### 手間
動作確認のために毎回commit/pushする必要があるわけですが、これは手間です。

そこで、救世主[nektos/act](https://github.com/nektos/act)を使えばactionをローカルで走らせることができます。
これで毎回commit/pushしなくてもactionの動作確認ができます。
ただし、YAMLで書かれたactionに対応していません！(2019年12月23日現在)

<hr>

上記の理由により（2019年10月現在）、actionの開発はちょっと面倒くさいので、些細なものでも誰かが作ってくれてるとありがたみが大きいです。
-->

# おわりに
[imgcmp](https://github.com/9sako6/imgcmp)は簡単な作りをしているので、新たにGitHub Actionsを作りたい方の参考になるかもしれません。

imgcmpに関して、issue、pull request、その他意見など投げてくれると喜びます！

[^1]: https://help.github.com/ja/articles/virtual-environments-for-github-actions#environment-variables