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
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ bb auth status
```

```text
Target Bitbucket: https://bitbucket.acme.corp (expected version 9.4.16, auth=token, source=stored/default)
Target Bitbucket: https://bitbucket.acme.corp (auth=token, source=stored/default)
```

**Clone and browse** — no need to look up URLs:
Expand Down Expand Up @@ -123,7 +123,7 @@ bb --json auth status
"version": "v2",
"data": {
"bitbucket_url": "https://bitbucket.acme.corp",
"bitbucket_version_target": "9.4.16",
"bitbucket_version_target": "",
"auth_mode": "token",
"auth_source": "stored/default"
},
Expand All @@ -146,8 +146,16 @@ bb --json auth status

## Compatibility and contracts

- Primary target: Atlassian Bitbucket Data Center `9.4.x`
- API contract source: Atlassian Bitbucket `9.4` OpenAPI (`docs/reference/atlassian/bitbucket-9.4-openapi.json`)
- Supported version: the newest Bitbucket Data Center release that runs in the project's
container stack and passes the live integration suite. There is no pinned target advertised
here — the version under test is the image tag in `docker/compose.yml`, which is the one place
it is recorded. Newer releases are adopted by bumping that image when they work; some do not
run in the stack, so the newest published release is not automatically the supported one.
Set `BITBUCKET_VERSION_TARGET` if you want to record a version for your own environment.
- API contract source: a version-pinned Atlassian OpenAPI artifact
(`docs/reference/atlassian/bitbucket-9.4-openapi.json`). This fixes the endpoint and payload
shapes the generated client is built from — it is the provenance of the spec, not a statement
about which server versions work. Behavior is established by live tests, not the spec.
- CLI identity and machine contract: `bb` / `bb.machine` `v2`
- JSON schemas for bulk policy/plan/status published in docs and versioned with releases

Expand Down
3 changes: 2 additions & 1 deletion docs/decisions/018-supported-bitbucket-version-policy.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
number: 18
title: Supported Bitbucket version policy
category: architecture
status: accepted
status: superseded
superseded_by: 42
decision: >
Support Atlassian Bitbucket 9.4.16 as the primary compatibility target initially.
Additional versions may be introduced through explicit decision updates and expanded live test coverage.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
number: 42
title: Track the newest containerisable Bitbucket version
category: architecture
status: accepted
supersedes: 18
decision: >
Target the newest Bitbucket Data Center version that runs in this project's container stack and
passes the live integration suite, rather than a version pinned in advance.
A release that cannot run in the stack, or that runs but fails the suite, is not a target however
recent it is.
The version under test is recorded only in the stack definition, in docker/compose.yml and
docker/custom-bitbucket/Dockerfile. No other surface states a supported version.
agent_instructions: >
Do not state or assume a specific supported Bitbucket version in code, CLI output, or
documentation, and do not reintroduce a default version target in configuration.
To find the version under test, read the image tag in docker/compose.yml.
To move to a newer release, bump the image there and in docker/custom-bitbucket/Dockerfile and let
the live suite decide whether it holds; do not assume the newest published release is usable.
Where behavior differs between versions, record the version it was observed on next to the
workaround and cover it with a live test.
rationale: >
The previous 9.4.16 pin drifted. The stack moved on while the configuration default, the auth
status output, and the README still advertised 9.4.16, so the documented target described a
version nothing was testing against.
The intent was never to freeze on one release but to run the newest version that works, and that
has a real upper bound: newer releases have failed to run in this containerised stack, so the
newest published release and the newest supportable one are not the same thing.
Support is therefore a property of the stack and the suite rather than a number to restate, and
keeping it in the stack definition leaves one place to change on upgrade with no copies to drift.
rejected_alternatives:
- alternative: Bump the pinned target to the current stack version
reason: >
Drifts again at the next upgrade and recreates the duplicated copies this removes, without
making the claim any better verified.
- alternative: Always track the newest published Bitbucket release
reason: >
Newer releases have broken this containerised stack, so tracking the newest release would
claim support for versions the suite cannot exercise.
- alternative: Declare a supported version range
reason: >
Implies every version in the range is verified, which nothing in this project establishes, and
the upper bound is whatever still runs in the container rather than a version chosen up front.
- alternative: Remove the bitbucket_version_target field from machine output
reason: >
It is a required field of the bb.machine envelope, so removing it breaks consumers. Leaving it
settable lets operators record a version for their own environment without the project
asserting one.
provenance: human
3 changes: 2 additions & 1 deletion docs/site/adr/018-supported-bitbucket-version-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ This page is generated from `docs/decisions/*.yaml` by `task docs:export-adr-mar
- Number: `018`
- Title: `Supported Bitbucket version policy`
- Category: `architecture`
- Status: `accepted`
- Status: `superseded`
- Superseded By: `042`
- Provenance: `guided-ai`
- Source: `docs/decisions/018-supported-bitbucket-version-policy.yaml`

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# ADR 042: Track the newest containerisable Bitbucket version

This page is generated from `docs/decisions/*.yaml` by `task docs:export-adr-markdown`. Do not edit manually.

- Number: `042`
- Title: `Track the newest containerisable Bitbucket version`
- Category: `architecture`
- Status: `accepted`
- Supersedes: `018`
- Provenance: `human`
- Source: `docs/decisions/042-track-newest-containerisable-bitbucket-version.yaml`

## Decision

Target the newest Bitbucket Data Center version that runs in this project's container stack and passes the live integration suite, rather than a version pinned in advance. A release that cannot run in the stack, or that runs but fails the suite, is not a target however recent it is. The version under test is recorded only in the stack definition, in docker/compose.yml and docker/custom-bitbucket/Dockerfile. No other surface states a supported version.

## Agent Instructions

Do not state or assume a specific supported Bitbucket version in code, CLI output, or documentation, and do not reintroduce a default version target in configuration. To find the version under test, read the image tag in docker/compose.yml. To move to a newer release, bump the image there and in docker/custom-bitbucket/Dockerfile and let the live suite decide whether it holds; do not assume the newest published release is usable. Where behavior differs between versions, record the version it was observed on next to the workaround and cover it with a live test.

## Rationale

The previous 9.4.16 pin drifted. The stack moved on while the configuration default, the auth status output, and the README still advertised 9.4.16, so the documented target described a version nothing was testing against. The intent was never to freeze on one release but to run the newest version that works, and that has a real upper bound: newer releases have failed to run in this containerised stack, so the newest published release and the newest supportable one are not the same thing. Support is therefore a property of the stack and the suite rather than a number to restate, and keeping it in the stack definition leaves one place to change on upgrade with no copies to drift.

## Rejected Alternatives

- `Bump the pinned target to the current stack version`: Drifts again at the next upgrade and recreates the duplicated copies this removes, without making the claim any better verified.
- `Always track the newest published Bitbucket release`: Newer releases have broken this containerised stack, so tracking the newest release would claim support for versions the suite cannot exercise.
- `Declare a supported version range`: Implies every version in the range is verified, which nothing in this project establishes, and the upper bound is whatever still runs in the container rather than a version chosen up front.
- `Remove the bitbucket_version_target field from machine output`: It is a required field of the bb.machine envelope, so removing it breaks consumers. Leaving it settable lets operators record a version for their own environment without the project asserting one.
5 changes: 3 additions & 2 deletions docs/site/adr/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Published Architecture and Development Decision Records for this project.

This page and linked ADR pages are generated from `docs/decisions/*.yaml` by `task docs:export-adr-markdown`.

- Total ADRs: `41`
- Total ADRs: `42`
- Accepted ADRs: `40`

## ADR List
Expand All @@ -26,7 +26,7 @@ This page and linked ADR pages are generated from `docs/decisions/*.yaml` by `ta
- [ADR 015: Live test harness and deterministic seeding](015-live-test-harness-and-deterministic-seeding.md) (`development`, `accepted`)
- [ADR 016: Test classification and execution policy](016-test-classification-and-execution-policy.md) (`development`, `accepted`)
- [ADR 017: Undocumented behavior registry via live tests](017-undocumented-behavior-registry-via-live-tests.md) (`development`, `accepted`)
- [ADR 018: Supported Bitbucket version policy](018-supported-bitbucket-version-policy.md) (`architecture`, `accepted`)
- [ADR 018: Supported Bitbucket version policy](018-supported-bitbucket-version-policy.md) (`architecture`, `superseded`)
- [ADR 019: Configuration and secret handling policy](019-configuration-and-secret-handling-policy.md) (`development`, `accepted`)
- [ADR 020: Execgit as default Git backend](020-execgit-as-default-git-backend.md) (`architecture`, `accepted`)
- [ADR 021: Persistent auth configuration and keyring storage](021-persistent-auth-configuration-and-keyring-storage.md) (`architecture`, `accepted`)
Expand All @@ -50,4 +50,5 @@ This page and linked ADR pages are generated from `docs/decisions/*.yaml` by `ta
- [ADR 039: Built-in MCP server with explicit host scoping and token capability restriction](039-built-in-mcp-server-with-host-scoping-and-token-restriction.md) (`architecture`, `accepted`)
- [ADR 040: Agent skill distribution via static npx packaging and dynamic CLI generation](040-agent-skill-distribution-static-npx-and-dynamic-cli.md) (`development`, `accepted`)
- [ADR 041: Host aliases and clone URL discovery for server contexts](041-host-aliases-and-clone-url-discovery-for-server-contexts.md) (`architecture`, `accepted`)
- [ADR 042: Track the newest containerisable Bitbucket version](042-track-newest-containerisable-bitbucket-version.md) (`architecture`, `accepted`)

16 changes: 8 additions & 8 deletions internal/cli/cmd/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ func New(deps Dependencies) *cobra.Command {
return deps.WriteJSON(cmd.OutOrStdout(), payload)
}

fmt.Fprintf(
cmd.OutOrStdout(),
"Target Bitbucket: %s (expected version %s, auth=%s, source=%s)\n",
cfg.BitbucketURL,
cfg.BitbucketVersionTarget,
cfg.AuthMode(),
cfg.AuthSource,
)
// The expected version is only reported when the operator pinned
// one; the project itself does not claim a supported version.
details := fmt.Sprintf("auth=%s, source=%s", cfg.AuthMode(), cfg.AuthSource)
if version := strings.TrimSpace(cfg.BitbucketVersionTarget); version != "" {
details = fmt.Sprintf("expected version %s, %s", version, details)
}

fmt.Fprintf(cmd.OutOrStdout(), "Target Bitbucket: %s (%s)\n", cfg.BitbucketURL, details)
return nil
},
}
Expand Down
60 changes: 60 additions & 0 deletions internal/cli/cmd/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1609,3 +1609,63 @@ func recentResponseToAll(response *openapigenerated.GetRepositoriesRecentlyAcces
ApplicationjsonCharsetUTF8200: response.ApplicationjsonCharsetUTF8200,
}
}

// TestStatusHumanOmitsVersionWhenUnpinned covers the default: the project does
// not claim a supported Bitbucket version, so status must not report one
// unless the operator pinned it (ADR 042).
func TestStatusHumanOmitsVersionWhenUnpinned(t *testing.T) {
cmd := New(Dependencies{
JSONEnabled: func() bool { return false },
LoadConfig: func() (config.AppConfig, error) {
return config.AppConfig{
BitbucketURL: "http://bitbucket.example",
AuthSource: "env/default",
}, nil
},
})

buffer := &bytes.Buffer{}
cmd.SetOut(buffer)
cmd.SetErr(buffer)
cmd.SetArgs([]string{"status"})

if err := cmd.Execute(); err != nil {
t.Fatalf("expected no error, got: %v", err)
}

output := buffer.String()
if strings.Contains(output, "expected version") {
t.Errorf("status must not report a version when none is pinned, got %q", output)
}
if !strings.Contains(output, "http://bitbucket.example") {
t.Errorf("expected the target host in the output, got %q", output)
}
}

// TestStatusHumanReportsPinnedVersion covers the opposite: an operator who set
// BITBUCKET_VERSION_TARGET still sees it.
func TestStatusHumanReportsPinnedVersion(t *testing.T) {
cmd := New(Dependencies{
JSONEnabled: func() bool { return false },
LoadConfig: func() (config.AppConfig, error) {
return config.AppConfig{
BitbucketURL: "http://bitbucket.example",
BitbucketVersionTarget: "10.2.1",
AuthSource: "env/default",
}, nil
},
})

buffer := &bytes.Buffer{}
cmd.SetOut(buffer)
cmd.SetErr(buffer)
cmd.SetArgs([]string{"status"})

if err := cmd.Execute(); err != nil {
t.Fatalf("expected no error, got: %v", err)
}

if output := buffer.String(); !strings.Contains(output, "expected version 10.2.1") {
t.Errorf("expected the pinned version to be reported, got %q", output)
}
}
5 changes: 4 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import (
)

const (
defaultBitbucketVersionTarget = "9.4.16"
// No default Bitbucket version target: the supported version is whatever the
// container stack runs and the live suite passes against (ADR 042). Operators
// may still pin one for their own environment via BITBUCKET_VERSION_TARGET.
defaultBitbucketVersionTarget = ""
defaultProjectKey = "TEST"
defaultRequestTimeout = 20 * time.Second
defaultRetryCount = 2
Expand Down