Compare commits
6 Commits
v0.261.1-2
...
v0.261.3-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
def1d0a6f2 | ||
|
|
1656206765 | ||
|
|
6cdf1e5788 | ||
|
|
ab381649da | ||
|
|
38e7e9e939 | ||
|
|
2ab806053c |
@@ -46,6 +46,7 @@ type Input struct {
|
||||
artifactServerPort string
|
||||
noCacheServer bool
|
||||
cacheServerPath string
|
||||
cacheServerAdvertiseURL string
|
||||
cacheServerAddr string
|
||||
cacheServerPort uint16
|
||||
jsonLogger bool
|
||||
|
||||
@@ -94,6 +94,7 @@ func Execute(ctx context.Context, version string) {
|
||||
rootCmd.PersistentFlags().BoolVarP(&input.noSkipCheckout, "no-skip-checkout", "", false, "Do not skip actions/checkout")
|
||||
rootCmd.PersistentFlags().BoolVarP(&input.noCacheServer, "no-cache-server", "", false, "Disable cache server")
|
||||
rootCmd.PersistentFlags().StringVarP(&input.cacheServerPath, "cache-server-path", "", filepath.Join(CacheHomeDir, "actcache"), "Defines the path where the cache server stores caches.")
|
||||
rootCmd.PersistentFlags().StringVarP(&input.cacheServerAdvertiseURL, "cache-server-advertise-url", "", "", "Defines the URL for advertising the cache server behind a proxy. e.g.: https://act-cache-server.example.com")
|
||||
rootCmd.PersistentFlags().StringVarP(&input.cacheServerAddr, "cache-server-addr", "", common.GetOutboundIP().String(), "Defines the address to which the cache server binds.")
|
||||
rootCmd.PersistentFlags().Uint16VarP(&input.cacheServerPort, "cache-server-port", "", 0, "Defines the port where the artifact server listens. 0 means a randomly available port.")
|
||||
rootCmd.PersistentFlags().StringVarP(&input.actionCachePath, "action-cache-path", "", filepath.Join(CacheHomeDir, "act"), "Defines the path where the actions get cached and host workspaces created.")
|
||||
@@ -598,7 +599,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||
var cacheHandler *artifactcache.Handler
|
||||
if !input.noCacheServer && envs[cacheURLKey] == "" {
|
||||
var err error
|
||||
cacheHandler, err = artifactcache.StartHandler(input.cacheServerPath, input.cacheServerAddr, input.cacheServerPort, common.Logger(ctx))
|
||||
cacheHandler, err = artifactcache.StartHandler(input.cacheServerPath, input.cacheServerAdvertiseURL, input.cacheServerAddr, input.cacheServerPort, common.Logger(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -39,9 +39,10 @@ type Handler struct {
|
||||
gcAt time.Time
|
||||
|
||||
outboundIP string
|
||||
advertiseURL string
|
||||
}
|
||||
|
||||
func StartHandler(dir, outboundIP string, port uint16, logger logrus.FieldLogger) (*Handler, error) {
|
||||
func StartHandler(dir, advertiseURL, outboundIP string, port uint16, logger logrus.FieldLogger) (*Handler, error) {
|
||||
h := &Handler{}
|
||||
|
||||
if logger == nil {
|
||||
@@ -71,6 +72,8 @@ func StartHandler(dir, outboundIP string, port uint16, logger logrus.FieldLogger
|
||||
}
|
||||
h.storage = storage
|
||||
|
||||
h.advertiseURL = advertiseURL
|
||||
|
||||
if outboundIP != "" {
|
||||
h.outboundIP = outboundIP
|
||||
} else if ip := common.GetOutboundIP(); ip == nil {
|
||||
@@ -111,11 +114,14 @@ func StartHandler(dir, outboundIP string, port uint16, logger logrus.FieldLogger
|
||||
}
|
||||
|
||||
func (h *Handler) ExternalURL() string {
|
||||
// TODO: make the external url configurable if necessary
|
||||
if h.advertiseURL != "" {
|
||||
return h.advertiseURL
|
||||
} else {
|
||||
return fmt.Sprintf("http://%s:%d",
|
||||
h.outboundIP,
|
||||
h.listener.Addr().(*net.TCPAddr).Port)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) Close() error {
|
||||
if h == nil {
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
func TestHandler(t *testing.T) {
|
||||
dir := filepath.Join(t.TempDir(), "artifactcache")
|
||||
handler, err := StartHandler(dir, "", 0, nil)
|
||||
handler, err := StartHandler(dir, "", "", 0, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
base := fmt.Sprintf("%s%s", handler.ExternalURL(), urlBase)
|
||||
@@ -589,7 +589,7 @@ func uploadCacheNormally(t *testing.T, base, key, version string, content []byte
|
||||
|
||||
func TestHandler_gcCache(t *testing.T) {
|
||||
dir := filepath.Join(t.TempDir(), "artifactcache")
|
||||
handler, err := StartHandler(dir, "", 0, nil)
|
||||
handler, err := StartHandler(dir, "", "", 0, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
defer func() {
|
||||
|
||||
@@ -172,10 +172,20 @@ type RunDefaults struct {
|
||||
WorkingDirectory string `yaml:"working-directory,omitempty"`
|
||||
}
|
||||
|
||||
type WorkflowDispatchInput struct {
|
||||
Name string `yaml:"name"`
|
||||
Description string `yaml:"description"`
|
||||
Required bool `yaml:"required"`
|
||||
Default string `yaml:"default"`
|
||||
Type string `yaml:"type"`
|
||||
Options []string `yaml:"options"`
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Name string
|
||||
acts map[string][]string
|
||||
schedules []map[string]string
|
||||
inputs []WorkflowDispatchInput
|
||||
}
|
||||
|
||||
func (evt *Event) IsSchedule() bool {
|
||||
@@ -190,6 +200,47 @@ func (evt *Event) Schedules() []map[string]string {
|
||||
return evt.schedules
|
||||
}
|
||||
|
||||
func (evt *Event) Inputs() []WorkflowDispatchInput {
|
||||
return evt.inputs
|
||||
}
|
||||
|
||||
func parseWorkflowDispatchInputs(inputs map[string]interface{}) ([]WorkflowDispatchInput, error) {
|
||||
var results []WorkflowDispatchInput
|
||||
for name, input := range inputs {
|
||||
inputMap, ok := input.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid input: %v", input)
|
||||
}
|
||||
input := WorkflowDispatchInput{
|
||||
Name: name,
|
||||
}
|
||||
if desc, ok := inputMap["description"].(string); ok {
|
||||
input.Description = desc
|
||||
}
|
||||
if required, ok := inputMap["required"].(bool); ok {
|
||||
input.Required = required
|
||||
}
|
||||
if defaultVal, ok := inputMap["default"].(string); ok {
|
||||
input.Default = defaultVal
|
||||
}
|
||||
if inputType, ok := inputMap["type"].(string); ok {
|
||||
input.Type = inputType
|
||||
}
|
||||
if options, ok := inputMap["options"].([]string); ok {
|
||||
input.Options = options
|
||||
} else if options, ok := inputMap["options"].([]interface{}); ok {
|
||||
for _, option := range options {
|
||||
if opt, ok := option.(string); ok {
|
||||
input.Options = append(input.Options, opt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results = append(results, input)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
|
||||
switch rawOn.Kind {
|
||||
case yaml.ScalarNode:
|
||||
@@ -218,79 +269,119 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
|
||||
}
|
||||
return res, nil
|
||||
case yaml.MappingNode:
|
||||
events, triggers, err := parseMappingNode[interface{}](rawOn)
|
||||
events, triggers, err := parseMappingNode[yaml.Node](rawOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]*Event, 0, len(events))
|
||||
for i, k := range events {
|
||||
v := triggers[i]
|
||||
if v == nil {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
res = append(res, &Event{
|
||||
Name: k,
|
||||
acts: map[string][]string{},
|
||||
})
|
||||
continue
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
res = append(res, &Event{
|
||||
Name: k,
|
||||
acts: map[string][]string{},
|
||||
})
|
||||
case []string:
|
||||
res = append(res, &Event{
|
||||
Name: k,
|
||||
acts: map[string][]string{},
|
||||
})
|
||||
case map[string]interface{}:
|
||||
acts := make(map[string][]string, len(t))
|
||||
for act, branches := range t {
|
||||
switch b := branches.(type) {
|
||||
case string:
|
||||
acts[act] = []string{b}
|
||||
case []string:
|
||||
acts[act] = b
|
||||
case []interface{}:
|
||||
acts[act] = make([]string, len(b))
|
||||
for i, v := range b {
|
||||
var ok bool
|
||||
if acts[act][i], ok = v.(string); !ok {
|
||||
return nil, fmt.Errorf("unknown on type: %#v", branches)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown on type: %#v", branches)
|
||||
}
|
||||
}
|
||||
res = append(res, &Event{
|
||||
Name: k,
|
||||
acts: acts,
|
||||
})
|
||||
case []interface{}:
|
||||
if k != "schedule" {
|
||||
return nil, fmt.Errorf("unknown on type: %#v", v)
|
||||
case yaml.SequenceNode:
|
||||
var t []interface{}
|
||||
err := v.Decode(&t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
schedules := make([]map[string]string, len(t))
|
||||
if k == "schedule" {
|
||||
for i, tt := range t {
|
||||
vv, ok := tt.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown on type: %#v", v)
|
||||
return nil, fmt.Errorf("unknown on type(schedule): %#v", v)
|
||||
}
|
||||
schedules[i] = make(map[string]string, len(vv))
|
||||
for k, vvv := range vv {
|
||||
var ok bool
|
||||
if schedules[i][k], ok = vvv.(string); !ok {
|
||||
return nil, fmt.Errorf("unknown on type: %#v", v)
|
||||
return nil, fmt.Errorf("unknown on type(schedule): %#v", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(schedules) == 0 {
|
||||
schedules = nil
|
||||
}
|
||||
res = append(res, &Event{
|
||||
Name: k,
|
||||
schedules: schedules,
|
||||
})
|
||||
case yaml.MappingNode:
|
||||
acts := make(map[string][]string, len(v.Content)/2)
|
||||
var inputs []WorkflowDispatchInput
|
||||
expectedKey := true
|
||||
var act string
|
||||
for _, content := range v.Content {
|
||||
if expectedKey {
|
||||
if content.Kind != yaml.ScalarNode {
|
||||
return nil, fmt.Errorf("key type not string: %#v", content)
|
||||
}
|
||||
act = ""
|
||||
err := content.Decode(&act)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
switch content.Kind {
|
||||
case yaml.SequenceNode:
|
||||
var t []string
|
||||
err := content.Decode(&t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acts[act] = t
|
||||
case yaml.MappingNode:
|
||||
if k != "workflow_dispatch" || act != "inputs" {
|
||||
return nil, fmt.Errorf("map should only for workflow_dispatch but %s: %#v", act, content)
|
||||
}
|
||||
|
||||
var key string
|
||||
for i, vv := range content.Content {
|
||||
if i%2 == 0 {
|
||||
if vv.Kind != yaml.ScalarNode {
|
||||
return nil, fmt.Errorf("key type not string: %#v", vv)
|
||||
}
|
||||
key = ""
|
||||
if err := vv.Decode(&key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if vv.Kind != yaml.MappingNode {
|
||||
return nil, fmt.Errorf("key type not map(%s): %#v", key, vv)
|
||||
}
|
||||
|
||||
input := WorkflowDispatchInput{}
|
||||
if err := vv.Decode(&input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
input.Name = key
|
||||
inputs = append(inputs, input)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown on type: %#v", v)
|
||||
return nil, fmt.Errorf("unknown on type: %#v", content)
|
||||
}
|
||||
}
|
||||
expectedKey = !expectedKey
|
||||
}
|
||||
if len(inputs) == 0 {
|
||||
inputs = nil
|
||||
}
|
||||
if len(acts) == 0 {
|
||||
acts = nil
|
||||
}
|
||||
res = append(res, &Event{
|
||||
Name: k,
|
||||
acts: acts,
|
||||
inputs: inputs,
|
||||
})
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown on type: %v", v.Kind)
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
|
||||
@@ -186,6 +186,60 @@ func TestParseRawOn(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: `on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
logLevel:
|
||||
description: 'Log level'
|
||||
required: true
|
||||
default: 'warning'
|
||||
type: choice
|
||||
options:
|
||||
- info
|
||||
- warning
|
||||
- debug
|
||||
tags:
|
||||
description: 'Test scenario tags'
|
||||
required: false
|
||||
type: boolean
|
||||
environment:
|
||||
description: 'Environment to run tests against'
|
||||
type: environment
|
||||
required: true
|
||||
push:
|
||||
`,
|
||||
result: []*Event{
|
||||
{
|
||||
Name: "workflow_dispatch",
|
||||
inputs: []WorkflowDispatchInput{
|
||||
{
|
||||
Name: "logLevel",
|
||||
Description: "Log level",
|
||||
Required: true,
|
||||
Default: "warning",
|
||||
Type: "choice",
|
||||
Options: []string{"info", "warning", "debug"},
|
||||
},
|
||||
{
|
||||
Name: "tags",
|
||||
Description: "Test scenario tags",
|
||||
Required: false,
|
||||
Type: "boolean",
|
||||
},
|
||||
{
|
||||
Name: "environment",
|
||||
Description: "Environment to run tests against",
|
||||
Type: "environment",
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "push",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, kase := range kases {
|
||||
t.Run(kase.input, func(t *testing.T) {
|
||||
@@ -230,8 +284,7 @@ func TestParseMappingNode(t *testing.T) {
|
||||
{
|
||||
input: "on:\n push:\n branches:\n - master",
|
||||
scalars: []string{"push"},
|
||||
datas: []interface {
|
||||
}{
|
||||
datas: []interface{}{
|
||||
map[string]interface{}{
|
||||
"branches": []interface{}{"master"},
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
@@ -8,9 +9,10 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/nektos/act/pkg/common"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/nektos/act/pkg/common"
|
||||
)
|
||||
|
||||
// Workflow is the structure of the files in .github/workflows
|
||||
@@ -716,6 +718,12 @@ func (s *Step) Type() StepType {
|
||||
return StepTypeUsesActionRemote
|
||||
}
|
||||
|
||||
// UsesHash returns a hash of the uses string.
|
||||
// For Gitea.
|
||||
func (s *Step) UsesHash() string {
|
||||
return fmt.Sprintf("%x", sha256.Sum256([]byte(s.Uses)))
|
||||
}
|
||||
|
||||
// ReadWorkflow returns a list of jobs for a given workflow file reader
|
||||
func ReadWorkflow(in io.Reader) (*Workflow, error) {
|
||||
w := new(Workflow)
|
||||
|
||||
@@ -603,3 +603,37 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
|
||||
Type: "choice",
|
||||
}, workflowDispatch.Inputs["logLevel"])
|
||||
}
|
||||
|
||||
func TestStep_UsesHash(t *testing.T) {
|
||||
type fields struct {
|
||||
Uses string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "regular",
|
||||
fields: fields{
|
||||
Uses: "https://gitea.com/testa/testb@v3",
|
||||
},
|
||||
want: "ae437878e9f285bd7518c58664f9fabbb12d05feddd7169c01702a2a14322aa8",
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
fields: fields{
|
||||
Uses: "",
|
||||
},
|
||||
want: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := &Step{
|
||||
Uses: tt.fields.Uses,
|
||||
}
|
||||
assert.Equalf(t, tt.want, s.UsesHash(), "UsesHash()")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ func runPreStep(step actionStep) common.Executor {
|
||||
var actionPath string
|
||||
if _, ok := step.(*stepActionRemote); ok {
|
||||
actionPath = newRemoteAction(stepModel.Uses).Path
|
||||
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses))
|
||||
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), stepModel.UsesHash())
|
||||
} else {
|
||||
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
|
||||
actionPath = ""
|
||||
@@ -579,7 +579,7 @@ func runPreStep(step actionStep) common.Executor {
|
||||
var actionPath string
|
||||
if _, ok := step.(*stepActionRemote); ok {
|
||||
actionPath = newRemoteAction(stepModel.Uses).Path
|
||||
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses))
|
||||
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), stepModel.UsesHash())
|
||||
} else {
|
||||
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
|
||||
actionPath = ""
|
||||
@@ -665,7 +665,7 @@ func runPostStep(step actionStep) common.Executor {
|
||||
var actionPath string
|
||||
if _, ok := step.(*stepActionRemote); ok {
|
||||
actionPath = newRemoteAction(stepModel.Uses).Path
|
||||
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses))
|
||||
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), stepModel.UsesHash())
|
||||
} else {
|
||||
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
|
||||
actionPath = ""
|
||||
|
||||
@@ -185,7 +185,8 @@ func setJobResult(ctx context.Context, info jobInfo, rc *RunContext, success boo
|
||||
info.result(jobResult)
|
||||
if rc.caller != nil {
|
||||
// set reusable workflow job result
|
||||
rc.caller.runContext.result(jobResult)
|
||||
rc.caller.setReusedWorkflowJobResult(rc.JobName, jobResult) // For Gitea
|
||||
return
|
||||
}
|
||||
|
||||
jobResultMessage := "succeeded"
|
||||
|
||||
@@ -175,7 +175,11 @@ func newReusableWorkflowExecutor(rc *RunContext, directory string, workflow stri
|
||||
return err
|
||||
}
|
||||
|
||||
return runner.NewPlanExecutor(plan)(ctx)
|
||||
// return runner.NewPlanExecutor(plan)(ctx)
|
||||
return common.NewPipelineExecutor( // For Gitea
|
||||
runner.NewPlanExecutor(plan),
|
||||
setReusedWorkflowCallerResult(rc, runner),
|
||||
)(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +189,8 @@ func NewReusableWorkflowRunner(rc *RunContext) (Runner, error) {
|
||||
eventJSON: rc.EventJSON,
|
||||
caller: &caller{
|
||||
runContext: rc,
|
||||
|
||||
reusedWorkflowJobResults: map[string]string{}, // For Gitea
|
||||
},
|
||||
}
|
||||
|
||||
@@ -269,3 +275,47 @@ func newRemoteReusableWorkflow(uses string) *remoteReusableWorkflow {
|
||||
URL: "https://github.com",
|
||||
}
|
||||
}
|
||||
|
||||
// For Gitea
|
||||
func setReusedWorkflowCallerResult(rc *RunContext, runner Runner) common.Executor {
|
||||
return func(ctx context.Context) error {
|
||||
logger := common.Logger(ctx)
|
||||
|
||||
runnerImpl, ok := runner.(*runnerImpl)
|
||||
if !ok {
|
||||
logger.Warn("Failed to get caller from runner")
|
||||
return nil
|
||||
}
|
||||
caller := runnerImpl.caller
|
||||
|
||||
allJobDone := true
|
||||
hasFailure := false
|
||||
for _, result := range caller.reusedWorkflowJobResults {
|
||||
if result == "pending" {
|
||||
allJobDone = false
|
||||
break
|
||||
}
|
||||
if result == "failure" {
|
||||
hasFailure = true
|
||||
}
|
||||
}
|
||||
|
||||
if allJobDone {
|
||||
reusedWorkflowJobResult := "success"
|
||||
reusedWorkflowJobResultMessage := "succeeded"
|
||||
if hasFailure {
|
||||
reusedWorkflowJobResult = "failure"
|
||||
reusedWorkflowJobResultMessage = "failed"
|
||||
}
|
||||
|
||||
if rc.caller != nil {
|
||||
rc.caller.setReusedWorkflowJobResult(rc.JobName, reusedWorkflowJobResult)
|
||||
} else {
|
||||
rc.result(reusedWorkflowJobResult)
|
||||
logger.WithField("jobResult", reusedWorkflowJobResult).Infof("\U0001F3C1 Job %s", reusedWorkflowJobResultMessage)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,12 @@ func (rc *RunContext) GetEnv() map[string]string {
|
||||
}
|
||||
|
||||
func (rc *RunContext) jobContainerName() string {
|
||||
return createSimpleContainerName(rc.Config.ContainerNamePrefix, "WORKFLOW-"+rc.Run.Workflow.Name, "JOB-"+rc.Name)
|
||||
nameParts := []string{rc.Config.ContainerNamePrefix, "WORKFLOW-" + rc.Run.Workflow.Name, "JOB-" + rc.Name}
|
||||
if rc.caller != nil {
|
||||
nameParts = append(nameParts, "CALLED-BY-"+rc.caller.runContext.JobName)
|
||||
}
|
||||
// return createSimpleContainerName(rc.Config.ContainerNamePrefix, "WORKFLOW-"+rc.Run.Workflow.Name, "JOB-"+rc.Name)
|
||||
return createSimpleContainerName(nameParts...) // For Gitea
|
||||
}
|
||||
|
||||
// Deprecated: use `networkNameForGitea`
|
||||
@@ -653,6 +658,7 @@ func (rc *RunContext) Executor() (common.Executor, error) {
|
||||
return func(ctx context.Context) error {
|
||||
res, err := rc.isEnabled(ctx)
|
||||
if err != nil {
|
||||
rc.caller.setReusedWorkflowJobResult(rc.JobName, "failure") // For Gitea
|
||||
return err
|
||||
}
|
||||
if res {
|
||||
@@ -748,6 +754,10 @@ func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
|
||||
}
|
||||
|
||||
if !runJob {
|
||||
if rc.caller != nil { // For Gitea
|
||||
rc.caller.setReusedWorkflowJobResult(rc.JobName, "skipped")
|
||||
return false, nil
|
||||
}
|
||||
l.WithField("jobResult", "skipped").Debugf("Skipping job '%s' due to '%s'", job.Name, job.If.Value)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
docker_container "github.com/docker/docker/api/types/container"
|
||||
@@ -86,6 +87,9 @@ func (c Config) GetToken() string {
|
||||
|
||||
type caller struct {
|
||||
runContext *RunContext
|
||||
|
||||
updateResultLock sync.Mutex // For Gitea
|
||||
reusedWorkflowJobResults map[string]string // For Gitea
|
||||
}
|
||||
|
||||
type runnerImpl struct {
|
||||
@@ -206,6 +210,9 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
|
||||
if len(rc.String()) > maxJobNameLen {
|
||||
maxJobNameLen = len(rc.String())
|
||||
}
|
||||
if rc.caller != nil { // For Gitea
|
||||
rc.caller.setReusedWorkflowJobResult(rc.JobName, "pending")
|
||||
}
|
||||
stageExecutor = append(stageExecutor, func(ctx context.Context) error {
|
||||
jobName := fmt.Sprintf("%-*s", maxJobNameLen, rc.String())
|
||||
executor, err := rc.Executor()
|
||||
@@ -277,3 +284,10 @@ func (runner *runnerImpl) newRunContext(ctx context.Context, run *model.Run, mat
|
||||
|
||||
return rc
|
||||
}
|
||||
|
||||
// For Gitea
|
||||
func (c *caller) setReusedWorkflowJobResult(jobName string, result string) {
|
||||
c.updateResultLock.Lock()
|
||||
defer c.updateResultLock.Unlock()
|
||||
c.reusedWorkflowJobResults[jobName] = result
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
|
||||
return err
|
||||
}
|
||||
|
||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))
|
||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), sar.Step.UsesHash())
|
||||
gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{
|
||||
URL: sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance),
|
||||
Ref: sar.remoteAction.Ref,
|
||||
@@ -177,7 +177,7 @@ func (sar *stepActionRemote) main() common.Executor {
|
||||
return sar.RunContext.JobContainer.CopyDir(copyToPath, sar.RunContext.Config.Workdir+string(filepath.Separator)+".", sar.RunContext.Config.UseGitIgnore)(ctx)
|
||||
}
|
||||
|
||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))
|
||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), sar.Step.UsesHash())
|
||||
|
||||
return sar.runAction(sar, actionDir, sar.remoteAction)(ctx)
|
||||
}),
|
||||
@@ -236,7 +236,7 @@ func (sar *stepActionRemote) getActionModel() *model.Action {
|
||||
|
||||
func (sar *stepActionRemote) getCompositeRunContext(ctx context.Context) *RunContext {
|
||||
if sar.compositeRunContext == nil {
|
||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))
|
||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), sar.Step.UsesHash())
|
||||
actionLocation := path.Join(actionDir, sar.remoteAction.Path)
|
||||
_, containerActionDir := getContainerActionPaths(sar.getStepModel(), actionLocation, sar.RunContext)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user