preview.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package actions
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "strings"
  7. "github.com/google/go-github/v41/github"
  8. "gopkg.in/yaml.v2"
  9. )
  10. type EnvOpts struct {
  11. Client *github.Client
  12. ServerURL string
  13. PorterToken string
  14. GitRepoOwner, GitRepoName string
  15. EnvironmentName string
  16. ProjectID, ClusterID, GitInstallationID uint
  17. }
  18. func SetupEnv(opts *EnvOpts) error {
  19. // make a best-effort to create a Github environment. this is a non-fatal operation,
  20. // as the environments API is not enabled for private repositories that don't have
  21. // github enterprise.
  22. _, resp, err := opts.Client.Repositories.GetEnvironment(
  23. context.Background(),
  24. opts.GitRepoOwner,
  25. opts.GitRepoName,
  26. opts.EnvironmentName,
  27. )
  28. if resp != nil && resp.StatusCode == http.StatusNotFound {
  29. opts.Client.Repositories.CreateUpdateEnvironment(
  30. context.Background(),
  31. opts.GitRepoOwner,
  32. opts.GitRepoName,
  33. opts.EnvironmentName,
  34. nil,
  35. )
  36. }
  37. // create porter token secret
  38. err = createGithubSecret(
  39. opts.Client,
  40. getPorterTokenSecretName(opts.ProjectID),
  41. opts.PorterToken,
  42. opts.GitRepoOwner,
  43. opts.GitRepoName,
  44. )
  45. if err != nil {
  46. return err
  47. }
  48. // get the repository to find the default branch
  49. repo, _, err := opts.Client.Repositories.Get(
  50. context.TODO(),
  51. opts.GitRepoOwner,
  52. opts.GitRepoName,
  53. )
  54. if err != nil {
  55. return err
  56. }
  57. defaultBranch := repo.GetDefaultBranch()
  58. applyWorkflowYAML, err := getPreviewApplyActionYAML(opts)
  59. if err != nil {
  60. return err
  61. }
  62. _, err = commitGithubFile(
  63. opts.Client,
  64. fmt.Sprintf("porter_%s_env.yml", strings.ToLower(opts.EnvironmentName)),
  65. applyWorkflowYAML,
  66. opts.GitRepoOwner,
  67. opts.GitRepoName,
  68. defaultBranch,
  69. false,
  70. )
  71. if err != nil {
  72. return err
  73. }
  74. deleteWorkflowYAML, err := getPreviewDeleteActionYAML(opts)
  75. if err != nil {
  76. return err
  77. }
  78. _, err = commitGithubFile(
  79. opts.Client,
  80. fmt.Sprintf("porter_%s_delete_env.yml", strings.ToLower(opts.EnvironmentName)),
  81. deleteWorkflowYAML,
  82. opts.GitRepoOwner,
  83. opts.GitRepoName,
  84. defaultBranch,
  85. false,
  86. )
  87. if err != nil {
  88. return err
  89. }
  90. return err
  91. }
  92. func DeleteEnv(opts *EnvOpts) error {
  93. // get the repository to find the default branch
  94. repo, _, err := opts.Client.Repositories.Get(
  95. context.TODO(),
  96. opts.GitRepoOwner,
  97. opts.GitRepoName,
  98. )
  99. if err != nil {
  100. return err
  101. }
  102. defaultBranch := repo.GetDefaultBranch()
  103. // delete GitHub Environment: check that environment exists before deletion
  104. _, resp, err := opts.Client.Repositories.GetEnvironment(
  105. context.Background(),
  106. opts.GitRepoOwner,
  107. opts.GitRepoName,
  108. opts.EnvironmentName,
  109. )
  110. if err == nil && resp != nil && resp.StatusCode == http.StatusOK {
  111. _, err = opts.Client.Repositories.DeleteEnvironment(
  112. context.Background(),
  113. opts.GitRepoOwner,
  114. opts.GitRepoName,
  115. opts.EnvironmentName,
  116. )
  117. if err != nil {
  118. return err
  119. }
  120. }
  121. err = deleteGithubFile(
  122. opts.Client,
  123. fmt.Sprintf("porter_%s_env.yml", strings.ToLower(opts.EnvironmentName)),
  124. opts.GitRepoOwner,
  125. opts.GitRepoName,
  126. defaultBranch,
  127. false,
  128. )
  129. if err != nil {
  130. return err
  131. }
  132. return deleteGithubFile(
  133. opts.Client,
  134. fmt.Sprintf("porter_%s_delete_env.yml", strings.ToLower(opts.EnvironmentName)),
  135. opts.GitRepoOwner,
  136. opts.GitRepoName,
  137. defaultBranch,
  138. false,
  139. )
  140. }
  141. func getPreviewApplyActionYAML(opts *EnvOpts) ([]byte, error) {
  142. gaSteps := []GithubActionYAMLStep{
  143. getCheckoutCodeStep(),
  144. getCreatePreviewEnvStep(
  145. opts.ServerURL,
  146. getPorterTokenSecretName(opts.ProjectID),
  147. opts.ProjectID,
  148. opts.ClusterID,
  149. opts.GitInstallationID,
  150. opts.GitRepoName,
  151. "v0.1.0",
  152. ),
  153. }
  154. actionYAML := GithubActionYAML{
  155. On: []string{"pull_request"},
  156. Name: "Porter Preview Environment",
  157. Jobs: map[string]GithubActionYAMLJob{
  158. "porter-preview": {
  159. RunsOn: "ubuntu-latest",
  160. Steps: gaSteps,
  161. },
  162. },
  163. }
  164. return yaml.Marshal(actionYAML)
  165. }
  166. func getPreviewDeleteActionYAML(opts *EnvOpts) ([]byte, error) {
  167. gaSteps := []GithubActionYAMLStep{
  168. getDeletePreviewEnvStep(
  169. opts.ServerURL,
  170. getPorterTokenSecretName(opts.ProjectID),
  171. opts.ProjectID,
  172. opts.ClusterID,
  173. opts.GitInstallationID,
  174. opts.GitRepoName,
  175. "v0.1.0",
  176. ),
  177. }
  178. actionYAML := GithubActionYAML{
  179. On: map[string]interface{}{
  180. "pull_request": map[string]interface{}{
  181. "types": []string{"closed"},
  182. },
  183. },
  184. Name: "Porter Preview Environment",
  185. Jobs: map[string]GithubActionYAMLJob{
  186. "porter-delete-preview": {
  187. RunsOn: "ubuntu-latest",
  188. Steps: gaSteps,
  189. },
  190. },
  191. }
  192. return yaml.Marshal(actionYAML)
  193. }