1
0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2026-10-24 16:59:19 +03:00
Files
runner/act/exprparser/rewrite_sub_expr_test.go
Mathieu Fenniak ca76b4ce12 feat(jobparser): allow access to the outputs of a reusable workflow (#1216)
Reusable workflow expansion is a capability that will allow Forgejo to schedule every job of a reusable workflow as a separate job, allowing the use of multiple runners and clear independent logging.  This is a multi-PR implementation effort, project work tracking link: https://codeberg.org/forgejo/forgejo/issues/9768#issuecomment-8828016

This PR extends reusable workflow expansion to support accessing the outputs of a reusable workflow.  Four changes are involved:
- Centralizing a duplicated `rewriteSubExpression` function between the jobparser and the runner.
- Creating an expression mutator which allows for transformations of expressions by their abstract syntax tree.
- Transforming the outputs in `on.workflow_call.outputs`, which are in the form of `jobs.some-job.outputs`, into `needs[format("{0}.{1}", parent-job-id, job-id)].outputs....` on the parent job.  This moves evaluation of the outputs into the placeholder job that was previously created in #1215 to support dependencies between jobs.
- Addition of a utility function `EvaluateWorkflowCallOutputs` which Forgejo can use to evaluate the outputs, as the placeholder job is never sent to a runner to be executed.
- Corrected an earlier persistent misuse of "callee" to refer to "caller".

In addition to test automation present here, this change has been manually tested on an [experimental Forgejo branch](https://codeberg.org/mfenniak/forgejo/pulls/3).

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- features
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1216): <!--number 1216 --><!--line 0 --><!--description ZmVhdChqb2JwYXJzZXIpOiBhbGxvdyBhY2Nlc3MgdG8gdGhlIG91dHB1dHMgb2YgYSByZXVzYWJsZSB3b3JrZmxvdw==-->feat(jobparser): allow access to the outputs of a reusable workflow<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1216
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-12-13 14:27:51 +00:00

56 lines
1.7 KiB
Go

package exprparser
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestExpressionRewriteSubExpression(t *testing.T) {
table := []struct {
in string
out string
}{
{in: "Hello World", out: "Hello World"},
{in: "${{ true }}", out: "${{ true }}"},
{in: "${{ true }} ${{ true }}", out: "format('{0} {1}', true, true)"},
{in: "${{ true || false }} ${{ true && true }}", out: "format('{0} {1}', true || false, true && true)"},
{in: "${{ '}}' }}", out: "${{ '}}' }}"},
{in: "${{ '''}}''' }}", out: "${{ '''}}''' }}"},
{in: "${{ '''' }}", out: "${{ '''' }}"},
{in: `${{ fromJSON('"}}"') }}`, out: `${{ fromJSON('"}}"') }}`},
{in: `${{ fromJSON('"\"}}\""') }}`, out: `${{ fromJSON('"\"}}\""') }}`},
{in: `${{ fromJSON('"''}}"') }}`, out: `${{ fromJSON('"''}}"') }}`},
{in: "Hello ${{ 'World' }}", out: "format('Hello {0}', 'World')"},
}
for _, table := range table {
t.Run("TestRewriteSubExpression", func(t *testing.T) {
assertObject := assert.New(t)
out := RewriteSubExpression(table.in, false)
assertObject.Equal(table.out, out, table.in)
})
}
}
func TestExpressionRewriteSubExpressionForceFormat(t *testing.T) {
table := []struct {
in string
out string
}{
{in: "Hello World", out: "Hello World"},
{in: "${{ true }}", out: "format('{0}', true)"},
{in: "${{ '}}' }}", out: "format('{0}', '}}')"},
{in: `${{ fromJSON('"}}"') }}`, out: `format('{0}', fromJSON('"}}"'))`},
{in: "Hello ${{ 'World' }}", out: "format('Hello {0}', 'World')"},
}
for _, table := range table {
t.Run("TestRewriteSubExpressionForceFormat", func(t *testing.T) {
assertObject := assert.New(t)
out := RewriteSubExpression(table.in, true)
assertObject.Equal(table.out, out, table.in)
})
}
}