From 68442af185b083f3496e4ca6cd1d90211cc70ebe Mon Sep 17 00:00:00 2001 From: Nikita Sharaev Date: Wed, 28 Dec 2022 14:45:36 +0400 Subject: [PATCH 1/4] feature: add plugins section --- .github/workflows/test.yml | 1 + action.yml | 4 ++++ src/__tests__/config.test.ts | 3 +++ src/config.ts | 12 +++++++++++- src/main.ts | 10 ++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1bc69b70..3c76cefc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,4 +55,5 @@ jobs: upsert: true work-dir: .github/test-stacks/golang config-map: "{name: {value: test, secret: false}}" + plugins: "[{name: time, version: 0.0.9, kind: resource}]" - run: echo 'The random string is `${{ steps.pulumi.outputs.name }}`' diff --git a/action.yml b/action.yml index 4048c55c..a60f1481 100644 --- a/action.yml +++ b/action.yml @@ -47,6 +47,10 @@ inputs: description: 'Config to use during the operations' required: false default: '' + plugins: + description: 'Plugins which will install' + required: false + default: '[]' expect-no-changes: description: 'Return an error if any changes occur during this update' required: false diff --git a/src/__tests__/config.test.ts b/src/__tests__/config.test.ts index b8da0c92..628f7d80 100644 --- a/src/__tests__/config.test.ts +++ b/src/__tests__/config.test.ts @@ -55,6 +55,7 @@ describe('config.ts', () => { }, "refresh": undefined, "remove": undefined, + "plugins": undefined, "secretsProvider": undefined, "stackName": "dev", "upsert": undefined, @@ -120,6 +121,7 @@ describe('config.ts', () => { }, "refresh": undefined, "remove": undefined, + "plugins": undefined, "secretsProvider": undefined, "stackName": "dev", "upsert": undefined, @@ -177,6 +179,7 @@ describe('config.ts', () => { }, "refresh": undefined, "remove": undefined, + "plugins": undefined, "secretsProvider": undefined, "stackName": "dev", "upsert": undefined, diff --git a/src/config.ts b/src/config.ts index a46ed684..8ee7defe 100644 --- a/src/config.ts +++ b/src/config.ts @@ -10,9 +10,17 @@ export const command = rt.Union( rt.Literal('destroy'), rt.Literal('preview'), ); - export type Commands = rt.Static; +const plugin = rt.Partial({ + name: rt.String, + version: rt.String, + server: rt.String, + kind: rt.String +}); +type Plugin = rt.Static; +type Plugins = Plugin[]; + export const options = rt.Partial({ parallel: rt.Number, message: rt.String, @@ -48,6 +56,7 @@ export const config = rt upsert: rt.Boolean, remove: rt.Boolean, refresh: rt.Boolean, + plugins: rt.Array(plugin), secretsProvider: rt.String, commentOnPrNumber: rt.Number, }), @@ -69,6 +78,7 @@ export async function makeConfig(): Promise { remove: parseBoolean(getInput('remove')), refresh: parseBoolean(getInput('refresh')), configMap: getInput('config-map'), + plugins: JSON.parse(getInput('plugins')) as Plugins, isPullRequest: context?.payload?.pull_request !== undefined, options: { parallel: parseNumber(getInput('parallel')), diff --git a/src/main.ts b/src/main.ts index 052fe08b..3743b2e8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -54,6 +54,16 @@ const main = async () => { await stack.setAllConfig(configMap); } + if (config.plugins != []) { + for(const plugin of config.plugins) { + if (plugin.server) { + stack.workspace.installPluginFromServer(plugin.name, plugin.version, plugin.server); + } else { + stack.workspace.installPlugin(plugin.name, plugin.version, plugin.kind); + } + } + } + if (config.refresh) { core.startGroup(`Refresh stack on ${config.stackName}`); await stack.refresh({ onOutput }); From 00c493b1f3ccce4891257f5e5e29d83a091354aa Mon Sep 17 00:00:00 2001 From: Nikita Sharaev Date: Wed, 28 Dec 2022 14:56:20 +0400 Subject: [PATCH 2/4] fix: modify types and add GH workflow test --- .github/workflows/test.yml | 10 +++++++++- src/__tests__/config.test.ts | 6 +++--- src/config.ts | 8 ++++---- src/libs/utils.ts | 12 ++++++++++++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3c76cefc..29265561 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,6 +12,11 @@ on: # rebuild any PRs and main branch changes - 'CHANGELOG.md' - 'README.md' +env: + TEST_PLUGIN_NAME: "time" + TEST_PLUGIN_VERSION: "0.0.9" + TEST_PLUGIN_SERVER: "https://github.com/pulumiverse/pulumi-time/releases/download/v0.0.9" + jobs: build-test: # make sure build/ci work properly runs-on: ubuntu-latest @@ -55,5 +60,8 @@ jobs: upsert: true work-dir: .github/test-stacks/golang config-map: "{name: {value: test, secret: false}}" - plugins: "[{name: time, version: 0.0.9, kind: resource}]" + plugins: "[{name: ${{ env.TEST_PLUGIN_NAME }}, version: ${{ env.TEST_PLUGIN_VERSION }}, server: ${{ env.TEST_PLUGIN_SERVER }}}]" - run: echo 'The random string is `${{ steps.pulumi.outputs.name }}`' + - run: | + pulumi plugin ls | grep ${{ env.TEST_PLUGIN_NAME }} | grep ${{ env.TEST_PLUGIN_VERSION }} + exit $? diff --git a/src/__tests__/config.test.ts b/src/__tests__/config.test.ts index 628f7d80..c268b3d4 100644 --- a/src/__tests__/config.test.ts +++ b/src/__tests__/config.test.ts @@ -53,9 +53,9 @@ describe('config.ts', () => { "targetDependents": undefined, "userAgent": "pulumi/actions@v3", }, + "plugins": Array [], "refresh": undefined, "remove": undefined, - "plugins": undefined, "secretsProvider": undefined, "stackName": "dev", "upsert": undefined, @@ -119,9 +119,9 @@ describe('config.ts', () => { "targetDependents": undefined, "userAgent": "pulumi/actions@v3", }, + "plugins": Array [], "refresh": undefined, "remove": undefined, - "plugins": undefined, "secretsProvider": undefined, "stackName": "dev", "upsert": undefined, @@ -177,9 +177,9 @@ describe('config.ts', () => { "targetDependents": undefined, "userAgent": "pulumi/actions@v3", }, + "plugins": Array [], "refresh": undefined, "remove": undefined, - "plugins": undefined, "secretsProvider": undefined, "stackName": "dev", "upsert": undefined, diff --git a/src/config.ts b/src/config.ts index 8ee7defe..4ea1bc58 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,7 +1,7 @@ import { getInput } from '@actions/core'; import { context } from '@actions/github'; import * as rt from 'runtypes'; -import { parseArray, parseBoolean, parseNumber } from './libs/utils'; +import { parseArray, parseBoolean, parseNumber, parsePlugins } from './libs/utils'; export const command = rt.Union( rt.Literal('up'), @@ -18,8 +18,8 @@ const plugin = rt.Partial({ server: rt.String, kind: rt.String }); -type Plugin = rt.Static; -type Plugins = Plugin[]; +export type Plugin = rt.Static; +export type Plugins = Plugin[]; export const options = rt.Partial({ parallel: rt.Number, @@ -78,7 +78,7 @@ export async function makeConfig(): Promise { remove: parseBoolean(getInput('remove')), refresh: parseBoolean(getInput('refresh')), configMap: getInput('config-map'), - plugins: JSON.parse(getInput('plugins')) as Plugins, + plugins: parsePlugins(getInput('plugins')), isPullRequest: context?.payload?.pull_request !== undefined, options: { parallel: parseNumber(getInput('parallel')), diff --git a/src/libs/utils.ts b/src/libs/utils.ts index 60531188..da411ee1 100644 --- a/src/libs/utils.ts +++ b/src/libs/utils.ts @@ -1,3 +1,6 @@ +import YAML from 'yaml'; +import { Plugin, Plugins } from '../config'; + export function parseArray(input: string): string[] { return parseUndefined(input) ? input.split(/\r?\n/).reduce( @@ -22,3 +25,12 @@ export function parseBoolean(input: string): boolean | undefined { export function parseNumber(input: string): number | undefined { return parseUndefined(input) ? Number(input) : undefined; } + +export function parsePlugins(input: string): Plugins { + if (parseUndefined(input)) { + const plugins = YAML.parse(input); + return plugins.map(plugin => plugin as Plugin) as Plugins; + } else { + return [] as Plugins; + } +} From c83c71388f7f65f3dd62e64cd1f7c5840aacafd3 Mon Sep 17 00:00:00 2001 From: Nikita Sharaev Date: Wed, 28 Dec 2022 16:26:23 +0400 Subject: [PATCH 3/4] fix: add default value and description --- CHANGELOG.md | 1 + README.md | 13 ++++++++----- src/main.ts | 7 +++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38efb3ec..bfed7a8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG - feat: Add deletion of stack after destroy (remove flag) +- feat: add plugins installation -- diff --git a/README.md b/README.md index 47da07d1..5e160a0c 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ The action can be configured with the following arguments: values are `up` (update), `refresh`, `destroy` and `preview`. - `stack-name` (required) - The name of the stack that Pulumi will be operating - on. Use the fully quaified org-name/stack-name when operating on a stack outside - of your individual account. + on. Use the fully quaified org-name/stack-name when operating on a stack + outside of your individual account. - `work-dir` (optional) - The location of your Pulumi files. Defaults to `./`. @@ -63,7 +63,7 @@ The action can be configured with the following arguments: - `secrets-provider` - (optional) The type of the provider that should be used to encrypt and decrypt secrets. Possible choices: `default`, `passphrase`, `awskms`, `azurekeyvault`, `gcpkms`, `hashivault`. e.g. - `gcpkms://projects//locations/us-west1/keyRings/acmecorpsec/cryptoKeys/payroll ` + `gcpkms://projects//locations/us-west1/keyRings/acmecorpsec/cryptoKeys/payroll` - `color` - (optional) Colorize output. Choices are: always, never, raw, auto (default "auto"). @@ -100,13 +100,16 @@ The action can be configured with the following arguments: - `config-map` - (optional) Configuration of the stack. Format Yaml string: `{: {value: , secret: },}`. +- `plugins` - (optional) Installation Pulumi plugins. Format Yaml string: + `[{name: , version: , kind?: , server?: }, ...]`. + - `upsert` - (optional) Allows the creation of the specified stack if it currently doesn't exist. **PLEASE NOTE:** This will create a `Pulumi..yaml` file that you will need to add back to source control as part of the action if you wish to perform any further tasks with that stack. -- `remove` - (optional) Removes the target stack if all resources are - destroyed. Used only with `destroy` command. +- `remove` - (optional) Removes the target stack if all resources are destroyed. + Used only with `destroy` command. - `pulumi-version` - (optional) Install a specific version of the Pulumi CLI. Defaults to "^3" diff --git a/src/main.ts b/src/main.ts index 3743b2e8..c191c68c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -57,9 +57,12 @@ const main = async () => { if (config.plugins != []) { for(const plugin of config.plugins) { if (plugin.server) { - stack.workspace.installPluginFromServer(plugin.name, plugin.version, plugin.server); + await stack.workspace.installPluginFromServer(plugin.name, + plugin.version, + plugin.server); } else { - stack.workspace.installPlugin(plugin.name, plugin.version, plugin.kind); + await stack.workspace.installPlugin(plugin.name, plugin.version, + plugin.kind || 'resource'); } } } From 0de202d3a79a82a71cf017460e132e4a1a24a59c Mon Sep 17 00:00:00 2001 From: Nikita Sharaev Date: Wed, 28 Dec 2022 16:55:24 +0400 Subject: [PATCH 4/4] fix: change type of fields --- src/config.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/config.ts b/src/config.ts index 4ea1bc58..82923f47 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,12 +12,13 @@ export const command = rt.Union( ); export type Commands = rt.Static; -const plugin = rt.Partial({ +const plugin = rt.Record({ name: rt.String, version: rt.String, +}).And(rt.Partial({ server: rt.String, kind: rt.String -}); +})); export type Plugin = rt.Static; export type Plugins = Plugin[];