Skip to content

Commit 72ac7a0

Browse files
committed
add delete button for artifact
1 parent ae8e8f0 commit 72ac7a0

File tree

5 files changed

+51
-1
lines changed

5 files changed

+51
-1
lines changed

models/actions/artifact.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const (
2424
ArtifactStatusUploadConfirmed // 2, ArtifactStatusUploadConfirmed is the status of an artifact upload that is confirmed
2525
ArtifactStatusUploadError // 3, ArtifactStatusUploadError is the status of an artifact upload that is errored
2626
ArtifactStatusExpired // 4, ArtifactStatusExpired is the status of an artifact that is expired
27+
ArtifactStatusNeedDelete // 5, ArtifactStatusNeedDelete is the status of an artifact that is need-delete
28+
ArtifactStatusDeleted // 6, ArtifactStatusDeleted is the status of an artifact that is deleted
2729
)
2830

2931
func init() {
@@ -167,3 +169,9 @@ func SetArtifactExpired(ctx context.Context, artifactID int64) error {
167169
_, err := db.GetEngine(ctx).Where("id=? AND status = ?", artifactID, ArtifactStatusUploadConfirmed).Cols("status").Update(&ActionArtifact{Status: int64(ArtifactStatusExpired)})
168170
return err
169171
}
172+
173+
// SetArtifactNeedDelete sets an artifact to need-delete, cron job will delete it
174+
func SetArtifactNeedDelete(ctx context.Context, runID int64, name string) error {
175+
_, err := db.GetEngine(ctx).Where("run_id=? AND artifact_name=? AND status = ?", runID, name, ArtifactStatusUploadConfirmed).Cols("status").Update(&ActionArtifact{Status: int64(ArtifactStatusNeedDelete)})
176+
return err
177+
}

routers/web/repo/actions/view.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,31 @@ func ArtifactsView(ctx *context_module.Context) {
524524
ctx.JSON(http.StatusOK, artifactsResponse)
525525
}
526526

527+
func ArtifactsDeleteView(ctx *context_module.Context) {
528+
if !ctx.Repo.CanWrite(unit.TypeActions) {
529+
ctx.Error(http.StatusForbidden, "no permission")
530+
return
531+
}
532+
533+
runIndex := ctx.ParamsInt64("run")
534+
artifactName := ctx.Params("artifact_name")
535+
536+
run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
537+
if err != nil {
538+
if errors.Is(err, util.ErrNotExist) {
539+
ctx.Error(http.StatusNotFound, err.Error())
540+
return
541+
}
542+
ctx.Error(http.StatusInternalServerError, err.Error())
543+
return
544+
}
545+
if err = actions_model.SetArtifactNeedDelete(ctx, run.ID, artifactName); err != nil {
546+
ctx.Error(http.StatusInternalServerError, err.Error())
547+
return
548+
}
549+
ctx.JSON(http.StatusOK, struct{}{})
550+
}
551+
527552
func ArtifactsDownloadView(ctx *context_module.Context) {
528553
runIndex := ctx.ParamsInt64("run")
529554
artifactName := ctx.Params("artifact_name")

routers/web/web.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,7 @@ func registerRoutes(m *web.Route) {
13281328
m.Post("/approve", reqRepoActionsWriter, actions.Approve)
13291329
m.Post("/artifacts", actions.ArtifactsView)
13301330
m.Get("/artifacts/{artifact_name}", actions.ArtifactsDownloadView)
1331+
m.Delete("/artifacts/{artifact_name}", actions.ArtifactsDeleteView)
13311332
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
13321333
})
13331334
}, reqRepoActionsReader, actions.MustEnableActions)

web_src/js/components/RepoActionView.vue

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {createApp} from 'vue';
55
import {toggleElem} from '../utils/dom.js';
66
import {getCurrentLocale} from '../utils.js';
77
import {renderAnsi} from '../render/ansi.js';
8-
import {POST} from '../modules/fetch.js';
8+
import {POST,DELETE} from '../modules/fetch.js';
99
1010
const sfc = {
1111
name: 'RepoActionView',
@@ -200,6 +200,14 @@ const sfc = {
200200
return await resp.json();
201201
},
202202
203+
deleteArtifact(name) {
204+
if (!confirm(this.locale.artifactDeleteConfirm)) {
205+
return;
206+
}
207+
let link = this.run.link + '/artifacts/' + name
208+
DELETE(link).then(this.loadJob);
209+
},
210+
203211
async fetchJob() {
204212
const logCursors = this.currentJobStepsStates.map((it, idx) => {
205213
// cursor is used to indicate the last position of the logs
@@ -328,6 +336,7 @@ export function initRepositoryActionView() {
328336
cancel: el.getAttribute('data-locale-cancel'),
329337
rerun: el.getAttribute('data-locale-rerun'),
330338
artifactsTitle: el.getAttribute('data-locale-artifacts-title'),
339+
artifactDeleteConfirm: el.getAttribute('data-locale-artifact-delete-confirm'),
331340
rerun_all: el.getAttribute('data-locale-rerun-all'),
332341
showTimeStamps: el.getAttribute('data-locale-show-timestamps'),
333342
showLogSeconds: el.getAttribute('data-locale-show-log-seconds'),
@@ -403,6 +412,9 @@ export function initRepositoryActionView() {
403412
<a class="job-artifacts-link" target="_blank" :href="run.link+'/artifacts/'+artifact.name">
404413
<SvgIcon name="octicon-file" class="ui text black job-artifacts-icon"/>{{ artifact.name }}
405414
</a>
415+
<a v-if="run.canRerun" @click="deleteArtifact(artifact.name)" class="job-artifacts-delete">
416+
<SvgIcon name="octicon-trash" class="ui text black job-artifacts-icon"/>
417+
</a>
406418
</li>
407419
</ul>
408420
</div>
@@ -527,6 +539,8 @@ export function initRepositoryActionView() {
527539
.job-artifacts-item {
528540
margin: 5px 0;
529541
padding: 6px;
542+
display: flex;
543+
justify-content: space-between;
530544
}
531545
532546
.job-artifacts-list {

web_src/js/svg.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import octiconStrikethrough from '../../public/assets/img/svg/octicon-strikethro
6565
import octiconSync from '../../public/assets/img/svg/octicon-sync.svg';
6666
import octiconTable from '../../public/assets/img/svg/octicon-table.svg';
6767
import octiconTag from '../../public/assets/img/svg/octicon-tag.svg';
68+
import octiconTrash from '../../public/assets/img/svg/octicon-trash.svg';
6869
import octiconTriangleDown from '../../public/assets/img/svg/octicon-triangle-down.svg';
6970
import octiconX from '../../public/assets/img/svg/octicon-x.svg';
7071
import octiconXCircleFill from '../../public/assets/img/svg/octicon-x-circle-fill.svg';
@@ -136,6 +137,7 @@ const svgs = {
136137
'octicon-sync': octiconSync,
137138
'octicon-table': octiconTable,
138139
'octicon-tag': octiconTag,
140+
'octicon-trash': octiconTrash,
139141
'octicon-triangle-down': octiconTriangleDown,
140142
'octicon-x': octiconX,
141143
'octicon-x-circle-fill': octiconXCircleFill,

0 commit comments

Comments
 (0)