Skip to content

Commit

Permalink
feat: add environment-variables support (aws-actions#114)
Browse files Browse the repository at this point in the history
* feat: support for setting environment variables

* chore: Update dist

Co-authored-by: GitHub Actions <runner@fv-az224-488.bi4zmy1qo3tuniz3adueuvvcza.cx.internal.cloudapp.net>
  • Loading branch information
2 people authored and David Stephens committed Dec 2, 2022
1 parent e3a2b4b commit 5fba5aa
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 6 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ To insert the image URI `amazon/amazon-ecs-sample:latest` as the image for the `
task-definition: task-definition.json
container-name: web
image: amazon/amazon-ecs-sample:latest
environment-variables: "LOG_LEVEL=info"

- name: Deploy to Amazon ECS service
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
Expand All @@ -46,6 +47,9 @@ input of the second:
task-definition: task-definition.json
container-name: web
image: amazon/amazon-ecs-sample-1:latest
environment-variables: |
LOG_LEVEL=info
ENVIRONMENT=prod
- name: Modify Amazon ECS task definition with second container
id: render-app-container
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ inputs:
env-list:
description: 'A list of variables to pull from the environment'
required: false
environment-variables:
description: 'Variables to add to the container. Each variable is of the form KEY=value, you can specify multiple variables with multi-line YAML strings.'
required: false
outputs:
task-definition:
description: 'The path to the rendered task definition file'
Expand Down
40 changes: 40 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,8 @@ async function run() {
const containerName = core.getInput('container-name', { required: true });
const imageURI = core.getInput('image', { required: true });

const environmentVariables = core.getInput('environment-variables', { required: false });

// Parse the task definition
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
taskDefinitionFile :
Expand All @@ -1214,6 +1216,44 @@ async function run() {
}
containerDef.image = imageURI;

if (environmentVariables) {

// If environment array is missing, create it
if (!Array.isArray(containerDef.environment)) {
containerDef.environment = [];
}

// Get pairs by splitting on newlines
environmentVariables.split('\n').forEach(function (line) {
// Trim whitespace
const trimmedLine = line.trim();
// Skip if empty
if (trimmedLine.length === 0) { return; }
// Split on =
const separatorIdx = trimmedLine.indexOf("=");
// If there's nowhere to split
if (separatorIdx === -1) {
throw new Error(`Cannot parse the environment variable '${trimmedLine}'. Environment variable pairs must be of the form NAME=value.`);
}
// Build object
const variable = {
name: trimmedLine.substring(0, separatorIdx),
value: trimmedLine.substring(separatorIdx + 1),
};

// Search container definition environment for one matching name
const variableDef = containerDef.environment.find((e) => e.name == variable.name);
if (variableDef) {
// If found, update
variableDef.value = variable.value;
} else {
// Else, create
containerDef.environment.push(variable);
}
})
}


// Write out a new task definition file
var updatedTaskDefFile = tmp.fileSync({
tmpdir: process.env.RUNNER_TEMP,
Expand Down
40 changes: 40 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ async function run() {
}
console.log(envList)

const environmentVariables = core.getInput('environment-variables', { required: false });

// Parse the task definition
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
taskDefinitionFile :
Expand Down Expand Up @@ -75,6 +77,44 @@ async function run() {
taskDefContents.family = serviceFamily;
}

if (environmentVariables) {

// If environment array is missing, create it
if (!Array.isArray(containerDef.environment)) {
containerDef.environment = [];
}

// Get pairs by splitting on newlines
environmentVariables.split('\n').forEach(function (line) {
// Trim whitespace
const trimmedLine = line.trim();
// Skip if empty
if (trimmedLine.length === 0) { return; }
// Split on =
const separatorIdx = trimmedLine.indexOf("=");
// If there's nowhere to split
if (separatorIdx === -1) {
throw new Error(`Cannot parse the environment variable '${trimmedLine}'. Environment variable pairs must be of the form NAME=value.`);
}
// Build object
const variable = {
name: trimmedLine.substring(0, separatorIdx),
value: trimmedLine.substring(separatorIdx + 1),
};

// Search container definition environment for one matching name
const variableDef = containerDef.environment.find((e) => e.name == variable.name);
if (variableDef) {
// If found, update
variableDef.value = variable.value;
} else {
// Else, create
containerDef.environment.push(variable);
}
})
}


// Write out a new task definition file
var updatedTaskDefFile = tmp.fileSync({
tmpdir: process.env.RUNNER_TEMP,
Expand Down
43 changes: 37 additions & 6 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ describe('Render task definition', () => {
.mockReturnValueOnce('nginx:latest')
.mockReturnValueOnce('log-group')
.mockReturnValueOnce('service-family')
.mockReturnValueOnce('[ "DJANGO_ACCOUNT_ALLOW_REGISTRATION", "DJANGO_ADMIN_URL", "DJANGO_AWS_REGION_NAME", "DJANGO_AWS_S3_CUSTOM_DOMAIN", "DJANGO_AWS_STORAGE_BUCKET_NAME", "DJANGO_SECURE_SSL_REDIRECT", "DJANGO_SENTRY_LOG_LEVEL", "DJANGO_SENTRY_SAMPLE_RATE", "DJANGO_SETTINGS_MODULE", "MYSQL_DATABASE", "MYSQL_HOST", "MYSQL_PORT", "REDIS_URL", "SENTRY_DSN", "VRIFY_CDN_URL", "WEB_CONCURRENCY", "SOCIAL_AUTH_APPLE_ID_CLIENT", "SOCIAL_AUTH_APPLE_ID_AUDIENCE", "WEBAPP_ENDPOINT", "VPEAPP_ENDPOINT", "API_ENDPOINT", "CRONOFY_CLIENT_ID", "ENVIRONMENT", "MIXPANEL_API_KEY", "AMPLITUDE_API_KEY"]');
.mockReturnValueOnce('[ "DJANGO_ACCOUNT_ALLOW_REGISTRATION", "DJANGO_ADMIN_URL", "DJANGO_AWS_REGION_NAME", "DJANGO_AWS_S3_CUSTOM_DOMAIN", "DJANGO_AWS_STORAGE_BUCKET_NAME", "DJANGO_SECURE_SSL_REDIRECT", "DJANGO_SENTRY_LOG_LEVEL", "DJANGO_SENTRY_SAMPLE_RATE", "DJANGO_SETTINGS_MODULE", "MYSQL_DATABASE", "MYSQL_HOST", "MYSQL_PORT", "REDIS_URL", "SENTRY_DSN", "VRIFY_CDN_URL", "WEB_CONCURRENCY", "SOCIAL_AUTH_APPLE_ID_CLIENT", "SOCIAL_AUTH_APPLE_ID_AUDIENCE", "WEBAPP_ENDPOINT", "VPEAPP_ENDPOINT", "API_ENDPOINT", "CRONOFY_CLIENT_ID", "ENVIRONMENT", "MIXPANEL_API_KEY", "AMPLITUDE_API_KEY"]')
.mockReturnValueOnce('nginx:latest') // image
.mockReturnValueOnce('FOO=bar\nHELLO=world'); // environment-variables

process.env = Object.assign(process.env, { GITHUB_WORKSPACE: __dirname });
process.env = Object.assign(process.env, { RUNNER_TEMP: '/home/runner/work/_temp' });
Expand All @@ -41,7 +43,16 @@ describe('Render task definition', () => {
"awslogs-group": "",
},
},
environment: [{name:"RUNNER_TEMP", value: "/home/runner/work/_temp"}]
environment: [
{
name: "FOO",
value: "not bar"
},
{
name: "DONT-TOUCH",
value: "me"
}
]
},
{
name: "sidecar",
Expand Down Expand Up @@ -78,7 +89,20 @@ describe('Render task definition', () => {
"awslogs-group": "log-group",
},
},
environment: [{name:"RUNNER_TEMP", value: "/home/runner/work/_temp"}]
environment: [
{
name: "FOO",
value: "bar"
},
{
name: "DONT-TOUCH",
value: "me"
},
{
name: "HELLO",
value: "world"
}
]
},
{
name: "sidecar",
Expand All @@ -96,15 +120,17 @@ describe('Render task definition', () => {
expect(core.setOutput).toHaveBeenNthCalledWith(1, 'task-definition', 'new-task-def-file-name');
});

test('renders a task definition at an absolute path', async () => {
test('renders a task definition at an absolute path, and with initial environment empty', async () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('/hello/task-definition.json') // task-definition
.mockReturnValueOnce('web') // container-name
.mockReturnValueOnce('nginx:latest')
.mockReturnValueOnce('log-group')
.mockReturnValueOnce('service-family')
.mockReturnValueOnce('["RUNNER_TEMP"]');
.mockReturnValueOnce('["RUNNER_TEMP"]')
.mockReturnValueOnce('nginx:latest') // image
.mockReturnValueOnce('EXAMPLE=here'); // environment-variables
jest.mock('/hello/task-definition.json', () => ({
family: 'task-def-family',
containerDefinitions: [
Expand Down Expand Up @@ -142,7 +168,12 @@ describe('Render task definition', () => {
"awslogs-group": "log-group",
},
},
environment: [{name:"RUNNER_TEMP", value: "/home/runner/work/_temp"}]
environment: [
{
name: "EXAMPLE",
value: "here"
}
]
}
]
}, null, 2)
Expand Down

0 comments on commit 5fba5aa

Please sign in to comment.