{"meta":{"title":"Creating a third party CLI action","intro":"Learn how to develop an action to set up a CLI on GitHub Actions runners.","product":"GitHub Actions","breadcrumbs":[{"href":"/en/actions","title":"GitHub Actions"},{"href":"/en/actions/how-tos","title":"How-tos"},{"href":"/en/actions/how-tos/create-and-publish-actions","title":"Create and publish actions"},{"href":"/en/actions/how-tos/create-and-publish-actions/create-a-cli-action","title":"Create a CLI action"}],"documentType":"article"},"body":"# Creating a third party CLI action\n\nLearn how to develop an action to set up a CLI on GitHub Actions runners.\n\n## Introduction\n\nYou can write an action to provide a way for users to access your servers via a configured CLI environment on GitHub Actions runners.\n\nYour action should:\n\n* Make it simple for users to specify the version of the CLI to install\n* Support multiple operating systems\n* Run in an efficient fashion to minimize run-time and associated costs\n* Work across GitHub-hosted and self-hosted runners\n* Leverage community tooling when possible\n\nThis article will demonstrate how to write an action that retrieves a specific version of your CLI, installs it, adds it to the path, and (optionally) caches it. This type of action (an action that sets up a tool) is often named `setup-$TOOL`.\n\n## Prerequisites\n\nYou should have an understanding of how to write a custom action. For more information, see [Managing custom actions](/en/actions/how-tos/creating-and-publishing-actions/managing-custom-actions).\n\n## Example\n\nThe following script demonstrates how you can get a user-specified version as input, download and extract the specific version of your CLI, then add the CLI to the path.\n\nGitHub provides [`actions/toolkit`](https://github.com/actions/toolkit), which is a set of packages that helps you create actions. This example uses the [`actions/core`](https://github.com/actions/toolkit/tree/main/packages/core) and [`actions/tool-cache`](https://github.com/actions/toolkit/tree/main/packages/tool-cache) packages.\n\n```javascript copy\nconst core = require('@actions/core');\nconst tc = require('@actions/tool-cache');\n\nasync function setup() {\n  // Get version of tool to be installed\n  const version = core.getInput('version');\n\n  // Download the specific version of the tool, e.g. as a tarball\n  const pathToTarball = await tc.downloadTool(getDownloadURL());\n\n  // Extract the tarball onto the runner\n  const pathToCLI = await tc.extractTar(pathToTarball);\n\n  // Expose the tool by adding it to the PATH\n  core.addPath(pathToCLI)\n}\n\nmodule.exports = setup\n```\n\nTo use this script, replace `getDownloadURL` with a function that downloads your CLI. You will also need to create an actions metadata file (`action.yml`) that accepts a `version` input and that runs this script. For full details about how to create an action, see [Creating a JavaScript action](/en/actions/creating-actions/creating-a-javascript-action).\n\n## Further reading\n\nThis pattern is employed in several actions. For more examples, see:\n\n* [`ruby/setup-ruby`](https://github.com/ruby/setup-ruby)\n* [`google-github-actions/setup-gcloud`](https://github.com/google-github-actions/setup-gcloud)\n* [`hashicorp/setup-terraform`](https://github.com/hashicorp/setup-terraform)"}