mirror of
https://github.com/opentofu/setup-opentofu.git
synced 2025-12-31 15:02:19 +00:00
add tool cache option
Signed-off-by: Michi U. <4169888+michemache@users.noreply.github.com>
This commit is contained in:
parent
e95ccdd206
commit
3d18cc4a77
4 changed files with 115 additions and 3 deletions
10
README.md
10
README.md
|
|
@ -67,6 +67,15 @@ steps:
|
|||
tofu_wrapper: false
|
||||
```
|
||||
|
||||
Caching can be enabled to reduce download time on subsequent workflow runs by storing the OpenTofu binary in GitHub Actions tool cache:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: opentofu/setup-opentofu@v1
|
||||
with:
|
||||
cache: true
|
||||
```
|
||||
|
||||
Subsequent steps can access outputs when the wrapper script is installed:
|
||||
|
||||
```yaml
|
||||
|
|
@ -264,6 +273,7 @@ The action supports the following inputs:
|
|||
- `tofu_wrapper` - (optional) Whether to install a wrapper to wrap subsequent calls of
|
||||
the `tofu` binary and expose its STDOUT, STDERR, and exit code as outputs
|
||||
named `stdout`, `stderr`, and `exitcode` respectively. Defaults to `true`.
|
||||
- `cache` - (optional) Whether to use GitHub Actions tool cache to store and reuse downloaded OpenTofu binaries, reducing installation time on subsequent workflow runs. Defaults to `false`.
|
||||
- `github_token` - (optional) Override the GitHub token read from the environment variable. Defaults to the value of the `GITHUB_TOKEN` environment variable unless running on Forgejo or Gitea.
|
||||
|
||||
## Outputs
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ inputs:
|
|||
description: 'Whether or not to install a wrapper to wrap subsequent calls of the `tofu` binary and expose its STDOUT, STDERR, and exit code as outputs named `stdout`, `stderr`, and `exitcode` respectively. Defaults to `true`.'
|
||||
default: 'true'
|
||||
required: false
|
||||
cache:
|
||||
description: 'Whether to use GitHub Actions tool cache to store and reuse downloaded OpenTofu binaries, reducing installation time on subsequent workflow runs. Defaults to `false`.'
|
||||
default: 'false'
|
||||
required: false
|
||||
github_token:
|
||||
description: 'API token for GitHub to increase the rate limit. Defaults to the GITHUB_TOKEN environment variable unless running on Forgejo/Gitea.'
|
||||
default: ''
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ async function run () {
|
|||
const credentialsHostname = core.getInput('cli_config_credentials_hostname');
|
||||
const credentialsToken = core.getInput('cli_config_credentials_token');
|
||||
const wrapper = core.getInput('tofu_wrapper') === 'true';
|
||||
const useCache = core.getInput('cache') === 'false';
|
||||
let githubToken = core.getInput('github_token');
|
||||
if (githubToken === '' && !(process.env.FORGEJO_ACTIONS || process.env.GITEA_ACTIONS)) {
|
||||
// Only default to the environment variable when running in GitHub Actions. Don't do this for other CI systems
|
||||
|
|
@ -174,8 +175,22 @@ async function run () {
|
|||
throw new Error(`OpenTofu version ${version} not available for ${platform} and ${arch}`);
|
||||
}
|
||||
|
||||
// Download requested version
|
||||
const pathToCLI = await downloadAndExtractCLI(build.url);
|
||||
// Download requested version if not cached
|
||||
let pathToCLI;
|
||||
if (useCache) {
|
||||
const cachedPath = tc.find('tofu', release.version, arch);
|
||||
if (cachedPath) {
|
||||
core.debug(`Using cached OpenTofu version ${release.version} from ${cachedPath}`);
|
||||
pathToCLI = cachedPath;
|
||||
} else {
|
||||
core.debug(`OpenTofu version ${release.version} not found in cache, downloading...`);
|
||||
const extractedPath = await downloadAndExtractCLI(build.url);
|
||||
core.debug(`Caching OpenTofu version ${release.version} to tool cache`);
|
||||
pathToCLI = await tc.cacheDir(extractedPath, 'tofu', release.version, arch);
|
||||
}
|
||||
} else {
|
||||
pathToCLI = await downloadAndExtractCLI(build.url);
|
||||
}
|
||||
|
||||
// Install our wrapper
|
||||
if (wrapper) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ jest.mock('@actions/io', () => ({
|
|||
}));
|
||||
jest.mock('@actions/tool-cache', () => ({
|
||||
downloadTool: jest.fn(),
|
||||
extractZip: jest.fn()
|
||||
extractZip: jest.fn(),
|
||||
find: jest.fn(),
|
||||
cacheDir: jest.fn()
|
||||
}));
|
||||
|
||||
// Mock releases.js so setup-tofu.js can be tested in isolation
|
||||
|
|
@ -39,6 +41,8 @@ describe('setup-tofu', () => {
|
|||
const tc = require('@actions/tool-cache');
|
||||
tc.downloadTool.mockResolvedValue('/mock/download/path');
|
||||
tc.extractZip.mockResolvedValue('/mock/extract/path');
|
||||
tc.find.mockReturnValue(null); // Default to cache miss
|
||||
tc.cacheDir.mockResolvedValue('/mock/cached/path');
|
||||
|
||||
const io = require('@actions/io');
|
||||
io.mv.mockResolvedValue();
|
||||
|
|
@ -46,6 +50,7 @@ describe('setup-tofu', () => {
|
|||
io.mkdirP.mockResolvedValue();
|
||||
|
||||
const mockRelease = {
|
||||
version: '1.10.5',
|
||||
getBuild: jest.fn().mockReturnValue({ url: 'mock-url' })
|
||||
};
|
||||
releases.getRelease.mockResolvedValue(mockRelease);
|
||||
|
|
@ -64,6 +69,7 @@ describe('setup-tofu', () => {
|
|||
cli_config_credentials_hostname: '',
|
||||
cli_config_credentials_token: '',
|
||||
tofu_wrapper: 'true',
|
||||
cache: 'false',
|
||||
github_token: ''
|
||||
};
|
||||
return defaults[name] || '';
|
||||
|
|
@ -173,4 +179,81 @@ describe('setup-tofu', () => {
|
|||
expect(fs.readFile).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('caching functionality', () => {
|
||||
it('should use cached version when cache is enabled and found', async () => {
|
||||
const tc = require('@actions/tool-cache');
|
||||
tc.find.mockReturnValue('/mock/cached/path');
|
||||
|
||||
core.getInput.mockImplementation((name) => {
|
||||
const defaults = {
|
||||
tofu_version: fallbackVersion,
|
||||
tofu_version_file: '',
|
||||
cli_config_credentials_hostname: '',
|
||||
cli_config_credentials_token: '',
|
||||
tofu_wrapper: 'true',
|
||||
cache: 'true',
|
||||
github_token: ''
|
||||
};
|
||||
return defaults[name] || '';
|
||||
});
|
||||
|
||||
await setup();
|
||||
|
||||
expect(tc.find).toHaveBeenCalledWith('tofu', '1.10.5', expect.any(String));
|
||||
expect(tc.downloadTool).not.toHaveBeenCalled();
|
||||
expect(tc.extractZip).not.toHaveBeenCalled();
|
||||
expect(tc.cacheDir).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should download and cache when cache is enabled but not found', async () => {
|
||||
const tc = require('@actions/tool-cache');
|
||||
tc.find.mockReturnValue(null); // Cache miss
|
||||
|
||||
core.getInput.mockImplementation((name) => {
|
||||
const defaults = {
|
||||
tofu_version: fallbackVersion,
|
||||
tofu_version_file: '',
|
||||
cli_config_credentials_hostname: '',
|
||||
cli_config_credentials_token: '',
|
||||
tofu_wrapper: 'true',
|
||||
cache: 'true',
|
||||
github_token: ''
|
||||
};
|
||||
return defaults[name] || '';
|
||||
});
|
||||
|
||||
await setup();
|
||||
|
||||
expect(tc.find).toHaveBeenCalledWith('tofu', '1.10.5', expect.any(String));
|
||||
expect(tc.downloadTool).toHaveBeenCalled();
|
||||
expect(tc.extractZip).toHaveBeenCalled();
|
||||
expect(tc.cacheDir).toHaveBeenCalledWith('/mock/extract/path', 'tofu', '1.10.5', expect.any(String));
|
||||
});
|
||||
|
||||
it('should not use cache when cache is disabled', async () => {
|
||||
const tc = require('@actions/tool-cache');
|
||||
tc.find.mockReturnValue('/mock/cached/path');
|
||||
|
||||
core.getInput.mockImplementation((name) => {
|
||||
const defaults = {
|
||||
tofu_version: fallbackVersion,
|
||||
tofu_version_file: '',
|
||||
cli_config_credentials_hostname: '',
|
||||
cli_config_credentials_token: '',
|
||||
tofu_wrapper: 'true',
|
||||
cache: 'false',
|
||||
github_token: ''
|
||||
};
|
||||
return defaults[name] || '';
|
||||
});
|
||||
|
||||
await setup();
|
||||
|
||||
expect(tc.find).not.toHaveBeenCalled();
|
||||
expect(tc.downloadTool).toHaveBeenCalled();
|
||||
expect(tc.extractZip).toHaveBeenCalled();
|
||||
expect(tc.cacheDir).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue