snapshot of https://github.com/go-gitea/gitea.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped
Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped
This commit is contained in:
137
services/actions/helper_test.go
Normal file
137
services/actions/helper_test.go
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
actions_model "gitea.dev/models/actions"
|
||||
actions_module "gitea.dev/modules/actions"
|
||||
"gitea.dev/modules/json"
|
||||
api "gitea.dev/modules/structs"
|
||||
webhook_module "gitea.dev/modules/webhook"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEvaluateJobIfDefersMatrixExpression(t *testing.T) {
|
||||
// A placeholder's `if:` reading `matrix.*` can only be decided per combination once the matrix is expanded.
|
||||
|
||||
emptyRun := &actions_model.ActionRun{} // if the gate is removed, the emptyRun will cause an error
|
||||
deferredJob := func(ifExpr string) *actions_model.ActionRunJob {
|
||||
return &actions_model.ActionRunJob{
|
||||
ID: 1, JobID: "build", Needs: []string{"setup"}, IsMatrixDeferred: true,
|
||||
WorkflowPayload: fmt.Appendf(nil, `name: test
|
||||
on: push
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: %s
|
||||
strategy:
|
||||
matrix:
|
||||
value: ${{ fromJson(needs.setup.outputs.m) }}
|
||||
steps:
|
||||
- run: echo
|
||||
`, ifExpr),
|
||||
}
|
||||
}
|
||||
|
||||
for _, tt := range []struct {
|
||||
ifExpr string
|
||||
// wantNeedsFailed is what the `if:` decides when the needs did not all succeed.
|
||||
wantNeedsFailed bool
|
||||
}{
|
||||
// These hold only for a real combination, so none can be decided before the matrix expands,
|
||||
// and the fallback is the needs gate: a job whose needs did not succeed is still skipped.
|
||||
{ifExpr: "${{ matrix.value == 1 }}"},
|
||||
{ifExpr: "matrix.value == 1"}, // an `if:` may omit the `${{ }}`
|
||||
// always() asks to run whatever the needs did, so it must not fall back to their gate.
|
||||
{ifExpr: "${{ always() && matrix.value == 1 }}", wantNeedsFailed: true},
|
||||
} {
|
||||
t.Run(tt.ifExpr, func(t *testing.T) {
|
||||
got, err := evaluateJobIf(t.Context(), emptyRun, nil, deferredJob(tt.ifExpr), nil, true)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, got, "must reach the expansion that gates each combination on its own values")
|
||||
|
||||
got, err = evaluateJobIf(t.Context(), emptyRun, nil, deferredJob(tt.ifExpr), nil, false)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.wantNeedsFailed, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDispatchInputsForRunJobs(t *testing.T) {
|
||||
// a child carries the callee's `on: workflow_call`, so only a top-level job answers for the run
|
||||
run := &actions_model.ActionRun{Event: "workflow_dispatch", EventPayload: `{"inputs":{"deploy":"true"}}`}
|
||||
job := &actions_model.ActionRunJob{
|
||||
ID: 1, JobID: "deploy",
|
||||
WorkflowPayload: []byte("on: {workflow_dispatch: {inputs: {deploy: {type: boolean}}}}\njobs:\n deploy:\n steps: [{run: echo}]\n"),
|
||||
}
|
||||
child := &actions_model.ActionRunJob{
|
||||
ID: 2, JobID: "called", ParentJobID: job.ID,
|
||||
WorkflowPayload: []byte("on: workflow_call\njobs:\n called:\n steps: [{run: echo}]\n"),
|
||||
}
|
||||
|
||||
inputs, err := dispatchInputsForRunJobs(run, []*actions_model.ActionRunJob{child, job})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, inputs["deploy"])
|
||||
}
|
||||
|
||||
func TestPullRequestTargetBaseSHA(t *testing.T) {
|
||||
prPayload := func(baseSHA string) string {
|
||||
payload, err := json.Marshal(api.PullRequestPayload{
|
||||
PullRequest: &api.PullRequest{
|
||||
Base: &api.PRBranchInfo{Sha: baseSHA},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return string(payload)
|
||||
}
|
||||
|
||||
t.Run("pull_request_target with base SHA", func(t *testing.T) {
|
||||
run := &actions_model.ActionRun{
|
||||
Event: webhook_module.HookEventPullRequest,
|
||||
TriggerEvent: actions_module.GithubEventPullRequestTarget,
|
||||
EventPayload: prPayload("base-sha"),
|
||||
}
|
||||
got, ok := pullRequestTargetBaseSHA(run)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "base-sha", got)
|
||||
})
|
||||
|
||||
t.Run("non pull_request_target trigger", func(t *testing.T) {
|
||||
run := &actions_model.ActionRun{
|
||||
Event: webhook_module.HookEventPullRequest,
|
||||
TriggerEvent: actions_module.GithubEventPullRequest,
|
||||
EventPayload: prPayload("base-sha"),
|
||||
}
|
||||
got, ok := pullRequestTargetBaseSHA(run)
|
||||
assert.False(t, ok)
|
||||
assert.Empty(t, got)
|
||||
})
|
||||
|
||||
t.Run("missing base SHA", func(t *testing.T) {
|
||||
run := &actions_model.ActionRun{
|
||||
Event: webhook_module.HookEventPullRequest,
|
||||
TriggerEvent: actions_module.GithubEventPullRequestTarget,
|
||||
EventPayload: prPayload(""),
|
||||
}
|
||||
got, ok := pullRequestTargetBaseSHA(run)
|
||||
assert.False(t, ok)
|
||||
assert.Empty(t, got)
|
||||
})
|
||||
|
||||
t.Run("invalid payload", func(t *testing.T) {
|
||||
run := &actions_model.ActionRun{
|
||||
Event: webhook_module.HookEventPullRequest,
|
||||
TriggerEvent: actions_module.GithubEventPullRequestTarget,
|
||||
EventPayload: "{",
|
||||
}
|
||||
got, ok := pullRequestTargetBaseSHA(run)
|
||||
assert.False(t, ok)
|
||||
assert.Empty(t, got)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user