diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f1d820fceb..1f3032868e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -139,3 +139,40 @@ jobs: - run: | make build-service ./scripts/e2e.sh + e2e-gitlab: + runs-on: ubuntu-latest + # dont run e2e tests on forked PRs + if: github.event.pull_request.head.repo.fork == false + env: + TERRAFORM_VERSION: 1.9.2 + ATLANTIS_GITLAB_USER: ${{ secrets.ATLANTISBOT_GITLAB_USERNAME }} + ATLANTIS_GITLAB_TOKEN: ${{ secrets.ATLANTISBOT_GITLAB_TOKEN }} + NGROK_AUTH_TOKEN: ${{ secrets.ATLANTISBOT_NGROK_AUTH_TOKEN }} + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5 + with: + go-version-file: go.mod + + # This version of TF will be downloaded before Atlantis is started. + # We do this instead of setting --default-tf-version because setting + # that flag starts the download asynchronously so we'd have a race + # condition. + - uses: hashicorp/setup-terraform@651471c36a6092792c552e8b1bef71e592b462d8 # v3 + with: + terraform_version: ${{ env.TERRAFORM_VERSION }} + + - name: Setup ngrok + run: | + wget -q -O ngrok.tar.gz https://bin.equinox.io/a/4no1PS1PoRF/ngrok-v3-3.13.0-linux-amd64.tar.gz + tar -xzf ngrok.tar.gz + chmod +x ngrok + ./ngrok version + - name: Setup gitconfig + run: | + git config --global user.email "maintainers@runatlantis.io" + git config --global user.name "atlantisbot" + + - run: | + make build-service + ./scripts/e2e.sh diff --git a/e2e/e2e.go b/e2e/e2e.go index 5c19d501b0..b1be0e5e7d 100644 --- a/e2e/e2e.go +++ b/e2e/e2e.go @@ -147,7 +147,7 @@ func (t *E2ETester) Start(ctx context.Context) (*E2EResult, error) { } func checkStatus(state string) bool { - for _, s := range []string{"success", "error", "failure"} { + for _, s := range []string{"success", "error", "failure", "failed"} { if state == s { return false } @@ -155,20 +155,20 @@ func checkStatus(state string) bool { return true } -func cleanUp(ctx context.Context, t *E2ETester, pullRequestNumber int, branchName string) error { +func cleanUp(ctx context.Context, t *E2ETester, pullRequestNumber int, branchName string) { // clean up err := t.vcsClient.ClosePullRequest(ctx, pullRequestNumber) if err != nil { - return err + log.Printf("Failed to close PR %d: %v", pullRequestNumber, err) + return } log.Printf("closed pull request %d", pullRequestNumber) - deleteBranchName := fmt.Sprintf("%s/%s", "heads", branchName) - err = t.vcsClient.DeleteBranch(ctx, deleteBranchName) + err = t.vcsClient.DeleteBranch(ctx, branchName) if err != nil { - return fmt.Errorf("error while deleting branch %s: %v", deleteBranchName, err) + log.Printf("Failed to delete branch %s: %v", branchName, err) + return } - log.Printf("deleted branch %s", deleteBranchName) + log.Printf("deleted branch %s", branchName) - return nil } diff --git a/e2e/github.go b/e2e/github.go index 40b64f7efd..6f2eb7b454 100644 --- a/e2e/github.go +++ b/e2e/github.go @@ -153,7 +153,9 @@ func (g GithubClient) ClosePullRequest(ctx context.Context, pullRequestNumber in } func (g GithubClient) DeleteBranch(ctx context.Context, branchName string) error { - _, err := g.client.Git.DeleteRef(ctx, g.ownerName, g.repoName, branchName) + 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) } diff --git a/e2e/gitlab.go b/e2e/gitlab.go index e4bd940cb3..2c131374c3 100644 --- a/e2e/gitlab.go +++ b/e2e/gitlab.go @@ -24,12 +24,13 @@ import ( ) type GitlabClient struct { - client *gitlab.Client - username string - ownerName string - repoName string - token string - projectId int + client *gitlab.Client + username string + ownerName string + repoName string + token string + projectId int + branchToMR map[string]int } func NewGitlabClient() *GitlabClient { @@ -61,12 +62,13 @@ func NewGitlabClient() *GitlabClient { } return &GitlabClient{ - client: gitlabClient, - username: gitlabUsername, - ownerName: ownerName, - repoName: repoName, - token: gitlabToken, - projectId: project.ID, + client: gitlabClient, + username: gitlabUsername, + ownerName: ownerName, + repoName: repoName, + token: gitlabToken, + projectId: project.ID, + branchToMR: make(map[string]int), } } @@ -107,53 +109,44 @@ func (g GitlabClient) DeleteAtlantisHook(ctx context.Context, hookID int64) erro return nil } -func (g GitlabClient) CreatePullRequest(ctx context.Context, title, branchName string) (string, PullRequest, error) { +func (g GitlabClient) CreatePullRequest(ctx context.Context, title, branchName string) (string, int, error) { + // log.Printf("Sleeping 10 seconds to prevent race conditions creating MR") + // time.Sleep(time.Second * 10) mr, _, err := g.client.MergeRequests.CreateMergeRequest(g.projectId, &gitlab.CreateMergeRequestOptions{ Title: gitlab.Ptr(title), SourceBranch: gitlab.Ptr(branchName), TargetBranch: gitlab.Ptr("main"), }) if err != nil { - return "", PullRequest{}, fmt.Errorf("error while creating new pull request: %v", err) + return "", 0, fmt.Errorf("error while creating new pull request: %v", err) } - return mr.WebURL, PullRequest{ - id: mr.IID, - branch: branchName, - }, nil + g.branchToMR[branchName] = mr.IID + return mr.WebURL, mr.IID, nil } -func (g GitlabClient) GetAtlantisStatus(ctx context.Context, pullRequest PullRequest) (string, error) { +func (g GitlabClient) GetAtlantisStatus(ctx context.Context, branchName string) (string, error) { - fmt.Println(pullRequest) - res, _, err := g.client.MergeRequests.ListMergeRequestPipelines(g.projectId, pullRequest.id) + pipelineInfos, _, err := g.client.MergeRequests.ListMergeRequestPipelines(g.projectId, g.branchToMR[branchName]) + if err != nil { + return "", err + } + // Possible todo: determine which status in the pipeline we care about? + if len(pipelineInfos) != 1 { + return "", fmt.Errorf("unexpected pipelines: %d", len(pipelineInfos)) + } + pipelineInfo := pipelineInfos[0] + pipeline, _, err := g.client.Pipelines.GetPipeline(g.projectId, pipelineInfo.ID) if err != nil { - fmt.Println("I have error", err) return "", err } - fmt.Println(res) - return "", nil - /* - - // 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 - */ + return pipeline.Status, nil } -func (g GitlabClient) ClosePullRequest(ctx context.Context, pullRequest PullRequest) error { +func (g GitlabClient) ClosePullRequest(ctx context.Context, pullRequestNumber int) error { // clean up - _, _, err := g.client.MergeRequests.UpdateMergeRequest(g.projectId, pullRequest.id, &gitlab.UpdateMergeRequestOptions{ + _, _, err := g.client.MergeRequests.UpdateMergeRequest(g.projectId, pullRequestNumber, &gitlab.UpdateMergeRequestOptions{ StateEvent: gitlab.Ptr("close"), }) if err != nil { @@ -163,13 +156,11 @@ func (g GitlabClient) ClosePullRequest(ctx context.Context, pullRequest PullRequ } func (g GitlabClient) DeleteBranch(ctx context.Context, branchName string) error { - panic("I'mdeleting branch") - /* - - _, err := g.client.Git.DeleteRef(ctx, g.ownerName, g.repoName, branchName) - if err != nil { - return fmt.Errorf("error while deleting branch %s: %v", branchName, err) - } - return nil - */ + _, err := g.client.Branches.DeleteBranch(g.projectId, branchName) + + if err != nil { + return fmt.Errorf("error while deleting branch %s: %v", branchName, err) + } + return nil + } diff --git a/scripts/e2e.sh b/scripts/e2e.sh index cd8e043ad2..56d1caced3 100755 --- a/scripts/e2e.sh +++ b/scripts/e2e.sh @@ -11,7 +11,7 @@ IFS=$'\n\t' --gitlab-token="$ATLANTISBOT_GITLAB_TOKEN" \ --data-dir="/tmp" \ --log-level="debug" \ - --repo-allowlist="github.com/runatlantis/atlantis-tests" \ + --repo-allowlist="github.com/runatlantis/atlantis-tests,gitlab.com/run-atlantis/atlantis-tests" \ --repo-config-json='{"repos":[{"id":"/.*/", "allowed_overrides":["apply_requirements","workflow"], "allow_custom_workflows":true}]}' \ &> /tmp/atlantis-server.log & sleep 2