{"id":15978970,"url":"https://github.com/phrozenbyte/gh-workflow-immortality","last_synced_at":"2026-03-13T00:09:09.574Z","repository":{"id":152899986,"uuid":"590682313","full_name":"PhrozenByte/gh-workflow-immortality","owner":"PhrozenByte","description":"Keeps cronjob based triggers of GitHub workflows alive.","archived":false,"fork":false,"pushed_at":"2023-01-19T00:38:36.000Z","size":15,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-12-14T23:47:18.284Z","etag":null,"topics":["cronjobs","github","github-action","github-workflow","immortality","keepalive","scheduled-jobs"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PhrozenByte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-19T00:27:32.000Z","updated_at":"2024-11-03T12:13:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"2d5bf2ff-a55c-424e-83b4-dedd39881e81","html_url":"https://github.com/PhrozenByte/gh-workflow-immortality","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhrozenByte%2Fgh-workflow-immortality","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhrozenByte%2Fgh-workflow-immortality/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhrozenByte%2Fgh-workflow-immortality/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PhrozenByte%2Fgh-workflow-immortality/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PhrozenByte","download_url":"https://codeload.github.com/PhrozenByte/gh-workflow-immortality/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230187565,"owners_count":18186951,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cronjobs","github","github-action","github-workflow","immortality","keepalive","scheduled-jobs"],"created_at":"2024-10-07T23:40:30.301Z","updated_at":"2026-03-13T00:09:09.563Z","avatar_url":"https://github.com/PhrozenByte.png","language":"Shell","readme":"GitHub Workflow Immortality\n===========================\n\nThis GitHub action resp. the [`gh-workflow-immortality.sh` script](gh-workflow-immortality.sh) makes scheduled GitHub workflows immortal by force enabling workflows.\n\nGitHub will suspend scheduled triggers of GitHub workflows of public repositories that didn't receive any activity within the past 60 days. The scheduled triggers no longer run and you'll see the following error:\n\n\u003e This scheduled workflow is disabled because there hasn't been activity in this repository for at least 60 days.\n\nThe `gh-workflow-immortality.sh` script simply iterates all your GitHub repositories and force enables your workflows, so that the workflow's inactivity counter is reset. Your scheduled triggers will run indefinitely and your workflows won't ever get suspended by GitHub for inactivity (they are \"immortal\"). The script will re-enable workflows that were previously disabled due to inactivity, but not workflows that were disabled manually.\n\nThe script was written to run with [GNU Bash](https://www.gnu.org/software/bash/) (version 4.2 or later). It requires the [`sed`](https://sed.sourceforge.io/), [`awk`](https://linux.die.net/man/1/awk), [`curl`](https://curl.se/), and [`jq`](https://jqlang.github.io/jq/) command line tools to be installed.\n\nMade with :heart: by [Daniel Rudolf](https://www.daniel-rudolf.de/) ([@PhrozenByte](https://github.com/PhrozenByte)). GitHub Workflow Immortality is free and open source software, released under the terms of the [MIT license](LICENSE).\n\n## How to use\n\nYou can either run the `gh-workflow-immortality.sh` script manually, or use the GitHub action. No matter what, you must [create a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token). This is also true when using the GitHub action, because GitHub's automatically created `GITHUB_TOKEN` secret lacks the required permissions.\n\nYou can use both fine-grained personal access tokens, and classic personal access tokens. If you choose to use classic personal access tokens, you must enable the \"workflow\" scope, which also implies the very potent \"repo\" scope. Thus it's better to use fine-grained personal access tokens when possible: The only repository permission required is the \"Actions\" permission with both read and write access. You can even limit the fine-grained personal access token to the repositories you really need. Please note that with fine-grained personal access tokens you need a token per GitHub user and GitHub organization. Don't forget to choose a suitable expiration date and to renew your personal access tokens accordingly.\n\nPlease note that `gh-workflow-immortality.sh` intentionally excludes forked, archived, and disabled repositories. Even though forked repositories can indeed use scheduled triggers for GitHub workflows, we expect them not to require immortality and are thus excluded by default. If you require the GitHub workflows of a forked repository to be immortal, either specify it using the `repos` options (when using the GitHub action) resp. pass it as command line argument (when running the script manually), or enable the `include_forks` option (when using the GitHub action) resp. pass the `--forks` command line option (when running the script manually). This won't work for archived and disabled repositories though, because they can't have active GitHub workflows. Please also note that `gh-workflow-immortality.sh` will exclude dynamic workflows without a YAML config file in the repo's `.github/workflows/` directory (e.g. the default GitHub Pages workflow), because they don't use scheduled triggers.\n\n`gh-workflow-immortality.sh` will respect GitHub's [REST API rate limiting](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28). If the limit was reached, the script will bail and tell you when to try again. Since it's practically impossible to pass the limit just with `gh-workflow-immortality.sh`, you should consider running the script at a time with fewer requests from your other applications using the GitHub API. If this isn't possibly, consider running the script multiple times at different times with a subset of repos.\n\n### Using the GitHub action\n\nSimply create a new GitHub workflow like the following and incorporate this GitHub action as its only step:\n\n```yaml\nname: GitHub Workflow Immortality\n\non:\n  schedule:\n    # run once a month on the first day of the month at 00:20 UTC\n    - cron: '20 0 1 * *'\n  workflow_dispatch: {}\n\njobs:\n  keepalive:\n    name: GitHub Workflow Immortality\n\n    runs-on: ubuntu-latest\n    permissions: {}\n\n    steps:\n      - name: Keep cronjob based triggers of GitHub workflows alive\n        uses: PhrozenByte/gh-workflow-immortality@v1\n        with:\n          secret: ${{ secrets.PERSONAL_ACCESS_TOKEN }}\n          repos: ${{ github.repository }}\n```\n\nThis example GitHub workflow will run once a month on the first day of the month at 00:20 UTC. It will keep all workflows of the containing GitHub repository alive. Running the workflow once a month is sufficient. Don't forget to [create an encrypted secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) (the example expects a secret named `PERSONAL_ACCESS_TOKEN`) with the personal access token you've created earlier (see above).\n\nYou can create an \"immortality workflow\" per repository, per user, per organization, or however you please, simply use the options below to specify the list of GitHub repositories whose workflows should be kept alive. Since your immortality workflow will use a scheduled trigger to run, you must make sure to include it in this list - otherwise GitHub might suspend it for inactivity. You can use the `${{ github.repository }}` variable to get the name of the repository including the immortality workflow.\n\nPlease note that running GitHub Workflow Immortality in a public repository to keep workflows of private repositories alive will inevitably expose the names of those private repositories. If you consider the names of private repositories confidential, you should run GitHub Workflow Immortality in a private repository instead. Enabling the `no_repo_names` option also hides repository names. However, be aware that GitHub Workflow Immortality might still inadvertently expose the name of a private repository if an associated GitHub API request fails.\n\nThe GitHub action will accept the following options:\n\n| Option               | Description                                                                                                                       | Default | Required |\n|----------------------|-----------------------------------------------------------------------------------------------------------------------------------|---------|----------|\n| `secret`             | Personal access token of the executing GitHub user (see above)                                                                    | None    | Yes      |\n| `include_forks`      | Also includes forks when loading repositories; either `true` or `false`                                                           | `false` | No       |\n| `owner_repos`        | Loads all repositories of the authenticated GitHub user (includes both public and private repositories); either `true` or `false` | `false` | No       |\n| `collaborator_repos` | Loads all repositories of which the authenticated GitHub user is a collaborator of; either `true` or `false`                      | `false` | No       |\n| `member_repos`       | Loads all repositories of organizations of which the authenticated GitHub user is a member of; either `true` or `false`           | `false` | No       |\n| `users`              | Loads all public repositories of the given GitHub users; expects a line separated list of GitHub user names                       | `\"\"`    | No       |\n| `orgs`               | Loads all repositories of the given GitHub organizations; expects a line separated list of GitHub organization names              | `\"\"`    | No       |\n| `repos`              | Loads the given repositories; expects a line separated list of GitHub repositories, e.g. `PhrozenByte/gh-workflow-immortality`    | `\"\"`    | No       |\n| `no_repo_names`      | Suppresses printing repository names, but prints repository IDs only; either `true` or `false`                                    | `false` | No       |\n| `verbose`            | Prints a list of issued GitHub API requests; either `true` or `false`                                                             | `false` | No       |\n\nEven though none of `owner_repos`, `collaborator_repos`, `member_repos`, `users`, `orgs`, and `repos` is mandatory, the options given must match at least one GitHub repository. Otherwise your GitHub workflow will fail.\n\nThe options `no_repo_names` and `verbose` are mutually exclusive. The GitHub workflow fails when enabling both.\n\n### Run script manually\n\nThe GitHub action is no more than a wrapper for the `gh-workflow-immortality.sh` script. `gh-workflow-immortality.sh` is just an ordinary Bash script you can run locally on your machine. Simply download the script and check its help:\n\n```console\n$ ./gh-workflow-immortality.sh --help\nUsage:\n  gh-workflow-immortality.sh [--forks] [[--owner] [--collaborator] [--member]|--all] \\\n    [--user USER]... [--org ORGANIZATION]... [REPOSITORY]...\n\nMakes scheduled GitHub workflows immortal by force enabling workflows. GitHub\nwill suspend scheduled triggers of GitHub workflows of repositories that didn't\nreceive any activity within the past 60 days. This small script simply iterates\nall your GitHub repositories and force enables your workflows, so that the\nworkflow's inactivity counter is reset.\n\nRepository options:\n  --forks             also loads forked repositories (otherwise excluded)\n  --owner             loads all repositories of the authenticated GitHub user\n                        (includes both public and private repositories)\n  --collaborator      loads all repositories of which the authenticated GitHub\n                        user is a collaborator of\n  --member            loads all repositories of organizations of which the\n                        authenticated GitHub user is a member of\n  --all               same as '--owner', '--collaborator', and '--member'\n  --user USER         loads all public repositories of the given GitHub user\n  --org ORGANIZATION  loads all repositories of the given GitHub organization\n  REPOSITORY          loads a single repository, no matter its status\n\nApplication options:\n  --dry-run           don't actually enable any workflows\n  --no-repo-names     don't print repository names, but repository IDs only\n  --verbose           print a list of issued GitHub API requests\n  --help              display this help and exit\n  --version           output version information and exit\n\nEnvironment variables:\n  GITHUB_TOKEN        uses the given GitHub personal access token\n  INCLUDE_FORKS       passing 'true' enables '--forks'\n  OWNER_REPOS         passing 'true' enables '--owner'\n  COLLABORATOR_REPOS  passing 'true' enables '--collaborator'\n  MEMBER_REPOS        passing 'true' enables '--member'\n  REPOS_USERS         line separated list of GitHub users for '--user'\n  REPOS_ORGS          line separated list of GitHub organizations for '--org'\n  REPOS               line separated list of 'REPOSITORY' arguments\n  NO_REPO_NAMES       passing 'true' enables '--no-repo-names'\n  VERBOSE             passing 'true' enables '--verbose'\n\nYou want to learn more about `gh-workflow-immortality`? Visit us on GitHub!\nPlease don't hesitate to ask your questions, or to report any issues found.\nCheck out \u003chttps://github.com/PhrozenByte/gh-workflow-immortality\u003e.\n```\n\nFor the script to work you must set the `GITHUB_TOKEN` environment variable - otherwise you'll see \"Bad credentials\" errors. Create a personal access token as described above and pass it as `GITHUB_TOKEN` environment variable. To keep all workflows of all of your own GitHub repositories alive, try the following:\n\n```console\n$ export GITHUB_TOKEN=my_personal_access_token\n$ ./gh-workflow-immortality.sh --owner\nGitHub repository 'PhrozenByte/gh-workflow-immortality' (ID: 590682313): 0 alive and 0 dead workflows\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphrozenbyte%2Fgh-workflow-immortality","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphrozenbyte%2Fgh-workflow-immortality","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphrozenbyte%2Fgh-workflow-immortality/lists"}