mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-28 18:38:29 +00:00
Signed-off-by: RB <7775707+nitrocode@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: RB <7775707+nitrocode@users.noreply.github.com>
178 lines
4.9 KiB
Go
178 lines
4.9 KiB
Go
// Copyright 2017 HootSuite Media Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the License);
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an AS IS BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
// Modified hereafter by contributors to runatlantis/atlantis.
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/google/go-github/v71/github"
|
|
)
|
|
|
|
type GithubClient struct {
|
|
client *github.Client
|
|
username string
|
|
ownerName string
|
|
repoName string
|
|
token string
|
|
}
|
|
|
|
func NewGithubClient() *GithubClient {
|
|
|
|
githubUsername := os.Getenv("ATLANTIS_GH_USER")
|
|
if githubUsername == "" {
|
|
log.Fatalf("ATLANTIS_GH_USER cannot be empty")
|
|
}
|
|
githubToken := os.Getenv("ATLANTIS_GH_TOKEN")
|
|
if githubToken == "" {
|
|
log.Fatalf("ATLANTIS_GH_TOKEN cannot be empty")
|
|
}
|
|
ownerName := os.Getenv("GITHUB_REPO_OWNER_NAME")
|
|
if ownerName == "" {
|
|
ownerName = "runatlantis"
|
|
}
|
|
repoName := os.Getenv("GITHUB_REPO_NAME")
|
|
if repoName == "" {
|
|
repoName = "atlantis-tests"
|
|
}
|
|
|
|
// create github client
|
|
tp := github.BasicAuthTransport{
|
|
Username: strings.TrimSpace(githubUsername),
|
|
Password: strings.TrimSpace(githubToken),
|
|
}
|
|
ghClient := github.NewClient(tp.Client())
|
|
|
|
return &GithubClient{
|
|
client: ghClient,
|
|
username: githubUsername,
|
|
ownerName: ownerName,
|
|
repoName: repoName,
|
|
token: githubToken,
|
|
}
|
|
|
|
}
|
|
|
|
func (g GithubClient) Clone(cloneDir string) error {
|
|
|
|
repoURL := fmt.Sprintf("https://%s:%s@github.com/%s/%s.git", g.username, g.token, g.ownerName, g.repoName)
|
|
cloneCmd := exec.Command("git", "clone", repoURL, cloneDir)
|
|
// git clone the repo
|
|
log.Printf("git cloning into %q", cloneDir)
|
|
if output, err := cloneCmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("failed to clone repository: %v: %s", err, string(output))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g GithubClient) CreateAtlantisWebhook(ctx context.Context, hookURL string) (int64, error) {
|
|
contentType := "json"
|
|
hookConfig := &github.HookConfig{
|
|
ContentType: &contentType,
|
|
URL: &hookURL,
|
|
}
|
|
// create atlantis hook
|
|
atlantisHook := &github.Hook{
|
|
Events: []string{"issue_comment", "pull_request", "push"},
|
|
Config: hookConfig,
|
|
Active: github.Ptr(true),
|
|
}
|
|
|
|
hook, _, err := g.client.Repositories.CreateHook(ctx, g.ownerName, g.repoName, atlantisHook)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
log.Println(hook.GetURL())
|
|
|
|
return hook.GetID(), nil
|
|
}
|
|
|
|
func (g GithubClient) DeleteAtlantisHook(ctx context.Context, hookID int64) error {
|
|
_, err := g.client.Repositories.DeleteHook(ctx, g.ownerName, g.repoName, hookID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Printf("deleted webhook id %d", hookID)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g GithubClient) CreatePullRequest(ctx context.Context, title, branchName string) (string, int, error) {
|
|
head := fmt.Sprintf("%s:%s", g.ownerName, branchName)
|
|
body := ""
|
|
base := "main"
|
|
newPullRequest := &github.NewPullRequest{Title: &title, Head: &head, Body: &body, Base: &base}
|
|
|
|
pull, _, err := g.client.PullRequests.Create(ctx, g.ownerName, g.repoName, newPullRequest)
|
|
if err != nil {
|
|
return "", 0, fmt.Errorf("error while creating new pull request: %v", err)
|
|
}
|
|
|
|
// set pull request url
|
|
return pull.GetHTMLURL(), pull.GetNumber(), nil
|
|
|
|
}
|
|
|
|
func (g GithubClient) GetAtlantisStatus(ctx context.Context, branchName string) (string, error) {
|
|
// check repo status
|
|
combinedStatus, _, err := g.client.Repositories.GetCombinedStatus(ctx, g.ownerName, g.repoName, branchName, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
for _, status := range combinedStatus.Statuses {
|
|
if status.GetContext() == "atlantis/plan" {
|
|
return status.GetState(), nil
|
|
}
|
|
}
|
|
|
|
return "", nil
|
|
}
|
|
|
|
func (g GithubClient) ClosePullRequest(ctx context.Context, pullRequestNumber int) error {
|
|
// clean up
|
|
_, _, err := g.client.PullRequests.Edit(ctx, g.ownerName, g.repoName, pullRequestNumber, &github.PullRequest{State: github.Ptr("closed")})
|
|
if err != nil {
|
|
return fmt.Errorf("error while closing new pull request: %v", err)
|
|
}
|
|
return nil
|
|
|
|
}
|
|
func (g GithubClient) DeleteBranch(ctx context.Context, branchName string) error {
|
|
|
|
deleteBranchName := fmt.Sprintf("%s/%s", "heads", branchName)
|
|
_, err := g.client.Git.DeleteRef(ctx, g.ownerName, g.repoName, deleteBranchName)
|
|
if err != nil {
|
|
return fmt.Errorf("error while deleting branch %s: %v", branchName, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g GithubClient) IsAtlantisInProgress(state string) bool {
|
|
for _, s := range []string{"success", "error", "failure"} {
|
|
if state == s {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (g GithubClient) DidAtlantisSucceed(state string) bool {
|
|
return state == "success"
|
|
}
|