gitforge/services/actions/context_test.go
forgejo-backport-action e112f42259 [v16.0/forgejo] fix: add forgejo_default_actions_url to actions context (#13411)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/13406

Forgejo only added the legacy `gitea_default_actions_url`.

### Tests for Go changes

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
  - [x] `make pr-go` before pushing

### Release notes

- [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Co-authored-by: Andreas Ahlenstorf <andreas@ahlenstorf.ch>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13411
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
2026-07-12 05:34:10 +02:00

406 lines
13 KiB
Go

// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"testing"
actions_model "forgejo.org/models/actions"
"forgejo.org/models/repo"
"forgejo.org/models/unittest"
"forgejo.org/models/user"
actions_module "forgejo.org/modules/actions"
"forgejo.org/modules/json"
"forgejo.org/modules/setting"
webhook_module "forgejo.org/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFindTaskNeeds(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
task := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: 51})
job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: task.JobID})
ret, err := FindTaskNeeds(t.Context(), job)
require.NoError(t, err)
assert.Len(t, ret, 1)
assert.Contains(t, ret, "job1")
assert.Len(t, ret["job1"].Outputs, 2)
assert.Equal(t, "abc", ret["job1"].Outputs["output_a"])
assert.Equal(t, "bbb", ret["job1"].Outputs["output_b"])
}
func TestGenerateGiteaContext(t *testing.T) {
testUser := &user.User{
ID: 123,
Name: "testuser",
}
testRepo := &repo.Repository{
ID: 456,
OwnerID: 789,
OwnerName: "testowner",
Name: "testrepo",
}
emptyField := func(t *testing.T, context map[string]any, field string) {
v, ok := context[field]
assert.True(t, ok, "expected field %q to be present", field)
assert.Empty(t, v)
}
t.Run("Basic workflow run without job", func(t *testing.T) {
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUserID: testUser.ID,
TriggerUser: testUser,
RepoID: testRepo.ID,
Repo: testRepo,
TriggerEvent: "push",
Ref: "refs/heads/main",
CommitSHA: "abc123def456",
WorkflowID: "test-workflow.yaml",
WorkflowDirectory: ".forgejo/workflows",
EventPayload: `{"repository": {"name": "testrepo"}}`,
}
context, err := GenerateGiteaContext(run, nil)
require.NoError(t, err)
assert.Equal(t, "testuser", context["actor"])
assert.Equal(t, "123", context["actor_id"])
assert.Equal(t, setting.AppURL+"api/v1", context["api_url"])
assert.Equal(t, "push", context["event_name"])
assert.Equal(t, "refs/heads/main", context["ref"])
assert.Equal(t, "main", context["ref_name"])
assert.Equal(t, "branch", context["ref_type"])
assert.Equal(t, "789", context["repository_owner_id"])
assert.Equal(t, "testowner/testrepo", context["repository"])
assert.Equal(t, "456", context["repository_id"])
assert.Equal(t, "testowner", context["repository_owner"])
assert.Equal(t, "abc123def456", context["sha"])
assert.Equal(t, "42", context["run_number"])
assert.Equal(t, "test-workflow.yaml", context["workflow"])
assert.Equal(t, "testowner/testrepo/.forgejo/workflows/test-workflow.yaml@refs/heads/main", context["workflow_ref"])
assert.Equal(t, false, context["ref_protected"])
assert.Equal(t, "Actions", context["secret_source"])
assert.Equal(t, setting.AppURL, context["server_url"])
assert.Equal(t, setting.Actions.DefaultActionsURL.URL(), context["gitea_default_actions_url"])
assert.Equal(t, setting.Actions.DefaultActionsURL.URL(), context["forgejo_default_actions_url"])
assert.Equal(t, setting.AppVer, context["forgejo_server_version"])
event, ok := context["event"].(map[string]any)
require.True(t, ok)
assert.Equal(t, "testrepo", event["repository"].(map[string]any)["name"])
emptyField(t, context, "action_path")
emptyField(t, context, "action_ref")
emptyField(t, context, "action_repository")
emptyField(t, context, "action_status")
emptyField(t, context, "action")
emptyField(t, context, "base_ref")
emptyField(t, context, "env")
emptyField(t, context, "event_path")
emptyField(t, context, "graphql_url")
emptyField(t, context, "head_ref")
emptyField(t, context, "job")
emptyField(t, context, "path")
emptyField(t, context, "retention_days")
emptyField(t, context, "run_attempt")
emptyField(t, context, "run_id")
emptyField(t, context, "triggering_actor")
emptyField(t, context, "workspace")
})
t.Run("Workflow run with job", func(t *testing.T) {
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUser: testUser,
Repo: testRepo,
TriggerEvent: "push",
Ref: "refs/heads/main",
CommitSHA: "abc123def456",
WorkflowID: "test-workflow",
EventPayload: `{}`,
}
job := &actions_model.ActionRunJob{
ID: 100,
RunID: 1,
JobID: "test-job",
Attempt: 1,
WorkflowPayload: []byte("on: [push]"),
}
context, err := GenerateGiteaContext(run, job)
require.NoError(t, err)
assert.Equal(t, "test-job", context["job"])
assert.Equal(t, "1", context["run_id"])
assert.Equal(t, "1", context["run_attempt"])
})
t.Run("Pull request event", func(t *testing.T) {
pullRequestPayload := map[string]any{
"pull_request": map[string]any{
"base": map[string]any{
"ref": "main",
"label": "main",
"sha": "base123sha",
},
"head": map[string]any{
"ref": "feature-branch",
"label": "feature-branch",
"sha": "head456sha",
},
},
}
payloadBytes, _ := json.Marshal(pullRequestPayload)
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUser: testUser,
Repo: testRepo,
TriggerEvent: "pull_request",
Ref: "refs/pull/1/merge",
CommitSHA: "merge789sha",
WorkflowID: "test-workflow.yaml",
WorkflowDirectory: ".forgejo/workflows",
Event: webhook_module.HookEventPullRequest,
EventPayload: string(payloadBytes),
}
context, err := GenerateGiteaContext(run, nil)
require.NoError(t, err)
assert.Equal(t, "main", context["base_ref"])
assert.Equal(t, "feature-branch", context["head_ref"])
assert.Equal(t, "refs/pull/1/merge", context["ref"])
assert.Equal(t, "merge789sha", context["sha"])
assert.Equal(t, "testowner/testrepo/.forgejo/workflows/test-workflow.yaml@refs/pull/1/merge", context["workflow_ref"])
})
t.Run("Pull request target event", func(t *testing.T) {
pullRequestPayload := map[string]any{
"pull_request": map[string]any{
"base": map[string]any{
"ref": "main",
"label": "main",
"sha": "base123sha",
},
"head": map[string]any{
"ref": "feature-branch",
"label": "feature-branch",
"sha": "head456sha",
},
},
}
payloadBytes, _ := json.Marshal(pullRequestPayload)
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUser: testUser,
Repo: testRepo,
TriggerEvent: actions_module.GithubEventPullRequestTarget,
Ref: "refs/pull/1/merge",
CommitSHA: "merge789sha",
WorkflowID: "test-workflow.yml",
WorkflowDirectory: ".github/workflows",
Event: webhook_module.HookEventPullRequest,
EventPayload: string(payloadBytes),
}
context, err := GenerateGiteaContext(run, nil)
require.NoError(t, err)
assert.Equal(t, "main", context["base_ref"])
assert.Equal(t, "feature-branch", context["head_ref"])
// For pull_request_target, ref and sha should be from base
assert.Equal(t, "refs/heads/main", context["ref"])
assert.Equal(t, "base123sha", context["sha"])
assert.Equal(t, "main", context["ref_name"])
assert.Equal(t, "branch", context["ref_type"])
assert.Equal(t, "testowner/testrepo/.github/workflows/test-workflow.yml@refs/heads/main", context["workflow_ref"])
})
t.Run("workflow_call job", func(t *testing.T) {
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUser: testUser,
Repo: testRepo,
TriggerEvent: "push",
Ref: "refs/heads/main",
CommitSHA: "abc123def456",
WorkflowID: "test-workflow",
EventPayload: `{}`,
}
job := &actions_model.ActionRunJob{
ID: 100,
RunID: 1,
JobID: "test-job",
Attempt: 1,
WorkflowPayload: []byte("on: { workflow_call: { inputs: {} } }\n__metadata:\n workflow_call_parent: b5a9f46f1f2513d7777fde50b169d323a6519e349cc175484c947ac315a209ed\n"),
}
context, err := GenerateGiteaContext(run, job)
require.NoError(t, err)
assert.Equal(t, "workflow_call", context["event_name"])
})
}
func TestGenerateGiteaContextForRun(t *testing.T) {
testUser := &user.User{
ID: 1,
Name: "testuser",
}
testRepo := &repo.Repository{
ID: 1,
OwnerName: "testowner",
Name: "testrepo",
}
t.Run("Basic workflow run", func(t *testing.T) {
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUser: testUser,
Repo: testRepo,
TriggerEvent: "push",
Ref: "refs/heads/main",
CommitSHA: "abc123def456",
WorkflowID: "test-workflow.yaml",
WorkflowDirectory: ".forgejo/workflows",
EventPayload: `{"repository": {"name": "testrepo"}}`,
}
gitContextObj := generateGiteaContextForRun(run)
assert.Equal(t, "testuser", gitContextObj.Actor)
assert.Equal(t, setting.AppURL+"api/v1", gitContextObj.APIURL)
assert.Equal(t, "push", gitContextObj.EventName)
assert.Equal(t, "refs/heads/main", gitContextObj.Ref)
assert.Equal(t, "main", gitContextObj.RefName)
assert.Equal(t, "branch", gitContextObj.RefType)
assert.Equal(t, "testowner/testrepo", gitContextObj.Repository)
assert.Equal(t, "testowner", gitContextObj.RepositoryOwner)
assert.Equal(t, "abc123def456", gitContextObj.Sha)
assert.Equal(t, "42", gitContextObj.RunNumber)
assert.Equal(t, "test-workflow.yaml", gitContextObj.Workflow)
assert.Equal(t, "testowner/testrepo/.forgejo/workflows/test-workflow.yaml@refs/heads/main", gitContextObj.WorkflowRef)
assert.Equal(t, "testrepo", gitContextObj.Event["repository"].(map[string]any)["name"])
assert.Empty(t, gitContextObj.ActionPath)
assert.Empty(t, gitContextObj.ActionRef)
assert.Empty(t, gitContextObj.ActionRepository)
assert.Empty(t, gitContextObj.Action)
assert.Empty(t, gitContextObj.BaseRef)
assert.Empty(t, gitContextObj.EventPath)
assert.Empty(t, gitContextObj.GraphQLURL)
assert.Empty(t, gitContextObj.HeadRef)
assert.Empty(t, gitContextObj.Job)
assert.Empty(t, gitContextObj.RetentionDays)
assert.Empty(t, gitContextObj.RunAttempt)
assert.Empty(t, gitContextObj.RunID)
assert.Empty(t, gitContextObj.Workspace)
})
t.Run("Pull request event", func(t *testing.T) {
pullRequestPayload := map[string]any{
"pull_request": map[string]any{
"base": map[string]any{
"ref": "main",
"label": "main",
"sha": "base123sha",
},
"head": map[string]any{
"ref": "feature-branch",
"label": "feature-branch",
"sha": "head456sha",
},
},
}
payloadBytes, _ := json.Marshal(pullRequestPayload)
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUser: testUser,
Repo: testRepo,
TriggerEvent: "pull_request",
Ref: "refs/pull/1/merge",
CommitSHA: "merge789sha",
WorkflowID: "test-workflow.yaml",
WorkflowDirectory: ".forgejo/workflows",
Event: webhook_module.HookEventPullRequest,
EventPayload: string(payloadBytes),
}
gitContextObj := generateGiteaContextForRun(run)
assert.Equal(t, "main", gitContextObj.BaseRef)
assert.Equal(t, "feature-branch", gitContextObj.HeadRef)
assert.Equal(t, "refs/pull/1/merge", gitContextObj.Ref)
assert.Equal(t, "merge789sha", gitContextObj.Sha)
assert.Equal(t, "testowner/testrepo/.forgejo/workflows/test-workflow.yaml@refs/pull/1/merge", gitContextObj.WorkflowRef)
})
t.Run("Pull request target event", func(t *testing.T) {
pullRequestPayload := map[string]any{
"pull_request": map[string]any{
"base": map[string]any{
"ref": "main",
"label": "main",
"sha": "base123sha",
},
"head": map[string]any{
"ref": "feature-branch",
"label": "feature-branch",
"sha": "head456sha",
},
},
}
payloadBytes, _ := json.Marshal(pullRequestPayload)
run := &actions_model.ActionRun{
ID: 1,
Index: 42,
TriggerUser: testUser,
Repo: testRepo,
TriggerEvent: actions_module.GithubEventPullRequestTarget,
Ref: "refs/pull/1/merge",
CommitSHA: "merge789sha",
WorkflowID: "test-workflow.yml",
WorkflowDirectory: ".github/workflows",
Event: webhook_module.HookEventPullRequest,
EventPayload: string(payloadBytes),
}
gitContextObj := generateGiteaContextForRun(run)
assert.Equal(t, "main", gitContextObj.BaseRef)
assert.Equal(t, "feature-branch", gitContextObj.HeadRef)
// For pull_request_target, ref and sha should be from base
assert.Equal(t, "refs/heads/main", gitContextObj.Ref)
assert.Equal(t, "base123sha", gitContextObj.Sha)
assert.Equal(t, "main", gitContextObj.RefName)
assert.Equal(t, "branch", gitContextObj.RefType)
assert.Equal(t, "testowner/testrepo/.github/workflows/test-workflow.yml@refs/heads/main", gitContextObj.WorkflowRef)
})
}