mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-07-18 07:28:47 +00:00
Forgejo Actions allows variables in `jobs.<job_id>.runs-on`. However, the action list [skips checking whether a suitable runner](c3412d0579/routers/web/repo/actions/actions.go (L114-L148)) is available if an expression contains variables. That hampers a user's ability to figure out whether an expression was evaluated correctly and why a job might not be picked up by an available runner.
This PR adds the ability to surface more complex and additional diagnostic information on the action view screen. Previously, only a job's status (waiting, running, ...) was displayed. Now, extended messages like "Waiting for a runner with the following labels: docker, trixie" are displayed with the possibility to show multiple messages simultaneously.
How it looked before:

How it looks after updating Forgejo without reloading the window:

How it looks afterwards with a single label:

How it looks afterwards with multiple labels:

## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests
- I added test coverage for Go changes...
- [x] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
- [x] in `web_src/js/*.test.js` if it can be unit tested.
- [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [ ] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.
<!--start release-notes-assistant-->
## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Features
- [PR](https://codeberg.org/forgejo/forgejo/pulls/9966): <!--number 9966 --><!--line 0 --><!--description ZGlzcGxheSBkZXRhaWxlZCBhY3Rpb24gcnVuIGRpYWdub3N0aWNz-->display detailed action run diagnostics<!--description-->
<!--end release-notes-assistant-->
Co-authored-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9966
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Co-authored-by: Andreas Ahlenstorf <andreas@ahlenstorf.ch>
Co-committed-by: Andreas Ahlenstorf <andreas@ahlenstorf.ch>
150 lines
4.5 KiB
Go
150 lines
4.5 KiB
Go
// SPDX-License-Identifier: MIT
|
|
|
|
package actions
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"testing"
|
|
|
|
"forgejo.org/models/db"
|
|
"forgejo.org/models/unittest"
|
|
"forgejo.org/modules/translation"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestActionRunJob_ItRunsOn(t *testing.T) {
|
|
actionJob := ActionRunJob{RunsOn: []string{"ubuntu"}}
|
|
agentLabels := []string{"ubuntu", "node-20"}
|
|
|
|
assert.True(t, actionJob.ItRunsOn(agentLabels))
|
|
assert.False(t, actionJob.ItRunsOn([]string{}))
|
|
|
|
actionJob.RunsOn = append(actionJob.RunsOn, "node-20")
|
|
|
|
assert.True(t, actionJob.ItRunsOn(agentLabels))
|
|
|
|
agentLabels = []string{"ubuntu"}
|
|
|
|
assert.False(t, actionJob.ItRunsOn(agentLabels))
|
|
|
|
actionJob.RunsOn = []string{}
|
|
|
|
assert.False(t, actionJob.ItRunsOn(agentLabels))
|
|
}
|
|
|
|
func TestActionRunJob_HTMLURL(t *testing.T) {
|
|
require.NoError(t, unittest.PrepareTestDatabase())
|
|
|
|
tests := []struct {
|
|
id int64
|
|
expected string
|
|
}{
|
|
{
|
|
id: 192,
|
|
expected: "https://try.gitea.io/user5/repo4/actions/runs/187/jobs/0/attempt/1",
|
|
},
|
|
{
|
|
id: 393,
|
|
expected: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/1/attempt/1",
|
|
},
|
|
{
|
|
id: 394,
|
|
expected: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/2/attempt/2",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(fmt.Sprintf("id=%d", tt.id), func(t *testing.T) {
|
|
var job ActionRunJob
|
|
has, err := db.GetEngine(t.Context()).Where("id=?", tt.id).Get(&job)
|
|
require.NoError(t, err)
|
|
require.True(t, has, "load ActionRunJob from fixture")
|
|
|
|
err = job.LoadAttributes(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
url, err := job.HTMLURL(t.Context())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expected, url)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestActionRunJob_StatusDiagnostics(t *testing.T) {
|
|
translation.InitLocales(t.Context())
|
|
english := translation.NewLocale("en-US")
|
|
|
|
tests := []struct {
|
|
name string
|
|
job ActionRunJob
|
|
expected []template.HTML
|
|
}{
|
|
{
|
|
name: "Unknown status",
|
|
job: ActionRunJob{RunsOn: []string{"windows"}, Status: StatusUnknown, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Unknown"},
|
|
},
|
|
{
|
|
name: "Waiting without labels",
|
|
job: ActionRunJob{RunsOn: []string{}, Status: StatusWaiting, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Waiting for a runner with the following labels: "},
|
|
},
|
|
{
|
|
name: "Waiting with one label",
|
|
job: ActionRunJob{RunsOn: []string{"freebsd"}, Status: StatusWaiting, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Waiting for a runner with the following label: freebsd"},
|
|
},
|
|
{
|
|
name: "Waiting with labels, no approval",
|
|
job: ActionRunJob{RunsOn: []string{"docker", "ubuntu"}, Status: StatusWaiting, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Waiting for a runner with the following labels: docker, ubuntu"},
|
|
},
|
|
{
|
|
name: "Waiting with labels, approval",
|
|
job: ActionRunJob{RunsOn: []string{"docker", "ubuntu"}, Status: StatusWaiting, Run: &ActionRun{NeedApproval: true}},
|
|
expected: []template.HTML{
|
|
"Waiting for a runner with the following labels: docker, ubuntu",
|
|
"Need approval to run workflows for fork pull request.",
|
|
},
|
|
},
|
|
{
|
|
name: "Running",
|
|
job: ActionRunJob{RunsOn: []string{"debian"}, Status: StatusRunning, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Running"},
|
|
},
|
|
{
|
|
name: "Success",
|
|
job: ActionRunJob{RunsOn: []string{"debian"}, Status: StatusSuccess, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Success"},
|
|
},
|
|
{
|
|
name: "Failure",
|
|
job: ActionRunJob{RunsOn: []string{"debian"}, Status: StatusFailure, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Failure"},
|
|
},
|
|
{
|
|
name: "Cancelled",
|
|
job: ActionRunJob{RunsOn: []string{"debian"}, Status: StatusCancelled, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Canceled"},
|
|
},
|
|
{
|
|
name: "Skipped",
|
|
job: ActionRunJob{RunsOn: []string{"debian"}, Status: StatusSkipped, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Skipped"},
|
|
},
|
|
{
|
|
name: "Blocked",
|
|
job: ActionRunJob{RunsOn: []string{"debian"}, Status: StatusBlocked, Run: &ActionRun{NeedApproval: false}},
|
|
expected: []template.HTML{"Blocked"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.expected, tt.job.StatusDiagnostics(english))
|
|
})
|
|
}
|
|
}
|