gitea icon indicating copy to clipboard operation
gitea copied to clipboard

Actions support workflow dispatch event

Open pangliang opened this issue 1 year ago • 16 comments

related #23668

My plan:

  • In the actions.list method, if workflow is selected and IsAdmin, check whether the on event contains workflow_dispatch. If so, display a Run workflow button to allow the user to manually trigger the run.
  • Providing a form that allows users to select target brach or tag, and these parameters can be configured in yaml
  • Simple form validation, required input cannot be empty
  • Add a route /actions/run, and an actions.Run method to handle
  • Add WorkflowDispatchPayload struct to pass the Webhook event payload to the runner when triggered, this payload carries the inputs values and other fields, doc: workflow_dispatch payload

Other PRs

  • the Workflow.WorkflowDispatchConfig() method still return non-nil when workflow_dispatch is not defined. I submitted a PR https://gitea.com/gitea/act/pulls/85 to fix it. Still waiting for them to process.

Behavior should be same with github, but may cause confusion. Here's a quick reminder.

  • Doc Said: This event will only trigger a workflow run if the workflow file is on the default branch.
    • If the workflow yaml file only exists in a non-default branch, it cannot be triggered. (It will not even show up in the workflow list)
    • If the same workflow yaml file exists in each branch at the same time, the version of the default branch is used. Even if Use workflow from selects another branch

image

name: Docker Image CI

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
      boolean_default_true:
        description: 'Test scenario tags'
        required: true
        type: boolean
        default: true
      boolean_default_false:
        description: 'Test scenario tags'
        required: false
        type: boolean
        default: false
      environment:
        description: 'Environment to run tests against'
        type: environment
        required: true
        default: 'environment values'
      number_required_1:
        description: 'number '
        type: number
        required: true
        default: '100'
      number_required_2:
        description: 'number'
        type: number
        required: true
        default: '100'
      number_required_3:
        description: 'number'
        type: number
        required: true
        default: '100'
      number_1:
        description: 'number'
        type: number
        required: false
      number_2:
        description: 'number'
        type: number
        required: false
      number_3:
        description: 'number'
        type: number
        required: false

env:
  inputs_logLevel:              ${{ inputs.logLevel }}
  inputs_tags:                  ${{ inputs.tags }}
  inputs_boolean_default_true:  ${{ inputs.boolean_default_true }}
  inputs_boolean_default_false: ${{ inputs.boolean_default_false }}
  inputs_environment:           ${{ inputs.environment }}
  inputs_number_1:              ${{ inputs.number_1  }}
  inputs_number_2:              ${{ inputs.number_2  }}
  inputs_number_3:              ${{ inputs.number_3  }}
  inputs_number_required_1:     ${{ inputs.number_required_1  }}
  inputs_number_required_2:     ${{ inputs.number_required_2  }}
  inputs_number_required_3:     ${{ inputs.number_required_3  }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: ls -la
      - run: env | grep inputs
      - run: echo ${{ inputs.logLevel }}
      - run: echo ${{ inputs.boolean_default_false }}

image image

pangliang avatar Nov 22 '23 03:11 pangliang

Well, the problem is, you can specify some user-supplied fields for workflow_dispatch, have you handled that case as well?

wizpresso-steve-cy-fan avatar Nov 23 '23 04:11 wizpresso-steve-cy-fan

Well, the problem is, you can specify some user-supplied fields for workflow_dispatch, have you handled that case as well?

I plan to implement a version similar to github, providing a form that allows users to fill in the env parameters of the workflow run, and these parameters can be configured in yaml. Hopefully I can complete it

pangliang avatar Nov 23 '23 06:11 pangliang

https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch image Should we also follow this note?

yp05327 avatar Nov 30 '23 00:11 yp05327

In the actions.list method, if workflow is selected and IsAdmin, check whether the on event contains workflow_dispatch. If so, display a Run workflow button to allow the user to manually trigger the run.

IMO, this notification takes too many spaces, and we don't need to always display it at there? How about put it into the dropdown menu? image

Not a block, feel free to discus.

yp05327 avatar Nov 30 '23 00:11 yp05327

https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch image Should we also follow this note?

I think it should be following now.

  • When list workflow, DefaultBranch is used
  • When running workflow_dispatch workflow, the target ref is selected and specified, but the workflow configuration still uses DefaultBranch

pangliang avatar Dec 05 '23 05:12 pangliang

In the actions.list method, if workflow is selected and IsAdmin, check whether the on event contains workflow_dispatch. If so, display a Run workflow button to allow the user to manually trigger the run.

IMO, this notification takes too many spaces, and we don't need to always display it at there? How about put it into the dropdown menu? image

Not a block, feel free to discus.

At first I also tried to put it in the dropdown menu, but there was a confusing problem. When no child elements exist, the dropdown menu will not hide automatically. Then it is more difficult to deal with when to display the button

if a or b or c or .... then
   <dropdown>
          if a then
              <menu a>
          end
          if b then
              <menu b>
          end
          ...
   </dropdown>
end

I don't know, I feel a little OCD here

Maybe I'm using it the wrong way, so I copied the design from github If you have a good solution please tell me, Or I can put it in dropdown. After all, there are only two if conditions now.

pangliang avatar Dec 05 '23 05:12 pangliang

image It is a required input, but it is empty.

yp05327 avatar Dec 07 '23 04:12 yp05327

  • environment: gitea doesn't support the environment feature yet, right? Maybe act_runner uses environment as a keyword, so it can't get the value of inputs.environment

gitea doesn't support the environment feature yet, right? Maybe act_runner uses environment as a keyword, so it can't get the value of inputs.environment

If I set a default value, it works. Maybe it is caused by something else. image image

And if I change the default value, it will still be the default value. So it seems that it will only display the default value, but not the value in the form.

yp05327 avatar Dec 07 '23 05:12 yp05327

  • environment: gitea doesn't support the environment feature yet, right? Maybe act_runner uses environment as a keyword, so it can't get the value of inputs.environment

gitea doesn't support the environment feature yet, right? Maybe act_runner uses environment as a keyword, so it can't get the value of inputs.environment

If I set a default value, it works. Maybe it is caused by something else. image image

And if I change the default value, it will still be the default value. So it seems that it will only display the default value, but not the value in the form.

I re-looked at the code and github documentation

On the runner side:

On the gitea side:

  • Use ActionRun.EventPayload to pass payload to runner
  • There are already some payloads, such as PushPayload, Follow the documentation workflow_dispatch payload Created a WorkflowDispatchPayload struct
  • ctx.Req.PostForm -> WorkflowDispatchPayload.Inputs -> ActionRun.EventPayload -> ghc.Event, it works correctly

pangliang avatar Dec 07 '23 12:12 pangliang

maybe we can also remove this in this PR

yp05327 avatar Dec 11 '23 08:12 yp05327

new pull requests: Fix workflow dispatch ui

TKaxv-7S avatar Dec 11 '23 13:12 TKaxv-7S

Ok, I didn't notice before that WorkflowDispatchConfig comes from nektos/act, now these steps are needed:

  • [x] Submit a PR to nektos/act: https://github.com/nektos/act/pull/2123
  • [x] Submit a PR to gitea/act and let them merge nektos/act
  • [x] Modify the reference of my PR to the new gitea/act version

pangliang avatar Dec 12 '23 06:12 pangliang

new pull requests: Fix workflow dispatch input items order

TKaxv-7S avatar Dec 17 '23 14:12 TKaxv-7S

@yp05327 Let’s discuss this. Workflow_Dispatch.Inputs in nektos/act is not suitable for use in views. Then we might as well write another structure and parsing method on the gitea side without depend nektos/act. What is your opinion?

If you think it's okay, I think i can roll back the modific package link github.com/nektos/act and move forward without waiting nektos/act#2123

type WorkflowDispatchInput struct {
	Name        string                                     //  add name
	Description string   `yaml:"description"`
	Required    bool     `yaml:"required"`
	Default     string   `yaml:"default"`
	Type        string   `yaml:"type"`
	Options     []string `yaml:"options"`
}

type WorkflowDispatch struct {
	Inputs []WorkflowDispatchInput            //slice, not map,  for keep ordered
}

func workflowDispatchConfig(w *model.Workflow) *WorkflowDispatch {
        switch w.RawOn.Kind {
	case yaml.ScalarNode:
		var val string
		if !decodeNode(w.RawOn, &val) {
			return nil
		}
		if val == "workflow_dispatch" {
			return &WorkflowDispatch{}
		}
	case yaml.SequenceNode:
		var val []string
		if !decodeNode(w.RawOn, &val) {
			return nil
		}
		for _, v := range val {
			if v == "workflow_dispatch" {
				return &WorkflowDispatch{}
			}
		}
	case yaml.MappingNode:
		var val map[string]yaml.Node
		if !decodeNode(w.RawOn, &val) {
			return nil
		}

		workflowDispatchNode, found := val["workflow_dispatch"]
		if !found {
			return nil
		}

		var workflowDispatchVal map[string]yaml.Node
		if !decodeNode(workflowDispatchNode, &workflowDispatchVal) {
			return nil
		}

		var workflowDispatch WorkflowDispatch
		inputsNode, found := workflowDispatchVal["inputs"]
		if found {
			i := 0
			for {
				if i+1 >= len(inputsNode.Content) {
					break
				}
				var input WorkflowDispatchInput
				if decodeNode(*inputsNode.Content[i+1], &input) {
					input.Name = inputsNode.Content[i].Value
					workflowDispatch.Inputs = append(workflowDispatch.Inputs, input)
				}
				i += 2
			}
		}
		return &workflowDispatch

	default:
		return nil
	}
	return nil
}

pangliang avatar Dec 18 '23 03:12 pangliang

@yp05327 Let’s discuss this. Workflow_Dispatch.Inputs in nektos/act is not suitable for use in views. Then we might as well write another structure and parsing method on the gitea side without depend nektos/act. What is your opinion?

If you think it's okay, I think i can roll back the modific package link github.com/nektos/act and move forward without waiting nektos/act#2123

type WorkflowDispatchInput struct {
	Name        string                                     //  add name
	Description string   `yaml:"description"`
	Required    bool     `yaml:"required"`
	Default     string   `yaml:"default"`
	Type        string   `yaml:"type"`
	Options     []string `yaml:"options"`
}

type WorkflowDispatch struct {
	Inputs []WorkflowDispatchInput            //slice, not map,  for keep ordered
}

func workflowDispatchConfig(w *model.Workflow) *WorkflowDispatch {
        switch w.RawOn.Kind {
	case yaml.ScalarNode:
		var val string
		if !decodeNode(w.RawOn, &val) {
			return nil
		}
		if val == "workflow_dispatch" {
			return &WorkflowDispatch{}
		}
	case yaml.SequenceNode:
		var val []string
		if !decodeNode(w.RawOn, &val) {
			return nil
		}
		for _, v := range val {
			if v == "workflow_dispatch" {
				return &WorkflowDispatch{}
			}
		}
	case yaml.MappingNode:
		var val map[string]yaml.Node
		if !decodeNode(w.RawOn, &val) {
			return nil
		}

		workflowDispatchNode, found := val["workflow_dispatch"]
		if !found {
			return nil
		}

		var workflowDispatchVal map[string]yaml.Node
		if !decodeNode(workflowDispatchNode, &workflowDispatchVal) {
			return nil
		}

		var workflowDispatch WorkflowDispatch
		inputsNode, found := workflowDispatchVal["inputs"]
		if found {
			i := 0
			for {
				if i+1 >= len(inputsNode.Content) {
					break
				}
				var input WorkflowDispatchInput
				if decodeNode(*inputsNode.Content[i+1], &input) {
					input.Name = inputsNode.Content[i].Value
					workflowDispatch.Inputs = append(workflowDispatch.Inputs, input)
				}
				i += 2
			}
		}
		return &workflowDispatch

	default:
		return nil
	}
	return nil
}

I think this is a good idea

TKaxv-7S avatar Dec 18 '23 03:12 TKaxv-7S

@pangliang I think we can try your approach - this is not a lot of code to add. It can still be removed later if there will be a better method inside act.

denyskon avatar Jan 15 '24 20:01 denyskon

Ok, I didn't notice before that WorkflowDispatchConfig comes from nektos/act, now these steps are needed:

These steps have been completed

pangliang avatar Mar 01 '24 06:03 pangliang

@pangliang Is this PR ready?

denyskon avatar Mar 01 '24 18:03 denyskon

@pangliang Is this PR ready?

Yes, this PR is ready for review. I've completed all the necessary work and checks. Please feel free to go through it and provide your feedback.

pangliang avatar Mar 02 '24 02:03 pangliang

@pangliang Is this PR ready?

Yes, this PR is ready for review. I've completed all the necessary work and checks. Please feel free to go through it and provide your feedback.

CI failed and there is a file conflicted with other recent merged PR.

lunny avatar Mar 02 '24 09:03 lunny

@pangliang Please resolve the merge conflict and run make fmt :)

Also starting from now, please only update your branch using merge, not using rebase/force-push to make reviewing easier...

denyskon avatar Mar 02 '24 09:03 denyskon

Just wanted to say - thank you for this! This should resolve #23668

ghnp5 avatar Mar 02 '24 17:03 ghnp5

@pangliang Please resolve the merge conflict and run make fmt :)

Also starting from now, please only update your branch using merge, not using rebase/force-push to make reviewing easier...

@denyskon I merged the latest main. All checks passed too, thanks and please review again.

pangliang avatar Mar 03 '24 02:03 pangliang

https://github.com/go-gitea/gitea/pull/28163/commits/44615a52112db94505c88fd40dabfbaeb6407acf#r1418529722 It seems that this is broken. image

yp05327 avatar Mar 05 '24 06:03 yp05327

44615a5#r1418529722 It seems that this is broken. image

In this discussion, I wonder if I misunderstood? We decided here that we don’t need to check whether it is a number type, just checking required is enough.

pangliang avatar Mar 05 '24 07:03 pangliang

Sorry, it has been a long time, I forgot that. 😭 Maybe you can update the screenshot in the description of this PR. It seems that it is outdated. image

yp05327 avatar Mar 05 '24 07:03 yp05327

I still think it is better to load the details of the workflow after user click the button instead of handling it when loading the page. Let's wait others' comment.

yp05327 avatar Mar 05 '24 09:03 yp05327

From your screenshot:

image

Can you vertically center the button? Should be as simple as adding gt-df gt-ac classes to the blue box.

silverwind avatar Mar 06 '24 00:03 silverwind

the Workflow.WorkflowDispatchConfig() method still return non-nil when workflow_dispatch is not defined. I submitted a PR https://gitea.com/gitea/act/pulls/85 to fix it. Still waiting for them to process.

Is it still required? Was it upstreamed into nektos/act?

silverwind avatar Mar 06 '24 00:03 silverwind

From your screenshot:

image Can you vertically center the button? Should be as simple as adding `gt-df gt-ac` classes to the blue box.

It is currently centered, I will update the screenshot image

pangliang avatar Mar 06 '24 01:03 pangliang