From 7d9f6526f5b867dcfff956b7be9d33111c1ea6f3 Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 6 Aug 2026 01:41:21 +0200 Subject: [PATCH] docs: track the newest containerisable Bitbucket version instead of a pin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 9.4.16 target had drifted. The container stack moved on while the config default, the auth status output, and the README still advertised 9.4.16, so the documented target described a version nothing was tested against. The intent was never to freeze on one release but to run the newest 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. Bumping the pin to the current stack version would only drift again at the next upgrade. So the version lives in one place: the image tag in docker/compose.yml and docker/custom-bitbucket/Dockerfile. Nothing else restates it. ADR 042 records this and supersedes ADR 018. BITBUCKET_VERSION_TARGET stays, so operators can record a version for their own environment, but it no longer defaults to one, and bb auth status reports it only when set. The field remains in the machine envelope: it is required by the bb.machine contract and removing it would break consumers. The API contract source is deliberately unchanged. The vendored 9.4 OpenAPI artifact pins the shapes the generated client is built from, which is spec provenance rather than a supported-version claim; the README now says so instead of leaving it ambiguous. Co-Authored-By: Claude Opus 4.8 --- README.md | 16 +++-- ...18-supported-bitbucket-version-policy.yaml | 3 +- ...est-containerisable-bitbucket-version.yaml | 48 +++++++++++++++ .../018-supported-bitbucket-version-policy.md | 3 +- ...ewest-containerisable-bitbucket-version.md | 30 ++++++++++ docs/site/adr/index.md | 5 +- internal/cli/cmd/auth/auth.go | 16 ++--- internal/cli/cmd/auth/auth_test.go | 60 +++++++++++++++++++ internal/config/config.go | 5 +- 9 files changed, 169 insertions(+), 17 deletions(-) create mode 100644 docs/decisions/042-track-newest-containerisable-bitbucket-version.yaml create mode 100644 docs/site/adr/042-track-newest-containerisable-bitbucket-version.md diff --git a/README.md b/README.md index f600174e..80dc44cb 100644 --- a/README.md +++ b/README.md @@ -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: @@ -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" }, @@ -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 diff --git a/docs/decisions/018-supported-bitbucket-version-policy.yaml b/docs/decisions/018-supported-bitbucket-version-policy.yaml index 380df90a..75f82c0e 100644 --- a/docs/decisions/018-supported-bitbucket-version-policy.yaml +++ b/docs/decisions/018-supported-bitbucket-version-policy.yaml @@ -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. diff --git a/docs/decisions/042-track-newest-containerisable-bitbucket-version.yaml b/docs/decisions/042-track-newest-containerisable-bitbucket-version.yaml new file mode 100644 index 00000000..0ba07a21 --- /dev/null +++ b/docs/decisions/042-track-newest-containerisable-bitbucket-version.yaml @@ -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 diff --git a/docs/site/adr/018-supported-bitbucket-version-policy.md b/docs/site/adr/018-supported-bitbucket-version-policy.md index cdc59521..2c69bbfb 100644 --- a/docs/site/adr/018-supported-bitbucket-version-policy.md +++ b/docs/site/adr/018-supported-bitbucket-version-policy.md @@ -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` diff --git a/docs/site/adr/042-track-newest-containerisable-bitbucket-version.md b/docs/site/adr/042-track-newest-containerisable-bitbucket-version.md new file mode 100644 index 00000000..e8e4ac77 --- /dev/null +++ b/docs/site/adr/042-track-newest-containerisable-bitbucket-version.md @@ -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. diff --git a/docs/site/adr/index.md b/docs/site/adr/index.md index 221f304e..4c9927f7 100644 --- a/docs/site/adr/index.md +++ b/docs/site/adr/index.md @@ -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 @@ -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`) @@ -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`) diff --git a/internal/cli/cmd/auth/auth.go b/internal/cli/cmd/auth/auth.go index a0b3887e..f1921a56 100644 --- a/internal/cli/cmd/auth/auth.go +++ b/internal/cli/cmd/auth/auth.go @@ -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 }, } diff --git a/internal/cli/cmd/auth/auth_test.go b/internal/cli/cmd/auth/auth_test.go index c3ada0e0..d759737c 100644 --- a/internal/cli/cmd/auth/auth_test.go +++ b/internal/cli/cmd/auth/auth_test.go @@ -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) + } +} diff --git a/internal/config/config.go b/internal/config/config.go index b4de013c..c11bdac9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -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