forgejo/services/actions/workflows.go
Renovate Bot 0fb9fc752b Update module code.forgejo.org/forgejo/act to v1.32.0 (forgejo) (#8502)
This PR contains the following updates:

| Package | Change | Age | Confidence |
|---|---|---|---|
| [code.forgejo.org/forgejo/act](https://code.forgejo.org/forgejo/act) | `v1.29.0` -> `v1.32.0` | [![age](https://developer.mend.io/api/mc/badges/age/go/code.forgejo.org%2fforgejo%2fact/v1.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/code.forgejo.org%2fforgejo%2fact/v1.29.0/v1.32.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>forgejo/act (code.forgejo.org/forgejo/act)</summary>

### [`v1.32.0`](https://code.forgejo.org/forgejo/act/compare/v1.31.0...v1.32.0)

[Compare Source](https://code.forgejo.org/forgejo/act/compare/v1.31.0...v1.32.0)

### [`v1.31.0`](https://code.forgejo.org/forgejo/act/compare/v1.30.0...v1.31.0)

[Compare Source](https://code.forgejo.org/forgejo/act/compare/v1.30.0...v1.31.0)

### [`v1.30.0`](https://code.forgejo.org/forgejo/act/compare/v1.29.0...v1.30.0)

[Compare Source](https://code.forgejo.org/forgejo/act/compare/v1.29.0...v1.30.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC), Automerge - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4yMy4yIiwidXBkYXRlZEluVmVyIjoiNDEuNDIuMiIsInRhcmdldEJyYW5jaCI6ImZvcmdlam8iLCJsYWJlbHMiOlsiZGVwZW5kZW5jeS11cGdyYWRlIiwidGVzdC9ub3QtbmVlZGVkIl19-->

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Breaking features
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/8502): <!--number 8502 --><!--line 0 --><!--description Rm9yZ2VqbyBBY3Rpb25zIHdvcmtmbG93cyBhcmUgdmVyaWZpZWQgd2l0aCBhIFlBTUwgc2NoZW1hIGFuZCBjb21tb24gZXJyb3JzIHN1Y2ggYXMgdXNpbmcgYW4gaW5jb3JyZWN0IGNvbnRleHQgKGUuZy4gYCR7eyBiYWRjb250ZXh0LkZPUkdFSk9fUkVQT1NJVE9SWSB9fWApIG9yIGEgdHlwbyBpbiBhIHJlcXVpcmVkIGtleXdvcmQgKGUuZy4gYHJ1aW5zLW9uOmAgaW5zdGVhZCBvZiBgcnVucy1vbjpgKSB3aWxsIGJlIHJlcG9ydGVkIGluIHRoZSBhY3Rpb24gcGFnZSBhbmQgdGhlIHdlYiBwYWdlIHRoYXQgZGlzcGxheXMgdGhlIGZpbGUgaW4gdGhlIHJlcG9zaXRvcnkuIEl0IGlzIHJlY29tbWVuZGVkIHRvIHZlcmlmeSBleGlzdGluZyB3b3JrZmxvd3MgYXJlIHN1Y2Nlc3NmdWxseSB2ZXJpZmllZCBwcmlvciB0byB1cGdyYWRpbmcsIFthcyBleHBsYWluZWQgaW4gdGhlIEZvcmdlam8gcnVubmVyIHJlbGVhc2Ugbm90ZXNdKGh0dHBzOi8vY29kZS5mb3JnZWpvLm9yZy9mb3JnZWpvL3J1bm5lci9zcmMvYnJhbmNoL21haW4vUkVMRUFTRS1OT1RFUy5tZCM4LTAtMCku-->Forgejo Actions workflows are verified with a YAML schema and common errors such as using an incorrect context (e.g. `${{ badcontext.FORGEJO_REPOSITORY }}`) or a typo in a required keyword (e.g. `ruins-on:` instead of `runs-on:`) will be reported in the action page and the web page that displays the file in the repository. It is recommended to verify existing workflows are successfully verified prior to upgrading, [as explained in the Forgejo runner release notes](https://code.forgejo.org/forgejo/runner/src/branch/main/RELEASE-NOTES.md#8-0-0).<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8502
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-07-23 01:01:31 +02:00

182 lines
4.2 KiB
Go

// Copyright The Forgejo Authors.
// SPDX-License-Identifier: MIT
package actions
import (
"bytes"
"context"
"errors"
"fmt"
"strconv"
actions_model "forgejo.org/models/actions"
"forgejo.org/models/perm"
"forgejo.org/models/perm/access"
repo_model "forgejo.org/models/repo"
"forgejo.org/models/user"
"forgejo.org/modules/actions"
"forgejo.org/modules/git"
"forgejo.org/modules/json"
"forgejo.org/modules/setting"
"forgejo.org/modules/structs"
"forgejo.org/modules/util"
"forgejo.org/modules/webhook"
"forgejo.org/services/convert"
"github.com/nektos/act/pkg/jobparser"
act_model "github.com/nektos/act/pkg/model"
)
type InputRequiredErr struct {
Name string
}
func (err InputRequiredErr) Error() string {
return fmt.Sprintf("input required for '%s'", err.Name)
}
func IsInputRequiredErr(err error) bool {
_, ok := err.(InputRequiredErr)
return ok
}
type Workflow struct {
WorkflowID string
Ref string
Commit *git.Commit
GitEntry *git.TreeEntry
}
type InputValueGetter func(key string) string
func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGetter, repo *repo_model.Repository, doer *user.User) (r *actions_model.ActionRun, j []string, err error) {
content, err := actions.GetContentFromEntry(entry.GitEntry)
if err != nil {
return nil, nil, err
}
wf, err := act_model.ReadWorkflow(bytes.NewReader(content), false)
if err != nil {
return nil, nil, err
}
fullWorkflowID := ".forgejo/workflows/" + entry.WorkflowID
title := wf.Name
if len(title) < 1 {
title = fullWorkflowID
}
inputs := make(map[string]string)
if workflowDispatch := wf.WorkflowDispatchConfig(); workflowDispatch != nil {
for key, input := range workflowDispatch.Inputs {
val := inputGetter(key)
if len(val) == 0 {
val = input.Default
if len(val) == 0 {
if input.Required {
name := input.Description
if len(name) == 0 {
name = key
}
return nil, nil, InputRequiredErr{Name: name}
}
continue
}
} else if input.Type == "boolean" {
// Since "boolean" inputs are rendered as a checkbox in html, the value inside the form is "on"
val = strconv.FormatBool(val == "on")
}
inputs[key] = val
}
}
if int64(len(inputs)) > setting.Actions.LimitDispatchInputs {
return nil, nil, errors.New("to many inputs")
}
jobNames := util.KeysOfMap(wf.Jobs)
payload := &structs.WorkflowDispatchPayload{
Inputs: inputs,
Ref: entry.Ref,
Repository: convert.ToRepo(ctx, repo, access.Permission{AccessMode: perm.AccessModeNone}),
Sender: convert.ToUser(ctx, doer, nil),
Workflow: fullWorkflowID,
}
p, err := json.Marshal(payload)
if err != nil {
return nil, nil, err
}
notifications, err := wf.Notifications()
if err != nil {
return nil, nil, err
}
run := &actions_model.ActionRun{
Title: title,
RepoID: repo.ID,
Repo: repo,
OwnerID: repo.OwnerID,
WorkflowID: entry.WorkflowID,
TriggerUserID: doer.ID,
TriggerUser: doer,
Ref: entry.Ref,
CommitSHA: entry.Commit.ID.String(),
Event: webhook.HookEventWorkflowDispatch,
EventPayload: string(p),
TriggerEvent: string(webhook.HookEventWorkflowDispatch),
Status: actions_model.StatusWaiting,
NotifyEmail: notifications,
}
vars, err := actions_model.GetVariablesOfRun(ctx, run)
if err != nil {
return nil, nil, err
}
jobs, err := jobparser.Parse(content, false, jobparser.WithVars(vars))
if err != nil {
return nil, nil, err
}
return run, jobNames, actions_model.InsertRun(ctx, run, jobs)
}
func GetWorkflowFromCommit(gitRepo *git.Repository, ref, workflowID string) (*Workflow, error) {
ref, err := gitRepo.ExpandRef(ref)
if err != nil {
return nil, err
}
commit, err := gitRepo.GetCommit(ref)
if err != nil {
return nil, err
}
entries, err := actions.ListWorkflows(commit)
if err != nil {
return nil, err
}
var workflowEntry *git.TreeEntry
for _, entry := range entries {
if entry.Name() == workflowID {
workflowEntry = entry
break
}
}
if workflowEntry == nil {
return nil, errors.New("workflow not found")
}
return &Workflow{
WorkflowID: workflowID,
Ref: ref,
Commit: commit,
GitEntry: workflowEntry,
}, nil
}