You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

artifact.go 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. // This artifact server is inspired by https://github.com/nektos/act/blob/master/pkg/artifacts/server.go.
  4. // It updates url setting and uses ObjectStore to handle artifacts persistence.
  5. package actions
  6. import (
  7. "context"
  8. "errors"
  9. "code.gitea.io/gitea/models/db"
  10. "code.gitea.io/gitea/modules/timeutil"
  11. "code.gitea.io/gitea/modules/util"
  12. )
  13. const (
  14. // ArtifactStatusUploadPending is the status of an artifact upload that is pending
  15. ArtifactStatusUploadPending = 1
  16. // ArtifactStatusUploadConfirmed is the status of an artifact upload that is confirmed
  17. ArtifactStatusUploadConfirmed = 2
  18. // ArtifactStatusUploadError is the status of an artifact upload that is errored
  19. ArtifactStatusUploadError = 3
  20. )
  21. func init() {
  22. db.RegisterModel(new(ActionArtifact))
  23. }
  24. // ActionArtifact is a file that is stored in the artifact storage.
  25. type ActionArtifact struct {
  26. ID int64 `xorm:"pk autoincr"`
  27. RunID int64 `xorm:"index UNIQUE(runid_name)"` // The run id of the artifact
  28. RunnerID int64
  29. RepoID int64 `xorm:"index"`
  30. OwnerID int64
  31. CommitSHA string
  32. StoragePath string // The path to the artifact in the storage
  33. FileSize int64 // The size of the artifact in bytes
  34. FileCompressedSize int64 // The size of the artifact in bytes after gzip compression
  35. ContentEncoding string // The content encoding of the artifact
  36. ArtifactPath string // The path to the artifact when runner uploads it
  37. ArtifactName string `xorm:"UNIQUE(runid_name)"` // The name of the artifact when runner uploads it
  38. Status int64 `xorm:"index"` // The status of the artifact, uploading, expired or need-delete
  39. CreatedUnix timeutil.TimeStamp `xorm:"created"`
  40. UpdatedUnix timeutil.TimeStamp `xorm:"updated index"`
  41. }
  42. // CreateArtifact create a new artifact with task info or get same named artifact in the same run
  43. func CreateArtifact(ctx context.Context, t *ActionTask, artifactName string) (*ActionArtifact, error) {
  44. if err := t.LoadJob(ctx); err != nil {
  45. return nil, err
  46. }
  47. artifact, err := getArtifactByArtifactName(ctx, t.Job.RunID, artifactName)
  48. if errors.Is(err, util.ErrNotExist) {
  49. artifact := &ActionArtifact{
  50. RunID: t.Job.RunID,
  51. RunnerID: t.RunnerID,
  52. RepoID: t.RepoID,
  53. OwnerID: t.OwnerID,
  54. CommitSHA: t.CommitSHA,
  55. Status: ArtifactStatusUploadPending,
  56. }
  57. if _, err := db.GetEngine(ctx).Insert(artifact); err != nil {
  58. return nil, err
  59. }
  60. return artifact, nil
  61. } else if err != nil {
  62. return nil, err
  63. }
  64. return artifact, nil
  65. }
  66. func getArtifactByArtifactName(ctx context.Context, runID int64, name string) (*ActionArtifact, error) {
  67. var art ActionArtifact
  68. has, err := db.GetEngine(ctx).Where("run_id = ? AND artifact_name = ?", runID, name).Get(&art)
  69. if err != nil {
  70. return nil, err
  71. } else if !has {
  72. return nil, util.ErrNotExist
  73. }
  74. return &art, nil
  75. }
  76. // GetArtifactByID returns an artifact by id
  77. func GetArtifactByID(ctx context.Context, id int64) (*ActionArtifact, error) {
  78. var art ActionArtifact
  79. has, err := db.GetEngine(ctx).ID(id).Get(&art)
  80. if err != nil {
  81. return nil, err
  82. } else if !has {
  83. return nil, util.ErrNotExist
  84. }
  85. return &art, nil
  86. }
  87. // UpdateArtifactByID updates an artifact by id
  88. func UpdateArtifactByID(ctx context.Context, id int64, art *ActionArtifact) error {
  89. art.ID = id
  90. _, err := db.GetEngine(ctx).ID(id).AllCols().Update(art)
  91. return err
  92. }
  93. // ListArtifactsByRunID returns all artifacts of a run
  94. func ListArtifactsByRunID(ctx context.Context, runID int64) ([]*ActionArtifact, error) {
  95. arts := make([]*ActionArtifact, 0, 10)
  96. return arts, db.GetEngine(ctx).Where("run_id=?", runID).Find(&arts)
  97. }
  98. // ListUploadedArtifactsByRunID returns all uploaded artifacts of a run
  99. func ListUploadedArtifactsByRunID(ctx context.Context, runID int64) ([]*ActionArtifact, error) {
  100. arts := make([]*ActionArtifact, 0, 10)
  101. return arts, db.GetEngine(ctx).Where("run_id=? AND status=?", runID, ArtifactStatusUploadConfirmed).Find(&arts)
  102. }
  103. // ListArtifactsByRepoID returns all artifacts of a repo
  104. func ListArtifactsByRepoID(ctx context.Context, repoID int64) ([]*ActionArtifact, error) {
  105. arts := make([]*ActionArtifact, 0, 10)
  106. return arts, db.GetEngine(ctx).Where("repo_id=?", repoID).Find(&arts)
  107. }