Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ If you are on MacOS, a community member has created a [Homebrew formula](https:/

``gitbackup`` requires a [GitHub API access token](https://github.com/blog/1509-personal-api-tokens) for
backing up GitHub repositories, a [GitLab personal access token](https://gitlab.com/profile/personal_access_tokens)
for GitLab repositories, a username and [app password](https://bitbucket.org/account/settings/app-passwords/) for
for GitLab repositories, a username and [API token](https://support.atlassian.com/bitbucket-cloud/docs/api-tokens/) (or [app password](https://bitbucket.org/account/settings/app-passwords/)) for
Bitbucket repositories, or a [Forgejo access token][https://docs.codeberg.org/advanced/access-token/] for Forgejo.

You can supply the tokens to ``gitbackup`` using ``GITHUB_TOKEN``, ``GITLAB_TOKEN``, or ``FORGEJO_TOKEN`` environment
variables respectively, and the Bitbucket credentials with ``BITBUCKET_USERNAME`` and ``BITBUCKET_PASSWORD``.
variables respectively, and the Bitbucket credentials with ``BITBUCKET_USERNAME`` and either ``BITBUCKET_TOKEN`` or ``BITBUCKET_PASSWORD``.

### GitHub Specific oAuth App Flow

Expand All @@ -84,11 +84,19 @@ time you run it, it will ask you for the keyring password and retrieve the token

#### Bitbucket

For the App password, the following permissions are required:
**API tokens** (recommended):

- `read:user:bitbucket`
- `read:workspace:bitbucket`
- `read:repository:bitbucket`

**App passwords** (deprecated, disabled after June 9, 2026):

- `Account:Read`
- `Repositories:Read`

**Note:** Bitbucket has deprecated app passwords. Use [API tokens](https://support.atlassian.com/bitbucket-cloud/docs/api-tokens/) instead by setting the ``BITBUCKET_TOKEN`` environment variable.

#### GitHub

- `repo`: Reading repositories, including private repositories
Expand Down Expand Up @@ -250,6 +258,14 @@ $ GITLAB_TOKEN=secret$token gitbackup -service gitlab -githost.url https://git.y

To backup all your Bitbucket repositories to the default backup directory (``$HOME/.gitbackup/``):

Using an API token (recommended):

```lang=bash
$ BITBUCKET_USERNAME=username BITBUCKET_TOKEN=token gitbackup -service bitbucket
```

Using an app password (deprecated, disabled after June 9, 2026):

```lang=bash
$ BITBUCKET_USERNAME=username BITBUCKET_PASSWORD=password gitbackup -service bitbucket
```
Expand Down
9 changes: 6 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,17 @@ func newBitbucketClient(gitHostURLParsed *url.URL) *bitbucket.Client {
log.Fatal("BITBUCKET_USERNAME environment variable not set")
}

bitbucketPassword := os.Getenv("BITBUCKET_PASSWORD")
bitbucketPassword := os.Getenv("BITBUCKET_TOKEN")
if bitbucketPassword == "" {
log.Fatal("BITBUCKET_PASSWORD environment variable not set")
bitbucketPassword = os.Getenv("BITBUCKET_PASSWORD")
}
if bitbucketPassword == "" {
log.Fatal("BITBUCKET_TOKEN or BITBUCKET_PASSWORD environment variable must be set")
}

gitHostToken = bitbucketPassword

client := bitbucket.NewBasicAuth(bitbucketUsername, bitbucketPassword)

if gitHostURLParsed != nil {
client.SetApiBaseURL(*gitHostURLParsed)
}
Expand Down
21 changes: 21 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"net/url"
"os"
"testing"

forgejo "codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2"
Expand Down Expand Up @@ -60,3 +61,23 @@ func TestNewClient(t *testing.T) {
}

}

func TestNewBitbucketClientWithToken(t *testing.T) {
setupRepositoryTests()
defer teardownRepositoryTests()

// Set BITBUCKET_TOKEN and unset BITBUCKET_PASSWORD to test token auth path
os.Setenv("BITBUCKET_TOKEN", "$$$randomtoken")
os.Unsetenv("BITBUCKET_PASSWORD")
defer os.Unsetenv("BITBUCKET_TOKEN")

client := newClient("bitbucket", "")
if client == nil {
t.Fatal("Expected non-nil bitbucket client")
}
_ = client.(*bitbucket.Client)

if gitHostToken != "$$$randomtoken" {
t.Errorf("Expected gitHostToken to be BITBUCKET_TOKEN value, got: %v", gitHostToken)
}
}
Loading