[GitHub Actions] ワークフローが 60 日で無効化されないようにする

60 日間リポジトリに「アクティビティ」がない場合、ワークフローは自動的に無効化されます。

この「アクティビティ」は公式から細かく説明されていませんが、少なくともコミットの作成は「アクティビティ」とみなされるようです。

参考「[ワークフローの無効化と有効化 - GitHub Docs](https://docs.github.com/ja/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/disabling-and-enabling-a-workflow)」
参考「[schedule - ワークフローをトリガーするイベント - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule)」

# 0. まとめ

回避方法は主に以下の 2 つがあります:

- GitHub API を用いてワークフローを有効化する
    - ワークフローが既に有効の場合でも、期限が延長される
    - ワークフローからの有効化も可
    - 期限を延長したいワークフローそれぞれを有効化する必要あり
- コミットを作成する
    - ワークフローからの push も可
    - オプション `--allow-empty` を用いた空コミットも可
    - デフォルトブランチ以外も可

参考「[GitHub - gautamkrishnar/keepalive-workflow: GitHub action to prevent GitHub from suspending your cronjob based triggers due to repository inactivity](https://github.com/gautamkrishnar/keepalive-workflow)」

# 1. GitHub API でワークフローを有効化する

GitHub API を用いてワークフローを有効化すると、その時点が 60 日の基準になります。

GitHub Actions の cron は実行されないこともあるため、月に 1 回より月に 2 回ほど実行を試みた方が良いと思います。

ワークフロー ID を取得しなくてもワークフローのファイル名で操作可能です。

期限を延長したいワークフローそれぞれを有効化する必要があります。

```yaml:.github/workflows/keepalive.yml
name: Prevent scheduled workflow from being automatically disabled

on:
  schedule:
    - cron: '45 14 4,19 * *'
  workflow_dispatch:

concurrency:
  group: keepalive
  cancel-in-progress: false

jobs:

  keepalive:
    permissions:
      actions: write
    runs-on: ubuntu-latest
    steps:

      - name: Re-enable workflow
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: ${{ github.repository }}
        run: |
          gh workflow enable keepalive.yml
          gh workflow enable foo.yml
```

※ここでは `GITHUB_TOKEN` を用いてワークフローの有効化を行うため、権限 `permissions.actions: write` が必要です。
※ここではリポジトリをチェックアウトせずに GitHub CLI を使用するため、環境変数またはコマンドのオプションを用いてリポジトリを指定する必要があります。
※リポジトリは `github.repository` または環境変数 `GITHUB_REPOSITORY` から取得出来ます。

参考「["Enable a workflow" のきめ細かいアクセス トークン - ワークフローの REST API エンドポイント - GitHub Docs](https://docs.github.com/ja/rest/actions/workflows?apiVersion=2022-11-28#enable-a-workflow--fine-grained-access-tokens)」(`permissions.actions: write`)
参考「[Repository permissions for "Actions" - GitHub Appに必要な権限 - GitHub Docs](https://docs.github.com/ja/rest/authentication/permissions-required-for-github-apps?apiVersion=2022-11-28#repository-permissions-for-actions)」(`PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable`)
参考「[Controlling permissions for GITHUB_TOKEN - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token)」(`permissions.actions`)
参考「[ワークフローで GitHub CLI を使用する - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-what-your-workflow-does/using-github-cli-in-workflows)」
参考「[GitHub CLI - ワークフローの無効化と有効化 - GitHub Docs](https://docs.github.com/ja/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/disabling-and-enabling-a-workflow?tool=cli)」
参考「[gh environment - GitHub CLI | Take GitHub to the command line](https://cli.github.com/manual/gh_help_environment)」(`GH_REPO`)
参考「[gh workflow enable - GitHub CLI | Take GitHub to the command line](https://cli.github.com/manual/gh_workflow_enable)」
参考「[github context - Accessing contextual information about workflow runs - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#github-context)」(`github.repository`)
参考「[Default environment variables - Store information in variables - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables)」(`GITHUB_REPOSITORY`)

# 2. コミットを作成する

コミットを作成すると、その時点が 60 日の基準になります。

GitHub Actions の cron は実行されないこともあるため、月に 1 回より 2 回ほど実行を試みた方が良いと思います。

デフォルトブランチのコミットも有効ですが、本質的でないコミットのため、デフォルトブランチ以外でコミットを作成するべきと思います。

```bash
git switch --orphan keep-active
git commit --allow-empty -m 'Initial commit'
git push --set-upstream origin keep-active
```

参考「[--orphan \<new-branch> - Git - git-switch Documentation](https://git-scm.com/docs/git-switch#Documentation/git-switch.txt---orphanltnew-branchgt)」
参考「[--orphan \<new-branch> - Git - git-checkout Documentation](https://git-scm.com/docs/git-checkout#Documentation/git-checkout.txt---orphanltnew-branchgt)」

オプション `--allow-empty` を用いて空コミットを作成します。

コミット時のユーザー情報を変更する方法はいくつかあります:

- オプション `-c <name>=<value>`
- `git config`
- 環境変数

```yaml:.github/workflows/keepalive.yml
name: Prevent scheduled workflow from being automatically disabled

on:
  schedule:
    - cron: '45 14 4,19 * *'
  workflow_dispatch:

concurrency:
  group: keepalive
  cancel-in-progress: false

jobs:

  keepalive:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:

      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: keep-active

      - name: Commit and push
        env:
          NAME: 'github-actions[bot]'
          EMAIL: '41898282+github-actions[bot]@users.noreply.github.com'
        run: |
          git -c user.name="$NAME" -c user.email="$EMAIL" commit --allow-empty -m 'Automated commit'
          git push
```

※ `actions/checkout` によって `GITHUB_TOKEN` が `git push` から使用されるようになるため、権限 `permissions.contents: write` が必要です。
※メールアドレス `41898282+github-actions[bot]@users.noreply.github.com` は GitHub Enterprise Server では使用出来ません。

参考「["Create a commit" のきめ細かいアクセス トークン - ワークフローの REST API エンドポイント - GitHub Docs](https://docs.github.com/ja/rest/git/commits?apiVersion=2022-11-28#create-a-commit--fine-grained-access-tokens)」(`permissions.contents: write`)
参考「[Repository permissions for "Contents" - GitHub Appに必要な権限 - GitHub Docs](https://docs.github.com/ja/rest/authentication/permissions-required-for-github-apps?apiVersion=2022-11-28#repository-permissions-for-contents)」(`POST /repos/{owner}/{repo}/git/commits`)
参考「[Controlling permissions for GITHUB_TOKEN - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token)」(`permissions.contents`)
参考「[Usage - GitHub - actions/checkout: Action for checking out a repo](https://github.com/actions/checkout?tab=readme-ov-file#usage)」
参考「[Push a commit using the built-in token - GitHub - actions/checkout at v4.1.7](https://github.com/actions/checkout/tree/v4.1.7?tab=readme-ov-file#Push-a-commit-using-the-built-in-token)」
参考「[-c \<name>=\<value> - Git - git Documentation](https://www.git-scm.com/docs/git/#Documentation/git.txt--cltnamegtltvaluegt)」
参考「[user.name - Git - git-config Documentation](https://git-scm.com/docs/git-config#Documentation/git-config.txt-username)」
参考「[COMMIT INFORMATION - Git - git-commit Documentation](https://www.git-scm.com/docs/git-commit/#_commit_information)」
参考「[--allow-empty - Git - git-commit Documentation](https://git-scm.com/docs/git-commit/#Documentation/git-commit.txt---allow-empty)」