{"id":13487161,"url":"https://github.com/cloudbase/garm","last_synced_at":"2026-04-13T13:04:38.159Z","repository":{"id":40363588,"uuid":"488973970","full_name":"cloudbase/garm","owner":"cloudbase","description":"GitHub Actions Runner Manager","archived":false,"fork":false,"pushed_at":"2026-04-10T18:18:30.000Z","size":40971,"stargazers_count":306,"open_issues_count":20,"forks_count":47,"subscribers_count":6,"default_branch":"main","last_synced_at":"2026-04-10T18:34:44.095Z","etag":null,"topics":["autoscaling","autoscaller","aws","azure","ec2","equinix","gcp","gitea","github","incus","k8s","kubernetes","lxd","openstack","runner","self-hosted"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudbase.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-05-05T13:00:24.000Z","updated_at":"2026-04-10T18:17:14.000Z","dependencies_parsed_at":"2022-07-09T08:16:30.072Z","dependency_job_id":"863f0736-2d93-473b-9fcc-1e33888e1c89","html_url":"https://github.com/cloudbase/garm","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/cloudbase/garm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudbase%2Fgarm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudbase%2Fgarm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudbase%2Fgarm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudbase%2Fgarm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudbase","download_url":"https://codeload.github.com/cloudbase/garm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudbase%2Fgarm/sbom","scorecard":{"id":159353,"data":{"date":"2025-08-11","repo":{"name":"github.com/cloudbase/garm","commit":"9f2764f614c498c9cc4028d5b6da478d55589613"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.5,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 15 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":2,"reason":"Found 1/4 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:29","Info: topLevel 'contents' permission set to 'read': .github/workflows/build-and-push.yml:17","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Info: found token with 'none' permissions: .github/workflows/go-tests.yml:1","Warn: no topLevel permission defined: .github/workflows/integration-tests.yml:1","Warn: no topLevel permission defined: .github/workflows/trigger-manual.yml:1","Warn: no topLevel permission defined: .github/workflows/trigger-nightly.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.1.6 not signed: https://api.github.com/repos/cloudbase/garm/releases/233721642","Warn: release artifact v0.1.5 not signed: https://api.github.com/repos/cloudbase/garm/releases/169332277","Warn: release artifact v0.1.4 not signed: https://api.github.com/repos/cloudbase/garm/releases/141683123","Warn: release artifact v0.1.4-rc1 not signed: https://api.github.com/repos/cloudbase/garm/releases/134362708","Warn: release artifact v0.1.3 not signed: https://api.github.com/repos/cloudbase/garm/releases/113561686","Warn: release artifact v0.1.6 does not have provenance: https://api.github.com/repos/cloudbase/garm/releases/233721642","Warn: release artifact v0.1.5 does not have provenance: https://api.github.com/repos/cloudbase/garm/releases/169332277","Warn: release artifact v0.1.4 does not have provenance: https://api.github.com/repos/cloudbase/garm/releases/141683123","Warn: release artifact v0.1.4-rc1 does not have provenance: https://api.github.com/repos/cloudbase/garm/releases/134362708","Warn: release artifact v0.1.3 does not have provenance: https://api.github.com/repos/cloudbase/garm/releases/113561686"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/build-and-push.yml:20"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-push.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/build-and-push.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build-and-push.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/build-and-push.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build-and-push.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/build-and-push.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:74: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go-tests.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/go-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go-tests.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/go-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go-tests.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/go-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go-tests.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/go-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/integration-tests.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/integration-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/integration-tests.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/integration-tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/integration-tests.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/integration-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/integration-tests.yml:106: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudbase/garm/integration-tests.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:62: pin your Docker image by updating busybox to busybox@sha256:f9a104fddb33220ec80fc45a4e606c74aadf1ef7a3832eb0b05be9e90cd61f5f","Warn: containerImage not pinned by hash: Dockerfile.build-static:1: pin your Docker image by updating docker.io/golang:alpine to docker.io/golang:alpine@sha256:c8c5f95d64aa79b6547f3b626eb84b16a7ce18a139e3e9ca19a8c078b85ba80d","Info:   0 out of  12 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned","Info:   0 out of   3 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (29) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T12:54:02.193Z","repository_id":40363588,"created_at":"2025-08-16T12:54:02.193Z","updated_at":"2025-08-16T12:54:02.193Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31753556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T09:16:15.125Z","status":"ssl_error","status_checked_at":"2026-04-13T09:16:05.023Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["autoscaling","autoscaller","aws","azure","ec2","equinix","gcp","gitea","github","incus","k8s","kubernetes","lxd","openstack","runner","self-hosted"],"created_at":"2024-07-31T18:00:56.089Z","updated_at":"2026-04-13T13:04:38.058Z","avatar_url":"https://github.com/cloudbase.png","language":"Go","readme":"\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/images/garm-light.svg#gh-light-mode-only\" width=\"384px\" alt=\"Light mode image\" /\u003e\n    \u003cimg src=\"doc/images/garm-dark.svg#gh-dark-mode-only\" width=\"384px\" alt=\"Dark mode image\" /\u003e\n\u003c/p\u003e\n\n# GitHub Actions Runner Manager (GARM)\n\n[![Go Tests](https://github.com/cloudbase/garm/actions/workflows/go-tests.yml/badge.svg)](https://github.com/cloudbase/garm/actions/workflows/go-tests.yml)\n\n\u003c!-- TOC --\u003e\n\n- [GitHub Actions Runner Manager GARM](#github-actions-runner-manager-garm)\n    - [About GARM](#about-garm)\n    - [Join us on slack](#join-us-on-slack)\n    - [Installing](#installing)\n        - [Quickstart](#quickstart)\n        - [Installing on Kubernetes](#installing-on-kubernetes)\n    - [Configuring GARM for GHES](#configuring-garm-for-ghes)\n    - [Configuring GARM for Gitea](#configuring-garm-for-gitea)\n    - [Enabling the web UI](#enabling-the-web-ui)\n    - [Using GARM](#using-garm)\n    - [Supported providers](#supported-providers)\n        - [Installing external providers](#installing-external-providers)\n    - [Optimizing your runners](#optimizing-your-runners)\n    - [Write your own provider](#write-your-own-provider)\n\n\u003c!-- /TOC --\u003e\n\n## About GARM\n\nWelcome to GARM!\n\nGARM enables you to create and automatically maintain pools of self-hosted runners in both [Github](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) and [Gitea](https://github.com/go-gitea/gitea/) with auto-scaling that can be used inside your workflow runs.\n\nThe goal of ```GARM``` is to be simple to set up, simple to configure and simple to use. The server itself is a single binary that can run on any GNU/Linux machine without any other requirements other than the providers you want to enable in your setup. It is intended to be easy to deploy in any environment and can create runners in virtually any system you can write a provider for (if one does not alreay exist). There is no complicated setup process and no extremely complex concepts to understand. Once set up, it's meant to stay out of your way.\n\nThrough the use of providers, `GARM` can create runners in a variety of environments using the same `GARM` instance. Whether you want to create runners in your OpenStack cloud, your Azure cloud or your Kubernetes cluster, that is easily achieved by installing the appropriate providers, configuring them in `GARM` and creating pools that use them. You can create zero-runner pools for instances with high costs (large VMs, GPU enabled instances, etc) and have them spin up on demand, or you can create large pools of eagerly created k8s backed runners that can be used for your CI/CD pipelines at a moment's notice. You can mix them up and create pools in any combination of providers or resource allocations you want.\n\nGARM supports two modes of operation:\n\n* Pools\n* Scale sets\n\nHere is a brief architectural diagram of how pools work and how GARM reacts to workflows triggered in GitHub (click the image to see a larger version):\n\n![GARM architecture diagram](/doc/images/garm-light.diagram.svg?raw=true#gh-light-mode-only)\n![GARM architecture diagram](/doc/images/garm-dark.diagram.svg?raw=true#gh-dark-mode-only)\n\n**Scale sets** work differently. While pools (as they are defined in GARM) rely on webhooks to know when a job was started and GARM needs to internally make the right decision in terms of which pool should handle that runner, scale sets have a lot of the scheduling and decision making logic done in GitHub itself.\n\n\u003e [!IMPORTANT]\n\u003e The README and documentation in the `main` branch are relevant to the not yet released code that is present in `main`. Following the documentation from the `main` branch for a stable release of GARM, may lead to errors. To view the documentation for the latest stable release, please switch to the appropriate tag. For information about setting up `v0.2.0-beta1`, please refer to the [v0.2.0-beta1 tag](https://github.com/cloudbase/garm/tree/v0.2.0-beta1).\n\n\u003e [!CAUTION]\n\u003e The `main` branch holds the latest code and is not guaranteed to be stable. If you are looking for a stable release, please check the releases page. If you plan to use the `main` branch, please do so on a new instance. Do not upgrade from a stable release to `main`.\n\n## Join us on slack\n\nWhether you're running into issues or just want to drop by and say \"hi\", feel free to [join us on slack](https://communityinviter.com/apps/garm-hq/garm).\n\n[![slack](https://img.shields.io/badge/slack-garm-brightgreen.svg?logo=slack)](https://communityinviter.com/apps/garm-hq/garm)\n\n## Installing\n\n### Quickstart\n\nCheck out the [quickstart](/doc/quickstart.md) document for instructions on how to install ```GARM```. If you'd like to build from source, check out the [building from source](/doc/building_from_source.md) document.\n\n### Installing on Kubernetes\n\nThanks to the efforts of the amazing folks at [@mercedes-benz](https://github.com/mercedes-benz/), GARM can now be integrated into k8s via their operator. Check out the [GARM operator](https://github.com/mercedes-benz/garm-operator/) for more details.\n\n## Configuring GARM for GHES\n\nGARM supports creating pools and scale sets in either GitHub itself or in your own deployment of [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.10/admin/overview/about-github-enterprise-server). For instructions on how to use ```GARM``` with GHE, see the [credentials](/doc/github_credentials.md) section of the documentation.\n\n## Configuring GARM for Gitea\n\nGARM now has support for Gitea (\u003e=1.24.0). For information on getting started with Gitea, see the [Gitea quickstart](/doc/gitea.md) document.\n\n## Enabling the web UI\n\nGARM now ships with a single page application. To enable it, add the following to your GARM config:\n\n```toml\n[apiserver.webui]\n  enable = true\n```\n\nCheck the [README.md](/webapp/README.md) file for details on the web UI.\n\n## Using GARM\n\nGARM is designed with simplicity in mind. At least we try to keep it as simple as possible. We're aware that adding a new tool in your workflow can be painful, especially when you already have to deal with so many. The cognitive load for OPS has reached a level where it feels overwhelming at times to even wrap your head around a new tool. As such, we believe that tools should be simple, should take no more than a few hours to understand and set up and if you absolutely need to interact with the tool, it should be as intuitive as possible. Although we try our best to make this happen, we're aware that GARM has some rough edges, especially for new users. If you encounter issues or feel like the setup process was too complicated, please let us know. We're always looking to improve the user experience.\n\nWe've written a short introduction into some of the commands that GARM has and some of the concepts involved in setting up GARM, managing runners and how GitHub does some of the things it does.\n\n[You can find it here](/doc/using_garm.md).\n\nPlease, feel free to [open an issue](https://github.com/cloudbase/garm/issues/new) if you find the documentation lacking and would like more info. Sometimes we forget the challenges that new users face as we're so close to the code and how it works. Any feedback is welcome and we're always looking to improve the documentation.\n\n## Supported providers\n\nGARM uses providers to create runners in a particular IaaS. The providers are external executables that GARM calls into to create runners. Before you can create runners, you'll need to install at least one provider.\n\n### Installing external providers\n\nExternal providers are binaries that GARM calls into to create runners in a particular IaaS. There are several external providers available:\n\n* [Akamai/Linode](https://github.com/flatcar/garm-provider-linode) - Experimental\n* [Amazon EC2](https://github.com/cloudbase/garm-provider-aws)\n* [Azure](https://github.com/cloudbase/garm-provider-azure)\n* [CloudStack](https://github.com/nexthop-ai/garm-provider-cloudstack)\n* [Google Cloud Platform (GCP)](https://github.com/cloudbase/garm-provider-gcp)\n* [Incus](https://github.com/cloudbase/garm-provider-incus)\n* [Kubernetes](https://github.com/mercedes-benz/garm-provider-k8s) - Thanks to the amazing folks at @mercedes-benz for sharing their awesome provider!\n* [LXD](https://github.com/cloudbase/garm-provider-lxd)\n* [OpenStack](https://github.com/cloudbase/garm-provider-openstack)\n* [Oracle Cloud Infrastructure (OCI)](https://github.com/cloudbase/garm-provider-oci)\n\nFollow the instructions in the README of each provider to install them.\n\n## Optimizing your runners\n\nIf you would like to optimize the startup time of new instance, take a look at the [performance considerations](/doc/performance_considerations.md) page.\n\n## Write your own provider\n\nThe providers are interfaces between ```GARM``` and a particular IaaS in which we spin up GitHub Runners. **External** providers can be written in any language, as they are in the form of an external executable that ```GARM``` calls into. Please see the [Writing an external provider](/doc/external_provider.md) document for details. Also, feel free to inspect the two available sample external providers in this repository.\n","funding_links":[],"categories":["The matrix (might be better readable on [GitHub pages](https://jonico.github.io/awesome-runners/))"],"sub_categories":["A word about self-hosted action runner images / virtual environments and how to test locally"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudbase%2Fgarm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudbase%2Fgarm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudbase%2Fgarm/lists"}