Skip to content

Commit 2a002da

Browse files
authored
Include environment vars (#15)
* Include environemnt vars * Add workflow test * Fix workflow test * Add include_env_vars
1 parent 4279823 commit 2a002da

File tree

4 files changed

+88
-19
lines changed

4 files changed

+88
-19
lines changed

.github/workflows/test.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,21 @@ jobs:
6969
full_text: TEST=1
7070
- run: cat .env
7171
- run: grep -zP "^TEST=1$" .env
72+
test-including-env-vars:
73+
runs-on: ubuntu-latest
74+
needs:
75+
- build
76+
steps:
77+
- uses: actions/checkout@v2
78+
- uses: actions/download-artifact@v2
79+
with:
80+
name: dist
81+
path: dist
82+
- uses: ./
83+
with:
84+
full_text: PROD=0
85+
include_env_vars: true
86+
env:
87+
ACTION_CREATE_ENV_TEST: 1
88+
- run: cat .env
89+
- run: grep -zP "^PROD=0\nTEST=1$" .env

__tests__/main.test.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,41 @@
1-
import { Args, writeEnv } from '../src/main'
1+
import { Args, writeToEnvFile } from '../src/main'
22
import * as process from 'process'
33
import * as cp from 'child_process'
44
import * as path from 'path'
55
import * as fs from 'fs'
66

77
const ARTIFACTS_PATH = path.join(__dirname, 'artifacts')
8+
const ENV_PREFIX = 'ACTION_CREATE_ENV_'
89

910
beforeEach(() => fs.mkdirSync(ARTIFACTS_PATH))
1011
afterEach(() => fs.rmSync(ARTIFACTS_PATH, { recursive: true, force: true }))
12+
afterEach(() => {
13+
Object.keys(process.env)
14+
.filter(key => key.startsWith(ENV_PREFIX))
15+
.forEach(key => {
16+
delete process.env[key]
17+
})
18+
})
1119

1220
test('throws if <directory> is not found', async () => {
1321
const args: Args = {
1422
directory: `${ARTIFACTS_PATH}/this_dir_does_not_exist`,
15-
full_text: ''
23+
full_text: '',
24+
include_env_vars: false
1625
}
17-
await expect(writeEnv(args))
26+
await expect(writeToEnvFile(args))
1827
.rejects
1928
.toThrow(`Invalid directory input: ${args.directory} doesn't exist.`)
2029
})
2130

2231
test('throws if <directory> is not a directory', async () => {
2332
const args: Args = {
2433
directory: `${ARTIFACTS_PATH}/file`,
25-
full_text: ''
34+
full_text: '',
35+
include_env_vars: false
2636
}
2737
fs.writeFileSync(args.directory, '')
28-
await expect(writeEnv(args))
38+
await expect(writeToEnvFile(args))
2939
.rejects
3040
.toThrow(`Invalid directory input: ${args.directory} is not a directory.`)
3141
})
@@ -36,9 +46,10 @@ test('creates .env', async () => {
3646
full_text: `
3747
PROD=0
3848
TEST=1\n
39-
`
49+
`,
50+
include_env_vars: false
4051
}
41-
await writeEnv(args)
52+
await writeToEnvFile(args)
4253
const content = fs.readFileSync(`${args.directory}/.env`).toString()
4354
expect(content).toEqual('PROD=0\nTEST=1')
4455
})
@@ -52,15 +63,28 @@ test('overwrites .env', async () => {
5263
directory: ARTIFACTS_PATH,
5364
full_text: `
5465
PROD=0
55-
`
66+
`,
67+
include_env_vars: false
5668
}
5769
const filePath = `${args.directory}/.env`
5870
fs.writeFileSync(filePath, initialText)
59-
await writeEnv(args)
71+
await writeToEnvFile(args)
6072
const content = fs.readFileSync(filePath).toString()
6173
expect(content).toEqual('PROD=0')
6274
})
6375

76+
test('includes env vars', async () => {
77+
const args: Args = {
78+
directory: ARTIFACTS_PATH,
79+
full_text: 'PROD=0\n', // should be trimmed
80+
include_env_vars: true
81+
}
82+
process.env[`${ENV_PREFIX}_${ENV_PREFIX}_TEST`] = '1' // prefix should only be removed once
83+
await writeToEnvFile(args)
84+
const content = fs.readFileSync(`${args.directory}/.env`).toString()
85+
expect(content).toEqual(`PROD=0\n_${ENV_PREFIX}_TEST=1`)
86+
})
87+
6488
// shows how the runner will run a javascript action with env / stdout protocol
6589
test('test runs', () => {
6690
process.env['INPUT_FULL_TEXT'] = 'PROD=0'

action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ inputs:
88
directory:
99
description: 'Directory to write the file to (defaults to .). Parent directories will NOT be created.'
1010
default: '.'
11+
include_env_vars:
12+
required: false
13+
description: |
14+
If set, environemnt vars starting with ACTION_CREATE_ENV_ will be included (i.e. ACTION_CREATE_ENV_PROD=1 will be incldued in .env as PROD=1).
15+
Vars set in this way are written after <full_text>.
1116
runs:
1217
using: 'node12'
1318
main: 'dist/index.js'

src/main.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,42 @@ import { getInput, info, setFailed } from '@actions/core'
22
import dedent from 'dedent'
33
import * as fs from 'fs'
44

5+
const ENV_PREFIX = 'ACTION_CREATE_ENV_'
6+
57
export interface Args {
68
full_text: string
79
directory: string
10+
include_env_vars: boolean
11+
}
12+
13+
function getTextForEnvFile(args: Args) {
14+
let text = dedent(args.full_text).trim()
15+
if (args.include_env_vars) {
16+
const envVars = Object.entries(process.env)
17+
.filter(([key]) => key.startsWith(ENV_PREFIX))
18+
.map(([key, val]) => {
19+
const newKey = key.replace(new RegExp(`^${ENV_PREFIX}`), '')
20+
return `${newKey}=${val}`
21+
})
22+
text += `\n${envVars.join('\n')}`
23+
}
24+
return text.trim()
25+
}
26+
27+
function validateArgs(args: Args) {
28+
if (!fs.existsSync(args.directory)) {
29+
throw new Error(`Invalid directory input: ${args.directory} doesn't exist.`)
30+
}
31+
if (!fs.statSync(args.directory).isDirectory()) {
32+
throw new Error(`Invalid directory input: ${args.directory} is not a directory.`)
33+
}
834
}
935

10-
export async function writeEnv(args: Args): Promise<void> {
36+
export async function writeToEnvFile(args: Args): Promise<void> {
1137
return new Promise<void>((resolve, reject) => {
12-
if (!fs.existsSync(args.directory)) {
13-
throw new Error(`Invalid directory input: ${args.directory} doesn't exist.`)
14-
}
15-
if (!fs.statSync(args.directory).isDirectory()) {
16-
throw new Error(`Invalid directory input: ${args.directory} is not a directory.`)
17-
}
38+
validateArgs(args)
1839
const filePath = `${args.directory}/.env`
19-
const text = dedent(args.full_text).trim()
40+
const text = getTextForEnvFile(args)
2041
fs.writeFile(filePath, text, err => {
2142
if (err) return reject(err)
2243
resolve()
@@ -28,10 +49,11 @@ export async function run(): Promise<void> {
2849
try {
2950
const args: Args = {
3051
full_text: getInput('full_text'),
31-
directory: getInput('directory')
52+
directory: getInput('directory'),
53+
include_env_vars: !!getInput('include_env_vars')
3254
}
3355
info(`Creating .env file in ${args.directory}`)
34-
await writeEnv(args)
56+
await writeToEnvFile(args)
3557
info('Done.')
3658
} catch (error) {
3759
setFailed(error.message)

0 commit comments

Comments
 (0)