Setting up a CLI on GitHub's hosted runners
Problem statement
Many of GitHub’s Technology Partners wish to provide a way for developers to easily access their services via a configured CLI environment on GitHub’s hosted runners, for example, so that it is available in a CI/CD workflow.
The solution should :
- Make it simple for developers to precisely describe the version of the CLI to be installed
- Support multiple operating systems
- Run in an efficient fashion to minimize run-time and associated costs
- Work across hosted and self-hosted runners
- Leverage community tooling when possible
Solution
Technology Partners should solve this by providing an action in a repo they maintain, written in, or compiled / transpiled to JavaScript. The action should be responsible for retrieving a specific version of the CLI, installing it, adding it to the path, and (optionally) caching it. Commonly this variety of action that performs some setup of a tool, is named **setup-$TOOL**
. Refer to the examples below to see how this pattern is already in use in multiple ecosystems.
GitHub provides the actions/toolkit set of packages, which makes this process more straightforward across all of GitHub’s hosted runners.
Specifically, the actions/core and actions/tool-cache package expose operations that are commonly required in this scenario, in a cross-platform way.
Implementation
A simple cross-platform implementation in JavaScript follows, note, the implementation for getDownloadURL
is intentionally absent, so that the example remains generic:
const core = require('@actions/core');
const tc = require('@actions/tool-cache');
async function setup() {
// Get version of tool to be installed
const version = core.getInput('version');
// Download the specific version of the tool, e.g. as a tarball
const pathToTarball = await tc.downloadTool(getDownloadURL());
// Extract the tarball onto host runner
const pathToCLI = await tc.extractTar(pathToTarball);
// Expose the tool by adding it to the PATH
core.addPath(pathToCLI)
}
module.exports = setup
Concrete implementation
A concrete implementation of this pattern is available here.
Examples
Example where this pattern is employed include:
Related
For more information on creating a JavaScript action, refer to this guide.