From d19cafcdd1be7e3358f84574a00df37af494036a Mon Sep 17 00:00:00 2001 From: Clare Liguori Date: Wed, 29 Jul 2020 09:03:44 -0700 Subject: [PATCH] feat: Add post-job action cleanup of credentials and region env vars (#101) --- action.yml | 1 + cleanup.js | 36 ++++++++++++++++++++++++++++++++++ cleanup.test.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ index.test.js | 2 +- package.json | 4 ++-- 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 cleanup.js create mode 100644 cleanup.test.js diff --git a/action.yml b/action.yml index 5c3ce8328..fafa25b8a 100644 --- a/action.yml +++ b/action.yml @@ -52,3 +52,4 @@ outputs: runs: using: 'node12' main: 'dist/index.js' + post: 'dist/cleanup/index.js' diff --git a/cleanup.js b/cleanup.js new file mode 100644 index 000000000..0ea67f247 --- /dev/null +++ b/cleanup.js @@ -0,0 +1,36 @@ +const core = require('@actions/core'); + +/** + * When the GitHub Actions job is done, clean up any environment variables that + * may have been set by the configure-aws-credentials steps in the job. + * + * Environment variables are not intended to be shared across different jobs in + * the same GitHub Actions workflow: GitHub Actions documentation states that + * each job runs in a fresh instance. However, doing our own cleanup will + * give us additional assurance that these environment variables are not shared + * with any other jobs. + */ + +async function cleanup() { + try { + // The GitHub Actions toolkit does not have an option to completely unset + // environment variables, so we overwrite the current value with an empty + // string. The AWS CLI and AWS SDKs will behave correctly: they treat an + // empty string value as if the environment variable does not exist. + core.exportVariable('AWS_ACCESS_KEY_ID', ''); + core.exportVariable('AWS_SECRET_ACCESS_KEY', ''); + core.exportVariable('AWS_SESSION_TOKEN', ''); + core.exportVariable('AWS_DEFAULT_REGION', ''); + core.exportVariable('AWS_REGION', ''); + } + catch (error) { + core.setFailed(error.message); + } +} + +module.exports = cleanup; + +/* istanbul ignore next */ +if (require.main === module) { + cleanup(); +} diff --git a/cleanup.test.js b/cleanup.test.js new file mode 100644 index 000000000..a84eaaf5d --- /dev/null +++ b/cleanup.test.js @@ -0,0 +1,51 @@ +const core = require('@actions/core'); +const cleanup = require('./cleanup.js'); + +jest.mock('@actions/core'); + +const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID'; +const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY'; +const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN'; +const FAKE_REGION = 'fake-region-1'; +const ACTION_ENVIRONMENT_VARIABLES = { + AWS_ACCESS_KEY_ID: FAKE_ACCESS_KEY_ID, + AWS_SECRET_ACCESS_KEY: FAKE_SECRET_ACCESS_KEY, + AWS_SESSION_TOKEN: FAKE_SESSION_TOKEN, + AWS_DEFAULT_REGION: FAKE_REGION, + AWS_REGION: FAKE_REGION, +}; + +describe('Configure AWS Credentials', () => { + const OLD_ENV = process.env; + + beforeEach(() => { + jest.resetModules(); + process.env = {...OLD_ENV, ...ACTION_ENVIRONMENT_VARIABLES}; + }); + + afterEach(() => { + process.env = OLD_ENV; + }); + + test('replaces AWS credential and region env vars with empty strings', async () => { + await cleanup(); + expect(core.setFailed).toHaveBeenCalledTimes(0); + expect(core.exportVariable).toHaveBeenCalledTimes(5); + expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', ''); + expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', ''); + expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', ''); + expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', ''); + expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', ''); + }); + + test('error is caught and fails the action', async () => { + core.exportVariable.mockReset(); + core.exportVariable.mockImplementation(() => { + throw new Error(); + }); + + await cleanup(); + + expect(core.setFailed).toBeCalled(); + }); +}); diff --git a/index.test.js b/index.test.js index 19fbc6020..e03f480de 100644 --- a/index.test.js +++ b/index.test.js @@ -1,7 +1,7 @@ const core = require('@actions/core'); const assert = require('assert'); const aws = require('aws-sdk'); -const run = require('.'); +const run = require('./index.js'); jest.mock('@actions/core'); diff --git a/package.json b/package.json index 06ddc60a4..aacc2723b 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "main": "index.js", "scripts": { "lint": "eslint **.js", - "package": "ncc build index.js -o dist", - "test": "eslint **.js && jest --coverage" + "package": "ncc build index.js -o dist && ncc build cleanup.js -o dist/cleanup", + "test": "eslint **.js && jest --coverage --verbose" }, "repository": { "type": "git",