stack.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package actions
  2. import (
  3. "context"
  4. "fmt"
  5. "strings"
  6. "github.com/google/go-github/v41/github"
  7. "gopkg.in/yaml.v2"
  8. )
  9. type GithubPROpts struct {
  10. Client *github.Client
  11. GitRepoOwner, GitRepoName string
  12. ApplyWorkflowYAML string
  13. StackName string
  14. ProjectID, ClusterID uint
  15. PorterToken string
  16. ServerURL string
  17. }
  18. type GetStackApplyActionYAMLOpts struct {
  19. ServerURL string
  20. StackName string
  21. ProjectID, ClusterID uint
  22. DefaultBranch string
  23. SecretName string
  24. }
  25. func OpenGithubPR(opts *GithubPROpts) error {
  26. // create porter secret
  27. secretName := fmt.Sprintf("PORTER_STACK_%d_%d", opts.ProjectID, opts.ClusterID)
  28. err := createGithubSecret(
  29. opts.Client,
  30. secretName,
  31. opts.PorterToken,
  32. opts.GitRepoOwner,
  33. opts.GitRepoName,
  34. )
  35. if err != nil {
  36. return err
  37. }
  38. // get the repository to find the default branch
  39. repo, _, err := opts.Client.Repositories.Get(
  40. context.TODO(),
  41. opts.GitRepoOwner,
  42. opts.GitRepoName,
  43. )
  44. if err != nil {
  45. return err
  46. }
  47. defaultBranch := repo.GetDefaultBranch()
  48. applyWorkflowYAML, err := getStackApplyActionYAML(&GetStackApplyActionYAMLOpts{
  49. ServerURL: opts.ServerURL,
  50. ClusterID: opts.ClusterID,
  51. ProjectID: opts.ProjectID,
  52. StackName: opts.StackName,
  53. DefaultBranch: defaultBranch,
  54. SecretName: secretName,
  55. })
  56. if err != nil {
  57. return err
  58. }
  59. err = createNewBranch(opts.Client,
  60. opts.GitRepoOwner,
  61. opts.GitRepoName,
  62. defaultBranch,
  63. "porter-stack")
  64. if err != nil {
  65. return fmt.Errorf(
  66. "Unable to create PR to merge workflow files into protected branch: %s.\n"+
  67. "To enable Porter Preview Environment deployments, please create Github workflow "+
  68. "files in this branch with the following contents:\n"+
  69. "--------\n%s--------\nERROR: %w",
  70. defaultBranch, string(applyWorkflowYAML), ErrCreatePRForProtectedBranch,
  71. )
  72. }
  73. _, err = commitWorkflowFile(
  74. opts.Client,
  75. fmt.Sprintf("porter_stack_%s.yml", strings.ToLower(opts.StackName)),
  76. applyWorkflowYAML, opts.GitRepoOwner,
  77. opts.GitRepoName, "porter-preview", false,
  78. )
  79. if err != nil {
  80. return fmt.Errorf(
  81. "Unable to create PR to merge workflow files into protected branch: %s.\n"+
  82. "To enable Porter Preview Environment deployments, please create Github workflow "+
  83. "files in this branch with the following contents:\n"+
  84. "--------\n%s--------\nERROR: %w",
  85. defaultBranch, string(applyWorkflowYAML), ErrCreatePRForProtectedBranch,
  86. )
  87. }
  88. _, _, err = opts.Client.PullRequests.Create(
  89. context.Background(), opts.GitRepoOwner, opts.GitRepoName, &github.NewPullRequest{
  90. Title: github.String("Enable Porter Preview Environment deployments"),
  91. Base: github.String(defaultBranch),
  92. Head: github.String("porter-preview"),
  93. },
  94. )
  95. if err != nil {
  96. return err
  97. }
  98. return nil
  99. }
  100. func getStackApplyActionYAML(opts *GetStackApplyActionYAMLOpts) ([]byte, error) {
  101. gaSteps := []GithubActionYAMLStep{
  102. getCheckoutCodeStep(),
  103. getSetTagStep(),
  104. getDeployStackStep(
  105. opts.ServerURL,
  106. opts.SecretName,
  107. opts.StackName,
  108. "v0.1.0",
  109. opts.ProjectID,
  110. opts.ClusterID,
  111. ),
  112. }
  113. actionYAML := GithubActionYAML{
  114. On: GithubActionYAMLOnPush{
  115. Push: GithubActionYAMLOnPushBranches{
  116. Branches: []string{
  117. opts.DefaultBranch,
  118. },
  119. },
  120. },
  121. Name: "Deploy to Porter",
  122. Jobs: map[string]GithubActionYAMLJob{
  123. "porter-deploy": {
  124. RunsOn: "ubuntu-latest",
  125. Steps: gaSteps,
  126. },
  127. },
  128. }
  129. return yaml.Marshal(actionYAML)
  130. }