mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-29 20:13:27 +00:00
123 lines
4.4 KiB
Go
123 lines
4.4 KiB
Go
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||
|
// SPDX-License-Identifier: MIT
|
||
|
|
||
|
// This artifact server is inspired by https://github.com/nektos/act/blob/master/pkg/artifacts/server.go.
|
||
|
// It updates url setting and uses ObjectStore to handle artifacts persistence.
|
||
|
|
||
|
package actions
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
|
||
|
"code.gitea.io/gitea/models/db"
|
||
|
"code.gitea.io/gitea/modules/timeutil"
|
||
|
"code.gitea.io/gitea/modules/util"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// ArtifactStatusUploadPending is the status of an artifact upload that is pending
|
||
|
ArtifactStatusUploadPending = 1
|
||
|
// ArtifactStatusUploadConfirmed is the status of an artifact upload that is confirmed
|
||
|
ArtifactStatusUploadConfirmed = 2
|
||
|
// ArtifactStatusUploadError is the status of an artifact upload that is errored
|
||
|
ArtifactStatusUploadError = 3
|
||
|
)
|
||
|
|
||
|
func init() {
|
||
|
db.RegisterModel(new(ActionArtifact))
|
||
|
}
|
||
|
|
||
|
// ActionArtifact is a file that is stored in the artifact storage.
|
||
|
type ActionArtifact struct {
|
||
|
ID int64 `xorm:"pk autoincr"`
|
||
|
RunID int64 `xorm:"index UNIQUE(runid_name)"` // The run id of the artifact
|
||
|
RunnerID int64
|
||
|
RepoID int64 `xorm:"index"`
|
||
|
OwnerID int64
|
||
|
CommitSHA string
|
||
|
StoragePath string // The path to the artifact in the storage
|
||
|
FileSize int64 // The size of the artifact in bytes
|
||
|
FileCompressedSize int64 // The size of the artifact in bytes after gzip compression
|
||
|
ContentEncoding string // The content encoding of the artifact
|
||
|
ArtifactPath string // The path to the artifact when runner uploads it
|
||
|
ArtifactName string `xorm:"UNIQUE(runid_name)"` // The name of the artifact when runner uploads it
|
||
|
Status int64 `xorm:"index"` // The status of the artifact, uploading, expired or need-delete
|
||
|
CreatedUnix timeutil.TimeStamp `xorm:"created"`
|
||
|
UpdatedUnix timeutil.TimeStamp `xorm:"updated index"`
|
||
|
}
|
||
|
|
||
|
// CreateArtifact create a new artifact with task info or get same named artifact in the same run
|
||
|
func CreateArtifact(ctx context.Context, t *ActionTask, artifactName string) (*ActionArtifact, error) {
|
||
|
if err := t.LoadJob(ctx); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
artifact, err := getArtifactByArtifactName(ctx, t.Job.RunID, artifactName)
|
||
|
if errors.Is(err, util.ErrNotExist) {
|
||
|
artifact := &ActionArtifact{
|
||
|
RunID: t.Job.RunID,
|
||
|
RunnerID: t.RunnerID,
|
||
|
RepoID: t.RepoID,
|
||
|
OwnerID: t.OwnerID,
|
||
|
CommitSHA: t.CommitSHA,
|
||
|
Status: ArtifactStatusUploadPending,
|
||
|
}
|
||
|
if _, err := db.GetEngine(ctx).Insert(artifact); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return artifact, nil
|
||
|
} else if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return artifact, nil
|
||
|
}
|
||
|
|
||
|
func getArtifactByArtifactName(ctx context.Context, runID int64, name string) (*ActionArtifact, error) {
|
||
|
var art ActionArtifact
|
||
|
has, err := db.GetEngine(ctx).Where("run_id = ? AND artifact_name = ?", runID, name).Get(&art)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
} else if !has {
|
||
|
return nil, util.ErrNotExist
|
||
|
}
|
||
|
return &art, nil
|
||
|
}
|
||
|
|
||
|
// GetArtifactByID returns an artifact by id
|
||
|
func GetArtifactByID(ctx context.Context, id int64) (*ActionArtifact, error) {
|
||
|
var art ActionArtifact
|
||
|
has, err := db.GetEngine(ctx).ID(id).Get(&art)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
} else if !has {
|
||
|
return nil, util.ErrNotExist
|
||
|
}
|
||
|
|
||
|
return &art, nil
|
||
|
}
|
||
|
|
||
|
// UpdateArtifactByID updates an artifact by id
|
||
|
func UpdateArtifactByID(ctx context.Context, id int64, art *ActionArtifact) error {
|
||
|
art.ID = id
|
||
|
_, err := db.GetEngine(ctx).ID(id).AllCols().Update(art)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// ListArtifactsByRunID returns all artifacts of a run
|
||
|
func ListArtifactsByRunID(ctx context.Context, runID int64) ([]*ActionArtifact, error) {
|
||
|
arts := make([]*ActionArtifact, 0, 10)
|
||
|
return arts, db.GetEngine(ctx).Where("run_id=?", runID).Find(&arts)
|
||
|
}
|
||
|
|
||
|
// ListUploadedArtifactsByRunID returns all uploaded artifacts of a run
|
||
|
func ListUploadedArtifactsByRunID(ctx context.Context, runID int64) ([]*ActionArtifact, error) {
|
||
|
arts := make([]*ActionArtifact, 0, 10)
|
||
|
return arts, db.GetEngine(ctx).Where("run_id=? AND status=?", runID, ArtifactStatusUploadConfirmed).Find(&arts)
|
||
|
}
|
||
|
|
||
|
// ListArtifactsByRepoID returns all artifacts of a repo
|
||
|
func ListArtifactsByRepoID(ctx context.Context, repoID int64) ([]*ActionArtifact, error) {
|
||
|
arts := make([]*ActionArtifact, 0, 10)
|
||
|
return arts, db.GetEngine(ctx).Where("repo_id=?", repoID).Find(&arts)
|
||
|
}
|