Skip to content

Commit

Permalink
feat: added working-directory input support
Browse files Browse the repository at this point in the history
  • Loading branch information
natterstefan committed Oct 21, 2022
1 parent 02bca7e commit c3a1d20
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 19 deletions.
9 changes: 6 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ module.exports = {
sourceType: 'module',
project: './tsconfig.eslintrc.json'
},
/**
* based on default rules from https://github.com/actions/typescript-action
*/
rules: {
/* custom rules */
'import/extensions': 'off',

/**
* based on default rules from https://github.com/actions/typescript-action
*/
'i18n-text/no-en': 'off',
'eslint-comments/no-use': 'off',
'import/no-namespace': 'off',
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,31 @@
## Usage

```text
# .env file
HELLO="WORLD"
```

```yaml
- name: Load .env file
uses: natterstefan/action-next-env@v1
with:
path: custom/path/to/folder/with/env # optional, default: .
environment: development

- name: Some other action
run: |
echo "HELLO Variable: ${{ env.HELLO }}"
```

or when using the action in a monorepo setup (but also applicable in other
cases):

```yaml
- name: Load .env file
uses: natterstefan/action-next-env@v1
with:
working-directory: 'packages/app'
path: custom/path/to/folder/with/env # optional, default: .
environment: development

Expand Down
47 changes: 47 additions & 0 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,38 @@ import * as process from 'process'
import * as cp from 'child_process'
import * as path from 'path'

import * as core from '@actions/core'

import {Input} from '../src/types'

let mockInput: Partial<Input> = {}

jest.mock('@actions/core', () => ({
...jest.requireActual('@actions/core'),
getInput: jest.fn((name: keyof Input, options?: core.InputOptions) => {
const input = mockInput[name]

if (!input && options && options.required) {
throw new Error(`Input missing: ${name}`)
}

return input
})
}))

const mockJoin = jest.fn((...args) => jest.requireActual('path').join(...args))
jest.mock('path', () => ({
join: (...args: string[]) => mockJoin(...args)
}))

describe('action-next-env', () => {
beforeEach(() => {
mockInput = {}
mockJoin.mockClear()
// because we use require() in some cases
jest.resetModules()
})

// shows how the runner will run a javascript action with env / stdout protocol
// eslint-disable-next-line jest/expect-expect
it('runs', () => {
Expand Down Expand Up @@ -35,4 +66,20 @@ describe('action-next-env', () => {

expect(process.env.HELLO).toBe('MOON')
})

it('does work with custom inputs', () => {
mockInput = {
'working-directory': 'custom-directory',
path: 'path-to-env-file'
}

// eslint-disable-next-line global-require, @typescript-eslint/no-require-imports
require('../src/main.ts')

expect(mockJoin).toHaveBeenNthCalledWith(
1,
'custom-directory',
'path-to-env-file'
)
})
})
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ branding:
icon: 'sliders'
color: 'green'
inputs:
working-directory:
description: 'the current working directory for the shell running the commands'
required: false
environment:
required: true
description: 'Define which environment you want to load: development, test or production.'
Expand Down
18 changes: 12 additions & 6 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"@semantic-release/release-notes-generator": "^10.0.3",
"@types/jest": "^28.1.8",
"@types/node": "^16.11.66",
"@types/semantic-release": "^17.2.4",
"@typescript-eslint/parser": "^5.40.1",
"@vercel/ncc": "^0.34.0",
"all-contributors-cli": "^6.24.0",
Expand Down
5 changes: 5 additions & 0 deletions release.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// ts-check

/* eslint-disable import/no-commonjs */
/**
* @type {import('semantic-release').Options}
*/
module.exports = {
branches: ['main'],
preset: 'conventionalcommits',
Expand Down
27 changes: 18 additions & 9 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,29 @@ import * as core from '@actions/core'
import {parse} from 'dotenv'
import {loadEnvConfig} from '@next/env'

type Environment = 'test' | 'production' | 'development'
type Input = {environment: Environment; pathToEnv: string}
import {Environment, InputValues} from './types'

const getInput = (): Input => {
const getInput = (): InputValues => {
const environment = core.getInput('environment') as Environment
const pathToEnv = core.getInput('path') || '.'
const workingDirectory = core.getInput('working-directory') || process.cwd()

return {
environment,
pathToEnv
pathToEnv,
workingDirectory
}
}

const loadEnvVariables = (
mode: Environment,
environment: Environment,
workingDirectory: string,
pathToEnv: string
): Record<string, string | undefined> => {
const isDevelopment = mode !== 'production'
const isDevelopment = environment !== 'production'
const envPath = path.join(workingDirectory, pathToEnv)

const nextEnvResult = loadEnvConfig(path.join(pathToEnv), isDevelopment, {
const nextEnvResult = loadEnvConfig(envPath, isDevelopment, {
info: core.info,
error: core.error
})
Expand Down Expand Up @@ -58,19 +61,25 @@ const exportEnvVariables = (env: Record<string, string | undefined>): void => {
}

async function run(): Promise<void> {
core.debug(`Starting ...`)
try {
const {environment, pathToEnv} = getInput()
core.debug(`Reading input ...`)
const {environment, pathToEnv, workingDirectory} = getInput()

// debug is only output if you set the secret `ACTIONS_STEP_DEBUG` to true
core.debug(`Reading environment ...`)
exportEnvVariables(loadEnvVariables(environment, pathToEnv))
exportEnvVariables(
loadEnvVariables(environment, workingDirectory, pathToEnv)
)
core.debug(`Read environment and set secrets ...`)

// sets the step's output parameter.
core.setOutput('loadedEnv', true)
} catch (error) {
if (error instanceof Error) core.setFailed(error.message)
}

core.debug(`Ended ...`)
}

run()
16 changes: 16 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @default 'development'
*/
export type Environment = 'test' | 'production' | 'development'

export type Input = {
environment: Environment
path: string
'working-directory': string
}

export type InputValues = {
environment: Environment
pathToEnv: string
workingDirectory: string
}

0 comments on commit c3a1d20

Please sign in to comment.