Skip to content

Commit

Permalink
feat: add option pulumi-version-file (#1204)
Browse files Browse the repository at this point in the history
Similar to how [Setup
Node](https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md?rgh-link-date=2024-06-24T19%3A12%3A42Z#node-version-file)
action works, this adds a new `pulumi-version-file` option that allows
users to specify a file to read the version from.

A lot of our providers use the `.pulumi.version` file to store the
current version of pulumi and we want to be able to use that version
rather than relying on what is already installed.

re pulumi/ci-mgmt#990
  • Loading branch information
corymhall authored Jun 25, 2024
1 parent 2a0c429 commit 1e13f23
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## HEAD (Unreleased)

- feat: add option `pulumi-version-file`
([#1204](https://github.com/pulumi/actions/pull/1204))

---

## 5.2.4 (2024-05-28)
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ The action can be configured with the following arguments:
range is installed. Use "latest" to fetch the latest published release or
"dev" to download the latest development pre-release.

- `pulumi-version-file` - (optional) File containing the version of the Pulumi
CLI to install. Example: .pulumi.version. Only one `pulumi-version` or
`pulumi-version-file` should be provided.

- `remove` - (optional) Removes the target stack if all resources are destroyed.
Used only with `destroy` command.

Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ inputs:
description: 'Install a specific version of the Pulumi CLI'
required: false
default: '^3'
pulumi-version-file:
description: 'File containing the version of the Pulumi CLI to install. Example: .pulumi.version'
required: false
work-dir:
description: 'Location of your Pulumi files. Defaults to ./'
required: false
Expand Down
25 changes: 23 additions & 2 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

89 changes: 89 additions & 0 deletions src/__tests__/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,95 @@ describe('Config without a provided command', () => {
pulumiVersion: '^2',
});
});

it('should read version from pulumi-version-file', async () => {
jest.mock('fs', () => ({
...jest.requireActual('fs'),
readFileSync: jest.fn((path: string) => {
expect(path).toEqual('.pulumi.version');
return '3.121.0';
}),
existsSync: jest.fn(() => {
return true;
}),
}));
jest.mock('@actions/core', () => ({
getInput: jest.fn((name: string) => {
switch (name) {
case 'pulumi-version-file':
return '.pulumi.version';
case 'pulumi-version':
return undefined;
}
return installConfig[name];
}),
}));

const { makeInstallationConfig } = require('../config');
const conf = makeInstallationConfig();
expect(conf.success).toBeTruthy();
expect(conf.value).toEqual({
command: undefined,
pulumiVersion: '3.121.0',
});
});

it('should fail if pulumi-version-file does not exist', async () => {
jest.mock('fs', () => ({
...jest.requireActual('fs'),
readFileSync: jest.fn((path: string) => {
expect(path).toEqual('.pulumi.version');
return '3.121.0';
}),
existsSync: jest.fn(() => {
return false;
}),
}));
jest.mock('@actions/core', () => ({
getInput: jest.fn((name: string) => {
switch (name) {
case 'pulumi-version-file':
return '.pulumi.version';
case 'pulumi-version':
return undefined;
}
return installConfig[name];
}),
}));

const { makeInstallationConfig } = require('../config');
expect(() => {
makeInstallationConfig();
}).toThrow(/pulumi-version-file '\.pulumi\.version' does not exist/);
});

it('should fail if pulumi-version-file and pulumi-version are both provided', async () => {
jest.mock('fs', () => ({
...jest.requireActual('fs'),
readFileSync: jest.fn((path: string) => {
expect(path).toEqual('.pulumi.version');
return '3.121.0';
}),
existsSync: jest.fn(() => {
return false;
}),
}));
jest.mock('@actions/core', () => ({
getInput: jest.fn((name: string) => {
if (name === 'pulumi-version-file') {
return '.pulumi.version';
}
return installConfig[name];
}),
}));

const { makeInstallationConfig } = require('../config');
expect(() => {
makeInstallationConfig();
}).toThrow(
/Only one of 'pulumi-version' or 'pulumi-version-file' should be provided, got both/,
);
});
});

describe('main.login', () => {
Expand Down
28 changes: 26 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as fs from 'fs';
import { ConfigMap } from '@pulumi/pulumi/automation';
import {
getBooleanInput,
Expand All @@ -22,9 +23,25 @@ export const installationConfig = rt.Record({
export type InstallationConfig = rt.Static<typeof installationConfig>;

export function makeInstallationConfig(): rt.Result<InstallationConfig> {
let pulumiVersion = getInput('pulumi-version');
const versionFile = getInput('pulumi-version-file');
if (pulumiVersion && versionFile) {
throw new Error(
"Only one of 'pulumi-version' or 'pulumi-version-file' should be provided, got both",
);
}
if (versionFile) {
if (fs.existsSync(versionFile)) {
pulumiVersion = fs
.readFileSync(versionFile, { encoding: 'utf-8' })
.trim();
} else {
throw new Error(`pulumi-version-file '${versionFile}' does not exist`);
}
}
return installationConfig.validate({
command: getInput('command') || undefined,
pulumiVersion: getInput('pulumi-version') || '^3',
pulumiVersion: pulumiVersion ?? '^3',
});
}

Expand All @@ -33,7 +50,14 @@ export function makeConfig() {
return {
command: getUnionInput('command', {
required: true,
alternatives: ['up', 'update', 'refresh', 'destroy', 'preview', 'output'] as const,
alternatives: [
'up',
'update',
'refresh',
'destroy',
'preview',
'output',
] as const,
}),
stackName: getInput('stack-name', { required: true }),
pulumiVersion: getInput('pulumi-version', { required: true }),
Expand Down

0 comments on commit 1e13f23

Please sign in to comment.