1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-08-06 17:40:58 +00:00

Merge remote-tracking branch 'upstream/master' into bump-nektos

This commit is contained in:
techknowlogick 2023-10-11 15:28:38 -04:00
commit b2f90e32b0
9 changed files with 5219 additions and 25 deletions

View file

@ -26,7 +26,7 @@ jobs:
with: with:
version: v1.53 version: v1.53
only-new-issues: true only-new-issues: true
- uses: megalinter/megalinter/flavors/go@v7.3.0 - uses: megalinter/megalinter/flavors/go@v7.4.0
env: env:
DEFAULT_BRANCH: master DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -12,18 +12,19 @@ import (
) )
type EvaluationEnvironment struct { type EvaluationEnvironment struct {
Github *model.GithubContext Github *model.GithubContext
Env map[string]string Env map[string]string
Job *model.JobContext Job *model.JobContext
Jobs *map[string]*model.WorkflowCallResult Jobs *map[string]*model.WorkflowCallResult
Steps map[string]*model.StepResult Steps map[string]*model.StepResult
Runner map[string]interface{} Runner map[string]interface{}
Secrets map[string]string Secrets map[string]string
Vars map[string]string Vars map[string]string
Strategy map[string]interface{} Strategy map[string]interface{}
Matrix map[string]interface{} Matrix map[string]interface{}
Needs map[string]Needs Needs map[string]Needs
Inputs map[string]interface{} Inputs map[string]interface{}
HashFiles func([]reflect.Value) (interface{}, error)
} }
type Needs struct { type Needs struct {
@ -609,6 +610,9 @@ func (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint.FuncCallN
case "fromjson": case "fromjson":
return impl.fromJSON(args[0]) return impl.fromJSON(args[0])
case "hashfiles": case "hashfiles":
if impl.env.HashFiles != nil {
return impl.env.HashFiles(args)
}
return impl.hashFiles(args...) return impl.hashFiles(args...)
case "always": case "always":
return impl.always() return impl.always()

View file

@ -37,6 +37,9 @@ func evaluateCompositeInputAndEnv(ctx context.Context, parent *RunContext, step
env[envKey] = ee.Interpolate(ctx, input.Default) env[envKey] = ee.Interpolate(ctx, input.Default)
} }
} }
gh := step.getGithubContext(ctx)
env["GITHUB_ACTION_REPOSITORY"] = gh.ActionRepository
env["GITHUB_ACTION_REF"] = gh.ActionRef
return env return env
} }
@ -53,11 +56,11 @@ func newCompositeRunContext(ctx context.Context, parent *RunContext, step action
Name: parent.Name, Name: parent.Name,
JobName: parent.JobName, JobName: parent.JobName,
Run: &model.Run{ Run: &model.Run{
JobID: "composite-job", JobID: parent.Run.JobID,
Workflow: &model.Workflow{ Workflow: &model.Workflow{
Name: parent.Run.Workflow.Name, Name: parent.Run.Workflow.Name,
Jobs: map[string]*model.Job{ Jobs: map[string]*model.Job{
"composite-job": {}, parent.Run.JobID: {},
}, },
}, },
}, },

View file

@ -1,12 +1,19 @@
package runner package runner
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"path"
"reflect"
"regexp" "regexp"
"strings" "strings"
"time"
_ "embed"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/container"
"github.com/nektos/act/pkg/exprparser" "github.com/nektos/act/pkg/exprparser"
"github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/model"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@ -75,13 +82,14 @@ func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map
Jobs: &workflowCallResult, Jobs: &workflowCallResult,
// todo: should be unavailable // todo: should be unavailable
// but required to interpolate/evaluate the step outputs on the job // but required to interpolate/evaluate the step outputs on the job
Steps: rc.getStepsContext(), Steps: rc.getStepsContext(),
Secrets: getWorkflowSecrets(ctx, rc), Secrets: getWorkflowSecrets(ctx, rc),
Vars: getWorkflowVars(ctx, rc), Vars: getWorkflowVars(ctx, rc),
Strategy: strategy, Strategy: strategy,
Matrix: rc.Matrix, Matrix: rc.Matrix,
Needs: using, Needs: using,
Inputs: inputs, Inputs: inputs,
HashFiles: getHashFilesFunction(ctx, rc),
} }
if rc.JobContainer != nil { if rc.JobContainer != nil {
ee.Runner = rc.JobContainer.GetRunnerContext(ctx) ee.Runner = rc.JobContainer.GetRunnerContext(ctx)
@ -95,6 +103,9 @@ func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map
} }
} }
//go:embed hashfiles/index.js
var hashfiles string
// NewExpressionEvaluator creates a new evaluator // NewExpressionEvaluator creates a new evaluator
func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step) ExpressionEvaluator { func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step) ExpressionEvaluator {
// todo: cleanup EvaluationEnvironment creation // todo: cleanup EvaluationEnvironment creation
@ -131,7 +142,8 @@ func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step)
Needs: using, Needs: using,
// todo: should be unavailable // todo: should be unavailable
// but required to interpolate/evaluate the inputs in actions/composite // but required to interpolate/evaluate the inputs in actions/composite
Inputs: inputs, Inputs: inputs,
HashFiles: getHashFilesFunction(ctx, rc),
} }
if rc.JobContainer != nil { if rc.JobContainer != nil {
ee.Runner = rc.JobContainer.GetRunnerContext(ctx) ee.Runner = rc.JobContainer.GetRunnerContext(ctx)
@ -145,6 +157,67 @@ func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step)
} }
} }
func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.Value) (interface{}, error) {
hashFiles := func(v []reflect.Value) (interface{}, error) {
if rc.JobContainer != nil {
timeed, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
name := "workflow/hashfiles/index.js"
hout := &bytes.Buffer{}
herr := &bytes.Buffer{}
patterns := []string{}
followSymlink := false
for i, p := range v {
s := p.String()
if i == 0 {
if strings.HasPrefix(s, "--") {
if strings.EqualFold(s, "--follow-symbolic-links") {
followSymlink = true
continue
}
return "", fmt.Errorf("Invalid glob option %s, available option: '--follow-symbolic-links'", s)
}
}
patterns = append(patterns, s)
}
env := map[string]string{}
for k, v := range rc.Env {
env[k] = v
}
env["patterns"] = strings.Join(patterns, "\n")
if followSymlink {
env["followSymbolicLinks"] = "true"
}
stdout, stderr := rc.JobContainer.ReplaceLogWriter(hout, herr)
_ = rc.JobContainer.Copy(rc.JobContainer.GetActPath(), &container.FileEntry{
Name: name,
Mode: 0o644,
Body: hashfiles,
}).
Then(rc.execJobContainer([]string{"node", path.Join(rc.JobContainer.GetActPath(), name)},
env, "", "")).
Finally(func(context.Context) error {
rc.JobContainer.ReplaceLogWriter(stdout, stderr)
return nil
})(timeed)
output := hout.String() + "\n" + herr.String()
guard := "__OUTPUT__"
outstart := strings.Index(output, guard)
if outstart != -1 {
outstart += len(guard)
outend := strings.Index(output[outstart:], guard)
if outend != -1 {
return output[outstart : outstart+outend], nil
}
}
}
return "", nil
}
return hashFiles
}
type expressionEvaluator struct { type expressionEvaluator struct {
interpreter exprparser.Interpreter interpreter exprparser.Interpreter
} }

File diff suppressed because it is too large Load diff

View file

@ -771,6 +771,8 @@ func (rc *RunContext) getGithubContext(ctx context.Context) *model.GithubContext
Token: rc.Config.Token, Token: rc.Config.Token,
Job: rc.Run.JobID, Job: rc.Run.JobID,
ActionPath: rc.ActionPath, ActionPath: rc.ActionPath,
ActionRepository: rc.Env["GITHUB_ACTION_REPOSITORY"],
ActionRef: rc.Env["GITHUB_ACTION_REF"],
RepositoryOwner: rc.Config.Env["GITHUB_REPOSITORY_OWNER"], RepositoryOwner: rc.Config.Env["GITHUB_REPOSITORY_OWNER"],
RetentionDays: rc.Config.Env["GITHUB_RETENTION_DAYS"], RetentionDays: rc.Config.Env["GITHUB_RETENTION_DAYS"],
RunnerPerflog: rc.Config.Env["RUNNER_PERFLOG"], RunnerPerflog: rc.Config.Env["RUNNER_PERFLOG"],

View file

@ -237,6 +237,7 @@ func TestRunEvent(t *testing.T) {
{workdir, "uses-composite-with-error", "push", "Job 'failing-composite-action' failed", platforms, secrets}, {workdir, "uses-composite-with-error", "push", "Job 'failing-composite-action' failed", platforms, secrets},
{workdir, "uses-nested-composite", "push", "", platforms, secrets}, {workdir, "uses-nested-composite", "push", "", platforms, secrets},
{workdir, "remote-action-composite-js-pre-with-defaults", "push", "", platforms, secrets}, {workdir, "remote-action-composite-js-pre-with-defaults", "push", "", platforms, secrets},
{workdir, "remote-action-composite-action-ref", "push", "", platforms, secrets},
{workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}}, {workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}},
{workdir, "uses-workflow", "pull_request", "", platforms, map[string]string{"secret": "keep_it_private"}}, {workdir, "uses-workflow", "pull_request", "", platforms, map[string]string{"secret": "keep_it_private"}},
{workdir, "uses-docker-url", "push", "", platforms, secrets}, {workdir, "uses-docker-url", "push", "", platforms, secrets},

View file

@ -0,0 +1,8 @@
name: remote-action-composite-action-ref
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: nektos/act-test-actions/composite-assert-action-ref-action@main

View file

@ -658,7 +658,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
func defaultImageSurvey(actrc string) error { func defaultImageSurvey(actrc string) error {
var answer string var answer string
confirmation := &survey.Select{ confirmation := &survey.Select{
Message: "Please choose the default image you want to use with act:\n\n - Large size image: +20GB Docker image, includes almost all tools used on GitHub Actions (IMPORTANT: currently only ubuntu-18.04 platform is available)\n - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with all actions\n - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\n\nDefault image and other options can be changed manually in ~/.actrc (please refer to https://github.com/nektos/act#configuration for additional information about file structure)", Message: "Please choose the default image you want to use with act:\n - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images\n - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions\n - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\n\nDefault image and other options can be changed manually in ~/.actrc (please refer to https://github.com/nektos/act#configuration for additional information about file structure)",
Help: "If you want to know why act asks you that, please go to https://github.com/nektos/act/issues/107", Help: "If you want to know why act asks you that, please go to https://github.com/nektos/act/issues/107",
Default: "Medium", Default: "Medium",
Options: []string{"Large", "Medium", "Micro"}, Options: []string{"Large", "Medium", "Micro"},
@ -672,7 +672,7 @@ func defaultImageSurvey(actrc string) error {
var option string var option string
switch answer { switch answer {
case "Large": case "Large":
option = "-P ubuntu-latest=catthehacker/ubuntu:full-latest\n-P ubuntu-latest=catthehacker/ubuntu:full-20.04\n-P ubuntu-18.04=catthehacker/ubuntu:full-18.04\n" option = "-P ubuntu-latest=catthehacker/ubuntu:full-latest\n-P ubuntu-22.04=catthehacker/ubuntu:full-22.04\n-P ubuntu-20.04=catthehacker/ubuntu:full-20.04\n-P ubuntu-18.04=catthehacker/ubuntu:full-18.04\n"
case "Medium": case "Medium":
option = "-P ubuntu-latest=catthehacker/ubuntu:act-latest\n-P ubuntu-22.04=catthehacker/ubuntu:act-22.04\n-P ubuntu-20.04=catthehacker/ubuntu:act-20.04\n-P ubuntu-18.04=catthehacker/ubuntu:act-18.04\n" option = "-P ubuntu-latest=catthehacker/ubuntu:act-latest\n-P ubuntu-22.04=catthehacker/ubuntu:act-22.04\n-P ubuntu-20.04=catthehacker/ubuntu:act-20.04\n-P ubuntu-18.04=catthehacker/ubuntu:act-18.04\n"
case "Micro": case "Micro":