diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6717649..432cd25 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies @@ -31,7 +31,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies @@ -57,7 +57,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies @@ -84,7 +84,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies @@ -107,7 +107,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f27e67e..6b07db6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies @@ -35,7 +35,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies @@ -55,7 +55,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies @@ -81,7 +81,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies diff --git a/action.yml b/action.yml index 23bc013..a030250 100644 --- a/action.yml +++ b/action.yml @@ -1,27 +1,27 @@ -name: 'aws-secrets-manager-actions' -description: 'GitHub Actions for AWS Secrets Manager' +name: "aws-secrets-manager-actions" +description: "GitHub Actions for AWS Secrets Manager" inputs: SECRET_NAME: - description: 'Set secret name that you want to get.' + description: "Set secret name that you want to get." required: true AWS_ACCESS_KEY_ID: - description: 'Set Aws Access Key ID' + description: "Set Aws Access Key ID" required: false AWS_SECRET_ACCESS_KEY: - description: 'Set Aws Secret access Key' + description: "Set Aws Secret access Key" required: false AWS_SESSION_TOKEN: - description: 'Set Aws Session token Key' + description: "Set Aws Session token Key" required: false AWS_DEFAULT_REGION: - description: 'Set Aws default region' + description: "Set Aws default region" required: false OUTPUT_PATH: - description: 'Set output file where variables are write' + description: "Set output file where variables are write" required: false runs: - using: 'node16' - main: 'dist/index.js' + using: "node20" + main: "dist/index.js" branding: - icon: 'lock' - color: 'orange' + icon: "lock" + color: "orange" diff --git a/index.js b/index.js index 9a47dba..89bebfd 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,6 @@ const aws = require('aws-sdk') const fs = require('fs') const outputPath = core.getInput('OUTPUT_PATH') -const secretName = core.getInput('SECRET_NAME') const AWSConfig = { accessKeyId: core.getInput('AWS_ACCESS_KEY_ID') || process.env.AWS_ACCESS_KEY_ID, @@ -15,40 +14,41 @@ if (core.getInput('AWS_SESSION_TOKEN') || process.env.AWS_SESSION_TOKEN) { AWSConfig.sessionToken = core.getInput('AWS_SESSION_TOKEN') || process.env.AWS_SESSION_TOKEN } -const secretsManager = new aws.SecretsManager(AWSConfig) - async function getSecretValue (secretsManager, secretName) { - return secretsManager.getSecretValue({ SecretId: secretName }).promise() -} + try { + if (!secretsManager) { + secretsManager = new aws.SecretsManager(AWSConfig) + } -getSecretValue(secretsManager, secretName).then(resp => { - const secretString = resp.SecretString - core.setSecret(secretString) + const resp = await secretsManager.getSecretValue({ SecretId: secretName }).promise() + const secretString = resp.SecretString + core.setSecret(secretString) - if (secretString == null) { - core.warning(`${secretName} has no secret values`) - return - } - - try { - const parsedSecret = JSON.parse(secretString) - Object.entries(parsedSecret).forEach(([key, value]) => { - core.setSecret(value) - core.exportVariable(key, value) - }) - if (outputPath) { - const secretsAsEnv = Object.entries(parsedSecret).map(([key, value]) => `${key}=${value}`).join('\n') - fs.writeFileSync(outputPath, secretsAsEnv) + if (secretString == null) { + core.warning(`${secretName} has no secret values`) + return } - } catch (e) { - core.warning('Parsing asm secret is failed. Secret will be store in asm_secret') - core.exportVariable('asm_secret', secretString) - if (outputPath) { - fs.writeFileSync(outputPath, secretString) + + try { + const parsedSecret = JSON.parse(secretString) + Object.entries(parsedSecret).forEach(([key, value]) => { + core.setSecret(value) + core.exportVariable(key, value) + }) + if (outputPath) { + const secretsAsEnv = Object.entries(parsedSecret).map(([key, value]) => `${key}=${value}`).join('\n') + fs.writeFileSync(outputPath, secretsAsEnv) + } + } catch (e) { + core.warning('Parsing asm secret is failed. Secret will be store in asm_secret') + core.exportVariable('asm_secret', secretString) + if (outputPath) { + fs.writeFileSync(outputPath, secretString) + } } + } catch (err) { + core.setFailed(err) } -}).catch(err => { - core.setFailed(err) -}) +} exports.getSecretValue = getSecretValue diff --git a/index.test.js b/index.test.js index 2e4d34f..a2c2ae7 100644 --- a/index.test.js +++ b/index.test.js @@ -2,54 +2,37 @@ const aws = require('aws-sdk') const index = require('./index.js') describe('get SecretString from AWS SecretsManager', () => { - let data = {} - describe('get parsable data', () => { - beforeAll(async () => { - const INPUT_SECRET_NAME = process.env.SECRET_NAME - - const AWSConfig = { - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - region: process.env.AWS_DEFAULT_REGION - } + const secretsManager = new aws.SecretsManager({ + accessKeyId: 'fake-access-key-id', + secretAccessKey: 'fake-secret', + region: 'us-east-1' + }) - if (process.env.AWS_SESSION_TOKEN) { - AWSConfig.sessionToken = process.env.AWS_SESSION_TOKEN - } + const secretName = 'secretName' - const secretsManager = new aws.SecretsManager(AWSConfig) - data = await index.getSecretValue(secretsManager, INPUT_SECRET_NAME) - }) + const secretString = JSON.stringify({ + key1: 'value1', + key2: 'value2' + }) - test('should have SecretString', () => { - expect(data).toHaveProperty('SecretString') - }) + const resp = { + SecretString: secretString + } - test('should have parsed values', () => { - const parsedData = JSON.parse(data.SecretString) - expect(parsedData.SCIENTIFIC_NAME).toEqual('Pygoscelis adeliae') - expect(parsedData.MIN_HEIGHT).toEqual(46) - expect(parsedData.MAX_HEIGHT).toEqual(71) - expect(parsedData.MIN_WEIGHT).toEqual(3.6) - expect(parsedData.MAX_WEIGHT).toEqual(6) - expect(parsedData.SWIMMING_SPEED).toEqual(8) - expect(parsedData.LEAPING_METERS).toEqual(3) - }) + secretsManager.getSecretValue = jest.fn().mockReturnValue({ + promise: jest.fn().mockResolvedValue(resp) }) - describe('get unparsable data', () => { - beforeAll(async () => { - const INPUT_SECRET_NAME = `${process.env.SECRET_NAME}-unvalid` - const secretsManager = new aws.SecretsManager({ - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - region: process.env.AWS_DEFAULT_REGION - }) - data = await index.getSecretValue(secretsManager, INPUT_SECRET_NAME) - }) + it('should have parsed values', async () => { + await index.getSecretValue(secretsManager, secretName) + expect(process.env.key1).toEqual('value1') + expect(process.env.key2).toEqual('value2') + }) - test('should have SecretString', () => { - expect(data).toHaveProperty('SecretString') - }) + it('should have written to file', async () => { + const fs = require('fs') + const outputPath = '.env' + await index.getSecretValue(secretsManager, secretName) + expect(fs.readFileSync(outputPath, 'utf8')).toEqual('key1=value1\nkey2=value2') }) }) diff --git a/jest.config.js b/jest.config.js index 41613cd..9cd29bc 100644 --- a/jest.config.js +++ b/jest.config.js @@ -7,3 +7,7 @@ module.exports = { }, setupFiles: ['dotenv/config'] } + +process.env = Object.assign(process.env, { + INPUT_OUTPUT_PATH: '.env' +}) diff --git a/package.json b/package.json index 4fe774c..bfe5dad 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "aws-sdk": "^2.1070.0" }, "devDependencies": { - "@zeit/ncc": "^0.22.1", + "@vercel/ncc": "^0.38.1", "dotenv": "^8.2.0", "eslint": "7.4.0", "eslint-plugin-import": "^2.20.2", diff --git a/yarn.lock b/yarn.lock index 9d2bc50..265b166 100644 --- a/yarn.lock +++ b/yarn.lock @@ -611,10 +611,10 @@ semver "^7.3.2" tsutils "^3.17.1" -"@zeit/ncc@^0.22.1": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.22.3.tgz#fca6b86b4454ce7a7e1e7e755165ec06457f16cd" - integrity sha512-jnCLpLXWuw/PAiJiVbLjA8WBC0IJQbFeUwF4I9M+23MvIxTxk5pD4Q8byQBSPmHQjz5aBoA7AKAElQxMpjrCLQ== +"@vercel/ncc@^0.38.1": + version "0.38.1" + resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.38.1.tgz#13f08738111e1d9e8a22fd6141f3590e54d9a60e" + integrity sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw== abab@^2.0.3: version "2.0.3"