diff --git a/src/utils/expression.ts b/src/utils/expression.ts index 2e5900b..8328f86 100644 --- a/src/utils/expression.ts +++ b/src/utils/expression.ts @@ -286,7 +286,7 @@ function canEvaluateExpression( } if (expr instanceof IndexAccess) { return ( - hasValueForIndexAccess(expr, values) || + hasStaticValueForIndexAccess(expr, values) || (canEvaluateExpression(expr.expr, values) && canEvaluateExpression(expr.index, values)) ) @@ -400,9 +400,28 @@ function replacementForIndexAccess( expr: IndexAccess, values: Record, ): string | undefined { - return hasValueForIndexAccess(expr, values) - ? valueLiteral(valueForIndexAccess(expr, values)) - : undefined + if (!hasValueForIndexAccess(expr, values)) { + return undefined + } + const value = valueForIndexAccess(expr, values) + if (typeof value === 'string') { + const body = expressionBody(value.trim()) + if (body !== undefined) { + return `(${body})` + } + } + return valueLiteral(value) +} + +function hasStaticValueForIndexAccess( + expr: IndexAccess, + values: Record, +): boolean { + if (!hasValueForIndexAccess(expr, values)) { + return false + } + const value = valueForIndexAccess(expr, values) + return typeof value !== 'string' || expressionBody(value.trim()) === undefined } function printIndexAccess( diff --git a/tests/index.test.ts b/tests/index.test.ts index 2a16fe8..f0f4082 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -55,6 +55,9 @@ class TestOutput { describe('actionspack', () => { it('simplifies static format calls inside expressions', () => { + const releaseTag = + "${{ contains(github.ref_name, 'alpha') && 'alpha' || contains(github.ref_name, 'beta') && 'beta' || contains(github.ref_name, 'rc') && 'rc' || '' }}" + expect( substituteString( '${{ fromJson(format(\'[{0}]\', \'"ubuntu-latest", "windows-latest"\')) }}', @@ -73,6 +76,21 @@ describe('actionspack', () => { {}, ), ).toEqual({ run: 'pnpm install' }) + expect( + substituteValue( + { + tag: releaseTag, + }, + {}, + ), + ).toEqual({ tag: releaseTag }) + expect( + substituteString("${{ inputs.tag || 'latest' }}", { + 'inputs.tag': releaseTag, + }), + ).toBe( + "${{ (contains(github.ref_name, 'alpha') && 'alpha' || contains(github.ref_name, 'beta') && 'beta' || contains(github.ref_name, 'rc') && 'rc' || '') || 'latest' }}", + ) }) it('reports when pack has no source workflows', async () => {