Skip to content

Commit 1e241b4

Browse files
Tmanocheclaude
andcommitted
Merge upstream runatlantis/atlantis main branch
Merged 7 commits from upstream, keeping fork's ECR-only workflow setup. Upstream changes included: - VCS package cleanup and file renames - Dependency updates (GitHub Actions, Docker digests) - Code improvements in server and events packages Conflict resolution: - Kept fork's customized atlantis-image.yml for ECR builds - Removed restored upstream workflow files (codeql, lint, test, etc.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2 parents 210c588 + 442130a commit 1e241b4

82 files changed

Lines changed: 599 additions & 707 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cmd/server_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ func TestExecute_ValidateVCSConfig(t *testing.T) {
620620
{
621621
"just github app key set",
622622
map[string]interface{}{
623-
GHAppKeyFlag: githubtestdata.GithubPrivateKey,
623+
GHAppKeyFlag: githubtestdata.PrivateKey,
624624
},
625625
true,
626626
},
@@ -730,7 +730,7 @@ func TestExecute_ValidateVCSConfig(t *testing.T) {
730730
"github app and key set and should be successful",
731731
map[string]interface{}{
732732
GHAppIDFlag: "1",
733-
GHAppKeyFlag: githubtestdata.GithubPrivateKey,
733+
GHAppKeyFlag: githubtestdata.PrivateKey,
734734
},
735735
false,
736736
},
@@ -867,7 +867,7 @@ func TestExecute_GithubUser(t *testing.T) {
867867
func TestExecute_GithubApp(t *testing.T) {
868868
t.Log("Should remove the @ from the github username if it's passed.")
869869
c := setup(map[string]interface{}{
870-
GHAppKeyFlag: githubtestdata.GithubPrivateKey,
870+
GHAppKeyFlag: githubtestdata.PrivateKey,
871871
GHAppIDFlag: "1",
872872
RepoAllowlistFlag: "*",
873873
}, t)
@@ -880,7 +880,7 @@ func TestExecute_GithubApp(t *testing.T) {
880880
func TestExecute_GithubAppWithInstallationID(t *testing.T) {
881881
t.Log("Should pass the installation ID to the config.")
882882
c := setup(map[string]interface{}{
883-
GHAppKeyFlag: githubtestdata.GithubPrivateKey,
883+
GHAppKeyFlag: githubtestdata.PrivateKey,
884884
GHAppIDFlag: "1",
885885
GHAppInstallationIDFlag: "2",
886886
RepoAllowlistFlag: "*",

server/controllers/events/events_controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ func (e *VCSEventsController) handleBitbucketCloudPost(w http.ResponseWriter, r
232232
return
233233
}
234234
if len(e.BitbucketWebhookSecret) > 0 {
235-
if err := bitbucketcloud.ValidateSignature(body, sig, e.BitbucketWebhookSecret); err != nil {
235+
if err := common.ValidateSignature(body, sig, e.BitbucketWebhookSecret); err != nil {
236236
e.respond(w, logging.Warn, http.StatusBadRequest, "%s", fmt.Errorf("request did not pass validation: %w", err).Error())
237237
return
238238
}
@@ -268,7 +268,7 @@ func (e *VCSEventsController) handleBitbucketServerPost(w http.ResponseWriter, r
268268
return
269269
}
270270
if len(e.BitbucketWebhookSecret) > 0 {
271-
if err := bitbucketserver.ValidateSignature(body, sig, e.BitbucketWebhookSecret); err != nil {
271+
if err := common.ValidateSignature(body, sig, e.BitbucketWebhookSecret); err != nil {
272272
e.respond(w, logging.Warn, http.StatusBadRequest, "%s", fmt.Errorf("request did not pass validation: %w", err).Error())
273273
return
274274
}

server/controllers/github_app_controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ func (g *GithubAppController) ExchangeCode(w http.ResponseWriter, r *http.Reques
5757
}
5858

5959
g.Logger.Debug("Exchanging GitHub app code for app credentials")
60-
creds := &github.GithubAnonymousCredentials{}
61-
config := github.GithubConfig{}
60+
creds := &github.AnonymousCredentials{}
61+
config := github.Config{}
6262
// This client does not post comments, so we don't need to configure it with maxCommentsPerCommand.
63-
client, err := github.NewGithubClient(g.GithubHostname, creds, config, 0, g.Logger)
63+
client, err := github.New(g.GithubHostname, creds, config, 0, g.Logger)
6464
if err != nil {
6565
g.respond(w, logging.Error, http.StatusInternalServerError, "Failed to exchange code for github app: %s", err)
6666
return

server/events/command_runner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ type DefaultCommandRunner struct {
9898
GithubPullGetter GithubPullGetter
9999
AzureDevopsPullGetter AzureDevopsPullGetter
100100
GitlabMergeRequestGetter GitlabMergeRequestGetter
101-
GiteaPullGetter *gitea.GiteaClient
101+
GiteaPullGetter *gitea.Client
102102
// User config option: Disables autoplan when a pull request is opened or updated.
103103
DisableAutoplan bool
104104
DisableAutoplanLabel string

server/events/github_app_working_dir.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const redactedReplacement = "://:<redacted>@"
1818
// before every clone, given Github App tokens expire quickly
1919
type GithubAppWorkingDir struct {
2020
WorkingDir
21-
Credentials github.GithubCredentials
21+
Credentials github.Credentials
2222
GithubHostname string
2323
}
2424

server/events/github_app_working_dir_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ func TestClone_GithubAppNoneExisting(t *testing.T) {
4040

4141
gwd := &events.GithubAppWorkingDir{
4242
WorkingDir: wd,
43-
Credentials: &github.GithubAppCredentials{
44-
Key: []byte(githubtestdata.GithubPrivateKey),
43+
Credentials: &github.AppCredentials{
44+
Key: []byte(githubtestdata.PrivateKey),
4545
AppID: 1,
4646
Hostname: testServer,
4747
},
@@ -66,7 +66,7 @@ func TestClone_GithubAppSetsCorrectUrl(t *testing.T) {
6666

6767
workingDir := eventMocks.NewMockWorkingDir()
6868

69-
credentials := githubMocks.NewMockGithubCredentials()
69+
credentials := githubMocks.NewMockCredentials()
7070

7171
ghAppWorkingDir := events.GithubAppWorkingDir{
7272
WorkingDir: workingDir,
@@ -111,7 +111,7 @@ func TestMergeAgain_GithubAppSetsCorrectUrl(t *testing.T) {
111111

112112
workingDir := eventMocks.NewMockWorkingDir()
113113

114-
credentials := githubMocks.NewMockGithubCredentials()
114+
credentials := githubMocks.NewMockCredentials()
115115

116116
ghAppWorkingDir := events.GithubAppWorkingDir{
117117
WorkingDir: workingDir,

server/events/project_locker_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
)
3030

3131
func TestDefaultProjectLocker_TryLockWhenLocked(t *testing.T) {
32-
var githubClient *github.GithubClient
32+
var githubClient *github.Client
3333
mockClient := vcs.NewClientProxy(githubClient, nil, nil, nil, nil, nil)
3434
mockLocker := mocks.NewMockLocker()
3535
locker := events.DefaultProjectLocker{
@@ -65,7 +65,7 @@ func TestDefaultProjectLocker_TryLockWhenLocked(t *testing.T) {
6565

6666
func TestDefaultProjectLocker_TryLockWhenLockedSamePull(t *testing.T) {
6767
RegisterMockTestingT(t)
68-
var githubClient *github.GithubClient
68+
var githubClient *github.Client
6969
mockClient := vcs.NewClientProxy(githubClient, nil, nil, nil, nil, nil)
7070
mockLocker := mocks.NewMockLocker()
7171
locker := events.DefaultProjectLocker{
@@ -104,7 +104,7 @@ func TestDefaultProjectLocker_TryLockWhenLockedSamePull(t *testing.T) {
104104

105105
func TestDefaultProjectLocker_TryLockUnlocked(t *testing.T) {
106106
RegisterMockTestingT(t)
107-
var githubClient *github.GithubClient
107+
var githubClient *github.Client
108108
mockClient := vcs.NewClientProxy(githubClient, nil, nil, nil, nil, nil)
109109
mockLocker := mocks.NewMockLocker()
110110
locker := events.DefaultProjectLocker{
@@ -142,7 +142,7 @@ func TestDefaultProjectLocker_TryLockUnlocked(t *testing.T) {
142142
}
143143

144144
func TestDefaultProjectLocker_RepoLocking(t *testing.T) {
145-
var githubClient *github.GithubClient
145+
var githubClient *github.Client
146146
mockClient := vcs.NewClientProxy(githubClient, nil, nil, nil, nil, nil)
147147
expProject := models.Project{}
148148
expWorkspace := "default"

server/events/vcs/azuredevops/azuredevops_client.go renamed to server/events/vcs/azuredevops/client.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ import (
1919
"github.com/runatlantis/atlantis/server/logging"
2020
)
2121

22-
// AzureDevopsClient represents an Azure DevOps VCS client
23-
type AzureDevopsClient struct {
22+
// Client represents an Azure DevOps VCS client
23+
type Client struct {
2424
Client *azuredevops.Client
2525
ctx context.Context
2626
UserName string
2727
}
2828

29-
// NewAzureDevopsClient returns a valid Azure DevOps client.
30-
func NewAzureDevopsClient(hostname string, userName string, token string) (*AzureDevopsClient, error) {
29+
// NewClient returns a valid Azure DevOps client.
30+
func New(hostname string, userName string, token string) (*Client, error) {
3131
tp := azuredevops.BasicAuthTransport{
3232
Username: "",
3333
Password: strings.TrimSpace(token),
@@ -48,7 +48,7 @@ func NewAzureDevopsClient(hostname string, userName string, token string) (*Azur
4848
adClient.BaseURL = *base
4949
}
5050

51-
client := &AzureDevopsClient{
51+
client := &Client{
5252
Client: adClient,
5353
UserName: userName,
5454
ctx: context.Background(),
@@ -59,7 +59,7 @@ func NewAzureDevopsClient(hostname string, userName string, token string) (*Azur
5959

6060
// GetModifiedFiles returns the names of files that were modified in the merge request
6161
// relative to the repo root, e.g. parent/child/file.txt.
62-
func (g *AzureDevopsClient) GetModifiedFiles(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest) ([]string, error) {
62+
func (g *Client) GetModifiedFiles(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest) ([]string, error) {
6363
var files []string
6464

6565
owner, project, repoName := SplitAzureDevopsRepoFullName(repo.FullName)
@@ -114,7 +114,7 @@ func (g *AzureDevopsClient) GetModifiedFiles(logger logging.SimpleLogging, repo
114114
//
115115
// If comment length is greater than the max comment length we split into
116116
// multiple comments.
117-
func (g *AzureDevopsClient) CreateComment(logger logging.SimpleLogging, repo models.Repo, pullNum int, comment string, command string) error { //nolint: revive
117+
func (g *Client) CreateComment(logger logging.SimpleLogging, repo models.Repo, pullNum int, comment string, command string) error { //nolint: revive
118118
sepEnd := "\n```\n</details>" +
119119
"\n<br>\n\n**Warning**: Output length greater than max comment size. Continued in next comment."
120120
sepStart := "Continued from previous comment.\n<details><summary>Show Output</summary>\n\n" +
@@ -149,17 +149,17 @@ func (g *AzureDevopsClient) CreateComment(logger logging.SimpleLogging, repo mod
149149
return nil
150150
}
151151

152-
func (g *AzureDevopsClient) ReactToComment(logger logging.SimpleLogging, repo models.Repo, pullNum int, commentID int64, reaction string) error { //nolint: revive
152+
func (g *Client) ReactToComment(logger logging.SimpleLogging, repo models.Repo, pullNum int, commentID int64, reaction string) error { //nolint: revive
153153
return nil
154154
}
155155

156-
func (g *AzureDevopsClient) HidePrevCommandComments(logger logging.SimpleLogging, repo models.Repo, pullNum int, command string, dir string) error { //nolint: revive
156+
func (g *Client) HidePrevCommandComments(logger logging.SimpleLogging, repo models.Repo, pullNum int, command string, dir string) error { //nolint: revive
157157
return nil
158158
}
159159

160160
// PullIsApproved returns true if the merge request was approved by another reviewer.
161161
// https://docs.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops#require-a-minimum-number-of-reviewers
162-
func (g *AzureDevopsClient) PullIsApproved(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest) (approvalStatus models.ApprovalStatus, err error) {
162+
func (g *Client) PullIsApproved(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest) (approvalStatus models.ApprovalStatus, err error) {
163163
owner, project, repoName := SplitAzureDevopsRepoFullName(repo.FullName)
164164

165165
opts := azuredevops.PullRequestGetOptions{
@@ -189,13 +189,13 @@ func (g *AzureDevopsClient) PullIsApproved(logger logging.SimpleLogging, repo mo
189189
return approvalStatus, nil
190190
}
191191

192-
func (g *AzureDevopsClient) DiscardReviews(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest) error { //nolint: revive
192+
func (g *Client) DiscardReviews(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest) error { //nolint: revive
193193
// TODO implement
194194
return nil
195195
}
196196

197197
// PullIsMergeable returns true if the merge request can be merged.
198-
func (g *AzureDevopsClient) PullIsMergeable(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, _ string, _ []string) (models.MergeableStatus, error) { //nolint: revive
198+
func (g *Client) PullIsMergeable(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, _ string, _ []string) (models.MergeableStatus, error) { //nolint: revive
199199
owner, project, repoName := SplitAzureDevopsRepoFullName(repo.FullName)
200200

201201
opts := azuredevops.PullRequestGetOptions{IncludeWorkItemRefs: true}
@@ -256,7 +256,7 @@ func (g *AzureDevopsClient) PullIsMergeable(logger logging.SimpleLogging, repo m
256256
}
257257

258258
// GetPullRequest returns the pull request.
259-
func (g *AzureDevopsClient) GetPullRequest(logger logging.SimpleLogging, repo models.Repo, num int) (*azuredevops.GitPullRequest, error) {
259+
func (g *Client) GetPullRequest(logger logging.SimpleLogging, repo models.Repo, num int) (*azuredevops.GitPullRequest, error) {
260260
opts := azuredevops.PullRequestGetOptions{
261261
IncludeWorkItemRefs: true,
262262
}
@@ -266,7 +266,7 @@ func (g *AzureDevopsClient) GetPullRequest(logger logging.SimpleLogging, repo mo
266266
}
267267

268268
// UpdateStatus updates the build status of a commit.
269-
func (g *AzureDevopsClient) UpdateStatus(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, state models.CommitStatus, src string, description string, url string) error {
269+
func (g *Client) UpdateStatus(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, state models.CommitStatus, src string, description string, url string) error {
270270
adState := azuredevops.GitError.String()
271271
switch state {
272272
case models.PendingCommitStatus:
@@ -280,7 +280,7 @@ func (g *AzureDevopsClient) UpdateStatus(logger logging.SimpleLogging, repo mode
280280
logger.Info("Updating Azure DevOps commit status for '%s' to '%s'", src, adState)
281281

282282
status := azuredevops.GitPullRequestStatus{}
283-
status.Context = GitStatusContextFromSrc(src)
283+
status.Context = gitStatusContextFromSrc(src)
284284
status.Description = &description
285285
status.State = &adState
286286
if url != "" {
@@ -334,7 +334,7 @@ func (g *AzureDevopsClient) UpdateStatus(logger logging.SimpleLogging, repo mode
334334
// If the user has set a branch policy that disallows no fast-forward, the merge will fail
335335
// until we handle branch policies
336336
// https://docs.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops
337-
func (g *AzureDevopsClient) MergePull(logger logging.SimpleLogging, pull models.PullRequest, pullOptions models.PullRequestOptions) error {
337+
func (g *Client) MergePull(logger logging.SimpleLogging, pull models.PullRequest, pullOptions models.PullRequestOptions) error {
338338
owner, project, repoName := SplitAzureDevopsRepoFullName(pull.BaseRepo.FullName)
339339
descriptor := "Atlantis Terraform Pull Request Automation"
340340

@@ -392,7 +392,7 @@ func (g *AzureDevopsClient) MergePull(logger logging.SimpleLogging, pull models.
392392
}
393393

394394
// MarkdownPullLink specifies the string used in a pull request comment to reference another pull request.
395-
func (g *AzureDevopsClient) MarkdownPullLink(pull models.PullRequest) (string, error) {
395+
func (g *Client) MarkdownPullLink(pull models.PullRequest) (string, error) {
396396
return fmt.Sprintf("!%d", pull.Num), nil
397397
}
398398

@@ -421,23 +421,23 @@ func SplitAzureDevopsRepoFullName(repoFullName string) (owner string, project st
421421
}
422422

423423
// GetTeamNamesForUser returns the names of the teams or groups that the user belongs to (in the organization the repository belongs to).
424-
func (g *AzureDevopsClient) GetTeamNamesForUser(_ logging.SimpleLogging, _ models.Repo, _ models.User) ([]string, error) { //nolint: revive
424+
func (g *Client) GetTeamNamesForUser(_ logging.SimpleLogging, _ models.Repo, _ models.User) ([]string, error) { //nolint: revive
425425
return nil, nil
426426
}
427427

428-
func (g *AzureDevopsClient) SupportsSingleFileDownload(repo models.Repo) bool { //nolint: revive
428+
func (g *Client) SupportsSingleFileDownload(repo models.Repo) bool { //nolint: revive
429429
return false
430430
}
431431

432-
func (g *AzureDevopsClient) GetFileContent(_ logging.SimpleLogging, _ models.Repo, _ string, _ string) (bool, []byte, error) { //nolint: revive
432+
func (g *Client) GetFileContent(_ logging.SimpleLogging, _ models.Repo, _ string, _ string) (bool, []byte, error) { //nolint: revive
433433
return false, []byte{}, fmt.Errorf("not implemented")
434434
}
435435

436436
// GitStatusContextFromSrc parses an Atlantis formatted src string into a context suitable
437437
// for the status update API. In the AzureDevops branch policy UI there is a single string
438438
// field used to drive these contexts where all text preceding the final '/' character is
439439
// treated as the 'genre'.
440-
func GitStatusContextFromSrc(src string) *azuredevops.GitStatusContext {
440+
func gitStatusContextFromSrc(src string) *azuredevops.GitStatusContext {
441441
lastSlashIdx := strings.LastIndex(src, "/")
442442
genre := "Atlantis Bot"
443443
name := src
@@ -452,10 +452,10 @@ func GitStatusContextFromSrc(src string) *azuredevops.GitStatusContext {
452452
}
453453
}
454454

455-
func (g *AzureDevopsClient) GetCloneURL(_ logging.SimpleLogging, VCSHostType models.VCSHostType, repo string) (string, error) { //nolint: revive
455+
func (g *Client) GetCloneURL(_ logging.SimpleLogging, VCSHostType models.VCSHostType, repo string) (string, error) { //nolint: revive
456456
return "", fmt.Errorf("not yet implemented")
457457
}
458458

459-
func (g *AzureDevopsClient) GetPullLabels(_ logging.SimpleLogging, _ models.Repo, _ models.PullRequest) ([]string, error) {
459+
func (g *Client) GetPullLabels(_ logging.SimpleLogging, _ models.Repo, _ models.PullRequest) ([]string, error) {
460460
return nil, fmt.Errorf("not yet implemented")
461461
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2025 The Atlantis Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package azuredevops
5+
6+
import (
7+
"testing"
8+
9+
. "github.com/runatlantis/atlantis/testing"
10+
)
11+
12+
func TestGitStatusContextFromSrc(t *testing.T) {
13+
cases := []struct {
14+
src string
15+
expGenre string
16+
expName string
17+
}{
18+
{
19+
"atlantis/plan",
20+
"Atlantis Bot/atlantis",
21+
"plan",
22+
},
23+
{
24+
"atlantis/foo/bar/biz/baz",
25+
"Atlantis Bot/atlantis/foo/bar/biz",
26+
"baz",
27+
},
28+
{
29+
"foo",
30+
"Atlantis Bot",
31+
"foo",
32+
},
33+
{
34+
"",
35+
"Atlantis Bot",
36+
"",
37+
},
38+
}
39+
40+
for _, c := range cases {
41+
result := gitStatusContextFromSrc(c.src)
42+
expName := c.expName
43+
expGenre := c.expGenre
44+
Equals(t, &expName, result.Name)
45+
Equals(t, &expGenre, result.Genre)
46+
}
47+
}

0 commit comments

Comments
 (0)