44package actions
55
66import (
7+ "code.gitea.io/gitea/modules/container"
78 "context"
9+ "errors"
810 "fmt"
911 "time"
1012
@@ -22,12 +24,12 @@ import (
2224// Cleanup removes expired actions logs, data, artifacts and used ephemeral runners
2325func Cleanup (ctx context.Context ) error {
2426 // clean up expired artifacts
25- if err := CleanupArtifacts (ctx ); err != nil {
27+ if err := CleanupExpiredArtifacts (ctx ); err != nil {
2628 return fmt .Errorf ("cleanup artifacts: %w" , err )
2729 }
2830
2931 // clean up old logs
30- if err := CleanupLogs (ctx ); err != nil {
32+ if err := CleanupExpiredLogs (ctx ); err != nil {
3133 return fmt .Errorf ("cleanup logs: %w" , err )
3234 }
3335
@@ -39,8 +41,8 @@ func Cleanup(ctx context.Context) error {
3941 return nil
4042}
4143
42- // CleanupArtifacts removes expired add need-deleted artifacts and set records expired status
43- func CleanupArtifacts (taskCtx context.Context ) error {
44+ // CleanupExpiredArtifacts removes expired add need-deleted artifacts and set records expired status
45+ func CleanupExpiredArtifacts (taskCtx context.Context ) error {
4446 if err := cleanExpiredArtifacts (taskCtx ); err != nil {
4547 return err
4648 }
@@ -98,8 +100,15 @@ func cleanNeedDeleteArtifacts(taskCtx context.Context) error {
98100
99101const deleteLogBatchSize = 100
100102
101- // CleanupLogs removes logs which are older than the configured retention time
102- func CleanupLogs (ctx context.Context ) error {
103+ func removeTaskLog (ctx context.Context , task * actions_model.ActionTask ) {
104+ if err := actions_module .RemoveLogs (ctx , task .LogInStorage , task .LogFilename ); err != nil {
105+ log .Error ("Failed to remove log %s (in storage %v) of task %v: %v" , task .LogFilename , task .LogInStorage , task .ID , err )
106+ // do not return error here, go on
107+ }
108+ }
109+
110+ // CleanupExpiredLogs removes logs which are older than the configured retention time
111+ func CleanupExpiredLogs (ctx context.Context ) error {
103112 olderThan := timeutil .TimeStampNow ().AddDuration (- time .Duration (setting .Actions .LogRetentionDays ) * 24 * time .Hour )
104113
105114 count := 0
@@ -109,10 +118,7 @@ func CleanupLogs(ctx context.Context) error {
109118 return fmt .Errorf ("find old tasks: %w" , err )
110119 }
111120 for _ , task := range tasks {
112- if err := actions_module .RemoveLogs (ctx , task .LogInStorage , task .LogFilename ); err != nil {
113- log .Error ("Failed to remove log %s (in storage %v) of task %v: %v" , task .LogFilename , task .LogInStorage , task .ID , err )
114- // do not return error here, go on
115- }
121+ removeTaskLog (ctx , task )
116122 task .LogIndexes = nil // clear log indexes since it's a heavy field
117123 task .LogExpired = true
118124 if err := actions_model .UpdateTask (ctx , task , "log_indexes" , "log_expired" ); err != nil {
@@ -148,3 +154,82 @@ func CleanupEphemeralRunners(ctx context.Context) error {
148154 log .Info ("Removed %d runners" , affected )
149155 return nil
150156}
157+
158+ // DeleteRun deletes workflow run, including all logs and artifacts.
159+ func DeleteRun (ctx context.Context , run * actions_model.ActionRun ) error {
160+ if ! run .Status .IsDone () {
161+ return errors .New ("run is not done" )
162+ }
163+
164+ repoID := run .RepoID
165+
166+ jobs , err := actions_model .GetRunJobsByRunID (ctx , run .ID )
167+ if err != nil {
168+ return err
169+ }
170+ jobIDs := container .FilterSlice (jobs , func (j * actions_model.ActionRunJob ) (int64 , bool ) {
171+ return j .ID , j .ID != 0
172+ })
173+ tasks := make (actions_model.TaskList , 0 )
174+ if len (jobIDs ) > 0 {
175+ if err := db .GetEngine (ctx ).Where ("repo_id = ?" , repoID ).In ("job_id" , jobIDs ).Find (& tasks ); err != nil {
176+ return err
177+ }
178+ }
179+
180+ artifacts , err := db .Find [actions_model.ActionArtifact ](ctx , actions_model.FindArtifactsOptions {
181+ RepoID : repoID ,
182+ RunID : run .ID ,
183+ })
184+ if err != nil {
185+ return err
186+ }
187+
188+ var recordsToDelete []any
189+
190+ recordsToDelete = append (recordsToDelete , & actions_model.ActionRun {
191+ RepoID : repoID ,
192+ ID : run .ID ,
193+ })
194+ recordsToDelete = append (recordsToDelete , & actions_model.ActionRunJob {
195+ RepoID : repoID ,
196+ RunID : run .ID ,
197+ })
198+ for _ , tas := range tasks {
199+ recordsToDelete = append (recordsToDelete , & actions_model.ActionTask {
200+ RepoID : repoID ,
201+ ID : tas .ID ,
202+ })
203+ recordsToDelete = append (recordsToDelete , & actions_model.ActionTaskStep {
204+ RepoID : repoID ,
205+ TaskID : tas .ID ,
206+ })
207+ recordsToDelete = append (recordsToDelete , & actions_model.ActionTaskOutput {
208+ TaskID : tas .ID ,
209+ })
210+ }
211+ recordsToDelete = append (recordsToDelete , & actions_model.ActionArtifact {
212+ RepoID : repoID ,
213+ RunID : run .ID ,
214+ })
215+
216+ if err := db .WithTx (ctx , func (ctx context.Context ) error {
217+ return db .DeleteBeans (ctx , recordsToDelete ... )
218+ }); err != nil {
219+ return err
220+ }
221+
222+ //Delete files on storage
223+ for _ , tas := range tasks {
224+ if err := actions_module .RemoveLogs (ctx , tas .LogInStorage , tas .LogFilename ); err != nil {
225+ log .Error ("remove log file %q: %v" , tas .LogFilename , err )
226+ }
227+ }
228+ for _ , art := range artifacts {
229+ if err := storage .ActionsArtifacts .Delete (art .StoragePath ); err != nil {
230+ log .Error ("remove artifact file %q: %v" , art .StoragePath , err )
231+ }
232+ }
233+
234+ return nil
235+ }
0 commit comments