Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utilize .tool-versions file to resolve terraform version #323

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
34 changes: 32 additions & 2 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,36 @@ function mapOS (os) {
return mappings[os] || os;
}

async function resolveVersion () {
let version = core.getInput('terraform_version');

if (!version) {
version = await getToolVersions();
}

return version;
}

async function getToolVersions () {
let version = '';
core.debug('Attempting to infer Terraform version from .tool-versions');

if (await fs.existsSync('.tool-versions')) {
const contents = await fs.readFileSync('.tool-versions').toString();
const match = contents.match(/^terraform (\d+(\.\d+)*)/m);

if (!match) {
core.debug('Could not find a valid terraform version from .tool-versions');
} else {
version = match[1];
}
} else {
core.debug('.tool-versions does not exist');
}

return version;
}

async function downloadCLI (url) {
core.debug(`Downloading Terraform CLI from ${url}`);
const pathToCLIZip = await tc.downloadTool(url);
Expand All @@ -50,7 +80,7 @@ async function downloadCLI (url) {
if (os.platform().startsWith('win')) {
core.debug(`Terraform CLI Download Path is ${pathToCLIZip}`);
const fixedPathToCLIZip = `${pathToCLIZip}.zip`;
io.mv(pathToCLIZip, fixedPathToCLIZip);
await io.mv(pathToCLIZip, fixedPathToCLIZip);
core.debug(`Moved download to ${fixedPathToCLIZip}`);
pathToCLI = await tc.extractZip(fixedPathToCLIZip);
} else {
Expand Down Expand Up @@ -130,7 +160,7 @@ credentials "${credentialsHostname}" {
async function run () {
try {
// Gather GitHub Actions inputs
const version = core.getInput('terraform_version');
const version = await resolveVersion();
const credentialsHostname = core.getInput('cli_config_credentials_hostname');
const credentialsToken = core.getInput('cli_config_credentials_token');
const wrapper = core.getInput('terraform_wrapper') === 'true';
Expand Down
34 changes: 32 additions & 2 deletions lib/setup-terraform.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,36 @@ function mapOS (os) {
return mappings[os] || os;
}

async function resolveVersion () {
let version = core.getInput('terraform_version');

if (!version) {
version = await getToolVersions();
}

return version;
}

async function getToolVersions () {
let version = '';
core.debug('Attempting to infer Terraform version from .tool-versions');

if (await fs.existsSync('.tool-versions')) {
const contents = await fs.readFileSync('.tool-versions').toString();
const match = contents.match(/^terraform (\d+(\.\d+)*)/m);

if (!match) {
core.debug('Could not find a valid terraform version from .tool-versions');
} else {
version = match[1];
}
} else {
core.debug('.tool-versions does not exist');
}

return version;
}

async function downloadCLI (url) {
core.debug(`Downloading Terraform CLI from ${url}`);
const pathToCLIZip = await tc.downloadTool(url);
Expand All @@ -44,7 +74,7 @@ async function downloadCLI (url) {
if (os.platform().startsWith('win')) {
core.debug(`Terraform CLI Download Path is ${pathToCLIZip}`);
const fixedPathToCLIZip = `${pathToCLIZip}.zip`;
io.mv(pathToCLIZip, fixedPathToCLIZip);
await io.mv(pathToCLIZip, fixedPathToCLIZip);
core.debug(`Moved download to ${fixedPathToCLIZip}`);
pathToCLI = await tc.extractZip(fixedPathToCLIZip);
} else {
Expand Down Expand Up @@ -124,7 +154,7 @@ credentials "${credentialsHostname}" {
async function run () {
try {
// Gather GitHub Actions inputs
const version = core.getInput('terraform_version');
const version = await resolveVersion();
const credentialsHostname = core.getInput('cli_config_credentials_hostname');
const credentialsToken = core.getInput('cli_config_credentials_token');
const wrapper = core.getInput('terraform_wrapper') === 'true';
Expand Down
40 changes: 40 additions & 0 deletions test/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,46 @@
"url": "https://releases.hashicorp.com/terraform/0.10.0/terraform_0.10.0_windows_386.zip"
}
]
},
"1.3.7": {
"name": "terraform",
"version": "1.3.7",
"shasums": "terraform_1.3.7_SHA256SUMS",
"shasums_signature": "terraform_1.3.7_SHA256SUMS.sig",
"builds": [
{
"name": "terraform",
"version": "1.3.7",
"os": "darwin",
"arch": "amd64",
"filename": "terraform_1.3.7_darwin_amd64.zip",
"url": "https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_darwin_amd64.zip"
},
{
"name": "terraform",
"version": "1.3.7",
"os": "linux",
"arch": "386",
"filename": "terraform_1.3.7_linux_386.zip",
"url": "https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_linux_386.zip"
},
{
"name": "terraform",
"version": "1.3.7",
"os": "linux",
"arch": "amd64",
"filename": "terraform_1.3.7_linux_amd64.zip",
"url": "https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_linux_amd64.zip"
},
{
"name": "terraform",
"version": "1.3.7",
"os": "windows",
"arch": "386",
"filename": "terraform_1.3.7_windows_386.zip",
"url": "https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_windows_386.zip"
}
]
}
}
}
55 changes: 54 additions & 1 deletion test/setup-terraform.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ describe('Setup Terraform', () => {
.reply(200, json);

const versionObj = await setup();
expect(versionObj.version).toEqual('0.10.0');
expect(versionObj.version).toEqual('1.3.7');

// downloaded CLI has been added to path
expect(core.addPath).toHaveBeenCalled();
Expand Down Expand Up @@ -425,6 +425,59 @@ describe('Setup Terraform', () => {
expect(creds.indexOf(credentialsToken)).toBeGreaterThan(-1);
});

test('gets version from .tool-versions when version not provided', async () => {
const credentialsHostname = 'app.terraform.io';
const credentialsToken = 'asdfjkl';

fs.existsSync = jest
.fn()
.mockReturnValueOnce(true);

fs.readFileSync = jest
.fn()
.mockReturnValueOnce(`terraform 1.3.7
golang 1.16.3
python 3.10.11
ruby 3.2.1
`);

core.getInput = jest
.fn()
.mockReturnValueOnce(null)
.mockReturnValueOnce(credentialsHostname)
.mockReturnValueOnce(credentialsToken);

tc.downloadTool = jest
.fn()
.mockReturnValueOnce('file.zip');

tc.extractZip = jest
.fn()
.mockReturnValueOnce('file');

os.platform = jest
.fn()
.mockReturnValue('linux');

os.arch = jest
.fn()
.mockReturnValue('amd64');

nock('https://releases.hashicorp.com')
.get('/terraform/index.json')
.reply(200, json);

const versionObj = await setup();
expect(versionObj.version).toEqual('1.3.7');

// downloaded CLI has been added to path
expect(core.addPath).toHaveBeenCalled();
// expect credentials are in ${HOME}.terraformrc
const creds = await fs.readFile(`${process.env.HOME}/.terraformrc`, { encoding: 'utf8' });
expect(creds.indexOf(credentialsHostname)).toBeGreaterThan(-1);
expect(creds.indexOf(credentialsToken)).toBeGreaterThan(-1);
});

test('fails when metadata cannot be downloaded', async () => {
const version = 'latest';
const credentialsHostname = 'app.terraform.io';
Expand Down