Skip to content

Commit 6e91234

Browse files
feat: add bitbucket cloud api-user flag (#5940)
Signed-off-by: jeronimo-caylent <[email protected]>
1 parent a1942a6 commit 6e91234

File tree

7 files changed

+54
-14
lines changed

7 files changed

+54
-14
lines changed

cmd/server.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ const (
6464
AutoplanModules = "autoplan-modules"
6565
AutoplanModulesFromProjects = "autoplan-modules-from-projects"
6666
AutoplanFileListFlag = "autoplan-file-list"
67+
BitbucketApiUserFlag = "bitbucket-api-user"
6768
BitbucketBaseURLFlag = "bitbucket-base-url"
6869
BitbucketTokenFlag = "bitbucket-token"
6970
BitbucketUserFlag = "bitbucket-user"
@@ -250,8 +251,11 @@ var stringFlags = map[string]stringFlag{
250251
" A custom Workflow that uses autoplan 'when_modified' will ignore this value.",
251252
defaultValue: DefaultAutoplanFileList,
252253
},
254+
BitbucketApiUserFlag: {
255+
description: "Bitbucket username for API calls. If not set, defaults to bitbucket-user for backward compatibility. Can also be specified via the ATLANTIS_BITBUCKET_API_USER environment variable.",
256+
},
253257
BitbucketUserFlag: {
254-
description: "Bitbucket username of API user.",
258+
description: "Bitbucket username for git operations.",
255259
},
256260
BitbucketTokenFlag: {
257261
description: "Bitbucket app password of API user. Can also be specified via the ATLANTIS_BITBUCKET_TOKEN environment variable.",

cmd/server_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ var testFlags = map[string]interface{}{
6969
AutoDiscoverModeFlag: "auto",
7070
AutomergeFlag: true,
7171
AutoplanFileListFlag: "**/*.tf,**/*.yml",
72+
BitbucketApiUserFlag: "bitbucket-api-user",
7273
BitbucketBaseURLFlag: "https://bitbucket-base-url.com",
7374
BitbucketTokenFlag: "bitbucket-token",
7475
BitbucketUserFlag: "bitbucket-user",

runatlantis.io/docs/server-configuration.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,30 @@ ATLANTIS_AZUREDEVOPS_WEBHOOK_USER="[email protected]"
304304

305305
Azure DevOps basic authentication username for inbound webhooks.
306306

307+
### `--bitbucket-api-user` <Badge text="v0.36.0+" type="info"/>
308+
309+
```bash
310+
atlantis server --bitbucket-api-user="[email protected]"
311+
# or
312+
ATLANTIS_BITBUCKET_API_USER="[email protected]"
313+
```
314+
315+
Bitbucket username (usually an email) used for API authentication with Bitbucket Cloud. This is used for API calls only. If not specified, Atlantis will use the value of `--bitbucket-user` for API authentication to maintain backward compatibility.
316+
317+
**Note:**
318+
319+
- The backward compatibility is for supporting the existing Bitbucket APP Passwords that are still valid until June 2026(see [here](https://www.atlassian.com/blog/bitbucket/bitbucket-cloud-transitions-to-api-tokens-enhancing-security-with-app-password-deprecation)).
320+
321+
**Config file key:**
322+
323+
```yaml
324+
bitbucket-api-user: [email protected]
325+
```
326+
327+
**Environment variable:** `ATLANTIS_BITBUCKET_API_USER`
328+
329+
**Note:** This flag is only relevant for Bitbucket Cloud (bitbucket.org) integrations.
330+
307331
### `--bitbucket-base-url` <Badge text="v0.36.0+" type="info"/>
308332

309333
```bash
@@ -334,7 +358,7 @@ atlantis server --bitbucket-user="myuser"
334358
ATLANTIS_BITBUCKET_USER="myuser"
335359
```
336360

337-
Bitbucket username of API user.
361+
Bitbucket username used for git operations. For Bitbucket Cloud, if `--bitbucket-api-user` is not specified, this value will also be used for API authentication.
338362

339363
### `--bitbucket-webhook-secret` <Badge text="v0.36.0+" type="info"/>
340364

server/events/vcs/bitbucketcloud/client.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import (
1717

1818
type Client struct {
1919
HTTPClient *http.Client
20-
Username string
20+
Username string // Used for git operations
21+
ApiUser string // Used for API calls (Basic Auth)
2122
Password string
2223
BaseURL string
2324
AtlantisURL string
@@ -27,13 +28,20 @@ type Client struct {
2728
// URL for Atlantis that will be linked to from the build status icons. This
2829
// linking is annoying because we don't have anywhere good to link but a URL is
2930
// required.
30-
func NewClient(httpClient *http.Client, username string, password string, atlantisURL string) *Client {
31+
// username is used for git operations, apiUser is used for API authentication (Basic Auth).
32+
// If apiUser is empty, it will default to username for backward compatibility.
33+
func NewClient(httpClient *http.Client, username string, password string, apiUser string, atlantisURL string) *Client {
3134
if httpClient == nil {
3235
httpClient = http.DefaultClient
3336
}
37+
// Use apiUser for API calls if provided, otherwise fall back to username for backward compatibility
38+
if apiUser == "" {
39+
apiUser = username
40+
}
3441
return &Client{
3542
HTTPClient: httpClient,
3643
Username: username,
44+
ApiUser: apiUser,
3745
Password: password,
3846
BaseURL: BaseURL,
3947
AtlantisURL: atlantisURL,
@@ -316,7 +324,8 @@ func (b *Client) prepRequest(method string, path string, body io.Reader) (*http.
316324
if err != nil {
317325
return nil, err
318326
}
319-
req.SetBasicAuth(b.Username, b.Password)
327+
// Use ApiUser for API authentication, Username is for git operations
328+
req.SetBasicAuth(b.ApiUser, b.Password)
320329
if body != nil {
321330
req.Header.Add("Content-Type", "application/json")
322331
}

server/events/vcs/bitbucketcloud/client_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func TestClient_GetModifiedFilesPagination(t *testing.T) {
7575
defer testServer.Close()
7676

7777
serverURL = testServer.URL
78-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
78+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
7979
client.BaseURL = testServer.URL
8080

8181
files, err := client.GetModifiedFiles(
@@ -139,7 +139,7 @@ func TestClient_GetModifiedFilesOldNil(t *testing.T) {
139139
}))
140140
defer testServer.Close()
141141

142-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
142+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
143143
client.BaseURL = testServer.URL
144144

145145
files, err := client.GetModifiedFiles(
@@ -208,7 +208,7 @@ func TestClient_PullIsApproved(t *testing.T) {
208208
}))
209209
defer testServer.Close()
210210

211-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
211+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
212212
client.BaseURL = testServer.URL
213213

214214
repo, err := models.NewRepo(models.BitbucketServer, "owner/repo", "https://bitbucket.org/owner/repo.git", "user", "token")
@@ -342,7 +342,7 @@ func TestClient_PullIsMergeable(t *testing.T) {
342342
}))
343343
defer testServer.Close()
344344

345-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
345+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
346346
client.BaseURL = testServer.URL
347347

348348
actMergeable, err := client.PullIsMergeable(
@@ -368,7 +368,7 @@ func TestClient_PullIsMergeable(t *testing.T) {
368368
}
369369

370370
func TestClient_MarkdownPullLink(t *testing.T) {
371-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
371+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
372372
pull := models.PullRequest{Num: 1}
373373
s, _ := client.MarkdownPullLink(pull)
374374
exp := "#1"
@@ -392,7 +392,7 @@ func TestClient_GetMyUUID(t *testing.T) {
392392
}))
393393
defer testServer.Close()
394394

395-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
395+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
396396
client.BaseURL = testServer.URL
397397
v, _ := client.GetMyUUID()
398398
Equals(t, v, "{00000000-0000-0000-0000-000000000001}")
@@ -415,7 +415,7 @@ func TestClient_GetComment(t *testing.T) {
415415
}))
416416
defer testServer.Close()
417417

418-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
418+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
419419
client.BaseURL = testServer.URL
420420
v, _ := client.GetPullRequestComments(
421421
models.Repo{
@@ -451,7 +451,7 @@ func TestClient_DeleteComment(t *testing.T) {
451451
}))
452452
defer testServer.Close()
453453

454-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
454+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
455455
client.BaseURL = testServer.URL
456456
err := client.DeletePullRequestComment(
457457
models.Repo{
@@ -513,7 +513,7 @@ func TestClient_HidePRComments(t *testing.T) {
513513
}))
514514
defer testServer.Close()
515515

516-
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
516+
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "", "runatlantis.io")
517517
client.BaseURL = testServer.URL
518518
err = client.HidePrevCommandComments(logger,
519519
models.Repo{

server/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) {
300300
http.DefaultClient,
301301
userConfig.BitbucketUser,
302302
userConfig.BitbucketToken,
303+
userConfig.BitbucketApiUser,
303304
userConfig.AtlantisURL)
304305
} else {
305306
supportedVCSHosts = append(supportedVCSHosts, models.BitbucketServer)

server/user_config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type UserConfig struct {
2727
AzureDevopsWebhookPassword string `mapstructure:"azuredevops-webhook-password"`
2828
AzureDevopsWebhookUser string `mapstructure:"azuredevops-webhook-user"`
2929
AzureDevOpsHostname string `mapstructure:"azuredevops-hostname"`
30+
BitbucketApiUser string `mapstructure:"bitbucket-api-user"`
3031
BitbucketBaseURL string `mapstructure:"bitbucket-base-url"`
3132
BitbucketToken string `mapstructure:"bitbucket-token"`
3233
BitbucketUser string `mapstructure:"bitbucket-user"`

0 commit comments

Comments
 (0)