@@ -581,6 +581,97 @@ func Approve(ctx *context_module.Context) {
581581 ctx .JSON (http .StatusOK , struct {}{})
582582}
583583
584+ // TODO: When deleting a run, it should at lease delete artifacts, tasks logs, database record.
585+ func Delete (ctx * context_module.Context ) {
586+ runIndex := getRunIndex (ctx )
587+
588+ job0 , jobs := getRunJobs (ctx , runIndex , - 1 )
589+ if ctx .Written () {
590+ return
591+ }
592+
593+ run := job0 .Run
594+ if ! run .Status .IsDone () {
595+ // TODO: Locale?
596+ ctx .JSONError ("run not done yet" )
597+ return
598+ }
599+
600+ repoID := ctx .Repo .Repository .ID
601+
602+ tasks := []* actions_model.ActionTask {}
603+
604+ for _ , job := range jobs {
605+ tasks0 , err := db .Find [actions_model.ActionTask ](ctx , actions_model.FindTaskOptions {
606+ RepoID : repoID ,
607+ JobID : job .ID ,
608+ })
609+ if err != nil {
610+ ctx .HTTPError (http .StatusInternalServerError , err .Error ())
611+ return
612+ }
613+ tasks = append (tasks , tasks0 ... )
614+ }
615+
616+ artifacts , err := db .Find [actions_model.ActionArtifact ](ctx , actions_model.FindArtifactsOptions {
617+ RepoID : repoID ,
618+ RunID : run .ID ,
619+ })
620+ if err != nil {
621+ ctx .HTTPError (http .StatusInternalServerError , err .Error ())
622+ return
623+ }
624+
625+ recordsToDelete := []any {}
626+
627+ for _ , task := range tasks {
628+ recordsToDelete = append (recordsToDelete , & actions_model.ActionTask {
629+ RepoID : repoID ,
630+ ID : task .ID ,
631+ })
632+ recordsToDelete = append (recordsToDelete , & actions_model.ActionTaskStep {
633+ RepoID : repoID ,
634+ TaskID : task .ID ,
635+ })
636+ }
637+ recordsToDelete = append (recordsToDelete , & actions_model.ActionRunJob {
638+ RepoID : repoID ,
639+ RunID : run .ID ,
640+ })
641+ recordsToDelete = append (recordsToDelete , & actions_model.ActionRun {
642+ RepoID : repoID ,
643+ ID : run .ID ,
644+ })
645+ recordsToDelete = append (recordsToDelete , & actions_model.ActionArtifact {
646+ RepoID : repoID ,
647+ RunID : run .ID ,
648+ })
649+
650+ if err := db .WithTx (ctx , func (ctx context.Context ) error {
651+ return db .DeleteBeans (ctx , recordsToDelete ... )
652+ }); err != nil {
653+ ctx .HTTPError (http .StatusInternalServerError , err .Error ())
654+ return
655+ }
656+
657+ // Delete files on storage
658+ for _ , task := range tasks {
659+ err := actions .RemoveLogs (ctx , task .LogInStorage , task .LogFilename )
660+ if err != nil {
661+ log .Error ("remove log file %q: %v" , task .LogFilename , err )
662+ }
663+ }
664+ for _ , art := range artifacts {
665+ if err := storage .ActionsArtifacts .Delete (art .StoragePath ); err != nil {
666+ log .Error ("remove artifact file %q: %v" , art .StoragePath , err )
667+ }
668+ }
669+
670+ // TODO: Delete commit status? Looks like it has no direct reference to a run/task/job. Not quite feasible without modifying db models (Dangerous).
671+
672+ ctx .JSON (http .StatusOK , struct {}{})
673+ }
674+
584675// getRunJobs gets the jobs of runIndex, and returns jobs[jobIndex], jobs.
585676// Any error will be written to the ctx.
586677// It never returns a nil job of an empty jobs, if the jobIndex is out of range, it will be treated as 0.
0 commit comments