mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-08 22:13:26 +09:00
enhance(actions): improve reusable workflow uses handling and cancellation (#37991)
Follow up #37478 ## Changes 1. #37478 doesn't support absolute URL in `uses`. This PR provides partial support for URL-style reusable workflow references. A reusable workflow can now be referenced by an absolute URL, as long as it points to the local Gitea instance: ```yaml jobs: call: uses: https://your-gitea.example.com/OWNER/REPO/.gitea/workflows/ci.yaml@v1 ``` 2. Show an error message in the UI for invalid `uses`. <img width="1600" alt="image" src="https://github.com/user-attachments/assets/21b34e61-bf10-4af1-b9fd-4ee4e9fde049" /> 3. Fix reusable caller cancellation issue. A reusable caller's status is aggregated from its children, so cancellation should processes a caller's descendants deepest-first. --------- Signed-off-by: Zettat123 <zettat123@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: bircni <bircni@icloud.com> Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI
bircni
Giteabot
parent
1e9ea9c8f5
commit
60f66a9bfd
@@ -131,3 +131,69 @@ func TestGetPriorAttemptChildrenByParent(t *testing.T) {
|
||||
assertAttempt1Children(t, out)
|
||||
})
|
||||
}
|
||||
|
||||
// A reusable caller subtree with a Blocked descendant (e.g. a nested caller stuck on an invalid `uses:`) must aggregate to Cancelled, when the run is cancelled.
|
||||
func TestCancelJobs_NestedBlockedReusableCaller(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
ctx := t.Context()
|
||||
|
||||
run := &ActionRun{
|
||||
Title: "cancel-nested-caller",
|
||||
RepoID: 4,
|
||||
Index: 9701,
|
||||
OwnerID: 1,
|
||||
WorkflowID: "caller.yaml",
|
||||
TriggerUserID: 1,
|
||||
Ref: "refs/heads/master",
|
||||
CommitSHA: "c2d72f548424103f01ee1dc02889c1e2bff816b0",
|
||||
Event: "push",
|
||||
TriggerEvent: "push",
|
||||
EventPayload: "{}",
|
||||
Status: StatusBlocked,
|
||||
}
|
||||
require.NoError(t, db.Insert(ctx, run))
|
||||
|
||||
attempt := &ActionRunAttempt{RepoID: run.RepoID, RunID: run.ID, Attempt: 1, TriggerUserID: 1, Status: StatusBlocked}
|
||||
require.NoError(t, db.Insert(ctx, attempt))
|
||||
run.LatestAttemptID = attempt.ID
|
||||
require.NoError(t, UpdateRun(ctx, run, "latest_attempt_id"))
|
||||
|
||||
newJob := func(name string, attemptJobID, parentID int64, callUses string) *ActionRunJob {
|
||||
job := &ActionRunJob{
|
||||
RunID: run.ID,
|
||||
RunAttemptID: attempt.ID,
|
||||
RepoID: run.RepoID,
|
||||
OwnerID: run.OwnerID,
|
||||
CommitSHA: run.CommitSHA,
|
||||
Name: name,
|
||||
JobID: name,
|
||||
Attempt: 1,
|
||||
Status: StatusBlocked,
|
||||
AttemptJobID: attemptJobID,
|
||||
IsReusableCaller: true,
|
||||
CallUses: callUses,
|
||||
ParentJobID: parentID,
|
||||
}
|
||||
require.NoError(t, db.Insert(ctx, job))
|
||||
return job
|
||||
}
|
||||
|
||||
// outer: a valid top-level caller that expanded; inner: a nested caller stuck Blocked (invalid uses, never expands).
|
||||
outer := newJob("outer", 1, 0, "./.gitea/workflows/lib.yml")
|
||||
inner := newJob("inner", 2, outer.ID, "https://other.example.com/o/r/.gitea/workflows/ci.yml@v1")
|
||||
|
||||
// Cancel all jobs of the attempt, ordered by id (parent before child).
|
||||
jobs, err := GetRunJobsByRunAndAttemptID(ctx, run.ID, attempt.ID)
|
||||
require.NoError(t, err)
|
||||
_, err = CancelJobs(ctx, jobs)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, j := range []*ActionRunJob{outer, inner} {
|
||||
got := unittest.AssertExistsAndLoadBean(t, &ActionRunJob{ID: j.ID})
|
||||
assert.Equal(t, StatusCancelled, got.Status, "job %q should be cancelled", j.JobID)
|
||||
}
|
||||
gotAttempt := unittest.AssertExistsAndLoadBean(t, &ActionRunAttempt{ID: attempt.ID})
|
||||
assert.Equal(t, StatusCancelled, gotAttempt.Status, "attempt must aggregate to Cancelled")
|
||||
gotRun := unittest.AssertExistsAndLoadBean(t, &ActionRun{ID: run.ID})
|
||||
assert.Equal(t, StatusCancelled, gotRun.Status, "run must aggregate to Cancelled, not stay Blocked")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user