rerun_workflow.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package gitinstallation
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/http"
  6. "strings"
  7. "github.com/porter-dev/porter/api/server/handlers"
  8. "github.com/porter-dev/porter/api/server/shared"
  9. "github.com/porter-dev/porter/api/server/shared/apierrors"
  10. "github.com/porter-dev/porter/api/server/shared/commonutils"
  11. "github.com/porter-dev/porter/api/server/shared/config"
  12. )
  13. type RerunWorkflowHandler struct {
  14. handlers.PorterHandlerReadWriter
  15. }
  16. func NewRerunWorkflowHandler(
  17. config *config.Config,
  18. decoderValidator shared.RequestDecoderValidator,
  19. writer shared.ResultWriter,
  20. ) *RerunWorkflowHandler {
  21. return &RerunWorkflowHandler{
  22. PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
  23. }
  24. }
  25. func (c *RerunWorkflowHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  26. owner, name, ok := commonutils.GetOwnerAndNameParams(c, w, r)
  27. if !ok {
  28. return
  29. }
  30. filename := r.URL.Query().Get("filename")
  31. // if branch is empty then the latest workflow run is rerun, meaning that if
  32. // there were multiple workflow runs for the same file but for different branches
  33. // only the very latest of the workflow runs will be rerun
  34. branch := r.URL.Query().Get("branch")
  35. releaseName := r.URL.Query().Get("release_name")
  36. if filename == "" && releaseName == "" {
  37. c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("filename and release name are both empty")))
  38. return
  39. }
  40. if filename == "" {
  41. if c.Config().ServerConf.InstanceName != "" {
  42. filename = fmt.Sprintf("porter_%s_%s.yml", strings.Replace(
  43. strings.ToLower(releaseName), "-", "_", -1),
  44. strings.ToLower(c.Config().ServerConf.InstanceName),
  45. )
  46. } else {
  47. filename = fmt.Sprintf("porter_%s.yml", strings.Replace(
  48. strings.ToLower(releaseName), "-", "_", -1),
  49. )
  50. }
  51. }
  52. client, err := GetGithubAppClientFromRequest(c.Config(), r)
  53. if err != nil {
  54. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  55. return
  56. }
  57. latestWorkflowRun, err := commonutils.GetLatestWorkflowRun(client, owner, name, filename, branch)
  58. if err != nil && errors.Is(err, commonutils.ErrNoWorkflowRuns) {
  59. c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, 400))
  60. return
  61. } else if err != nil && errors.Is(err, commonutils.ErrWorkflowNotFound) {
  62. w.WriteHeader(http.StatusNotFound)
  63. c.WriteResult(w, r, filename)
  64. return
  65. } else if err != nil {
  66. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  67. return
  68. }
  69. if latestWorkflowRun.GetStatus() == "in_progress" || latestWorkflowRun.GetStatus() == "queued" {
  70. w.WriteHeader(409)
  71. c.WriteResult(w, r, latestWorkflowRun.GetHTMLURL())
  72. return
  73. }
  74. _, err = client.Actions.RerunWorkflowByID(r.Context(), owner, name, latestWorkflowRun.GetID())
  75. if err != nil {
  76. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  77. return
  78. }
  79. latestWorkflowRun, err = commonutils.GetLatestWorkflowRun(client, owner, name, filename, branch)
  80. if err != nil {
  81. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  82. return
  83. }
  84. c.WriteResult(w, r, latestWorkflowRun.GetHTMLURL())
  85. }