From 68c0bd75c18eb66ef023f7375e6bd9aa9c7ee41a Mon Sep 17 00:00:00 2001 From: Damien Urruty Date: Tue, 7 Jul 2026 13:47:38 +0200 Subject: [PATCH] CLI-802 Remove the Homebrew-specific binaries --- .github/workflows/build.yml | 6 ++++-- CLAUDE.md | 1 + src/cli/command-tree.ts | 4 ++-- src/cli/commands/system/status.ts | 4 ++-- src/lib/distribution.ts | 25 +++++++++++++++++++------ tests/unit/lib/distribution.test.ts | 13 ++++++++++--- 6 files changed, 38 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e6f5f286..25695f6d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,7 +98,9 @@ jobs: SONARQUBE_CLI_DISTRIBUTION="$distribution" SONARQUBE_CLI_TARGET="$target" SONARQUBE_CLI_OUTFILE="dist/${filename}" bun build-scripts/build-binary.ts } - for distribution in standalone homebrew; do + distributions=(standalone) + + for distribution in "${distributions[@]}"; do build_binary "$distribution" bun-linux-x64 linux-x86-64 bin build_binary "$distribution" bun-linux-arm64 linux-arm64 bin build_binary "$distribution" bun-darwin-arm64 macos-arm64 bin @@ -279,7 +281,7 @@ jobs: ARTIFACTORY_DEPLOY_REPO: sonarsource-public-qa PROJECT: ${{ github.event.repository.name }} BUILD_NUMBER: ${{ needs.prepare.outputs.BUILD_NUMBER }} - ARTIFACTS_TO_PUBLISH: 'org.sonarsource.cli:sonarqube-cli:bin:linux-x86-64,org.sonarsource.cli:sonarqube-cli:bin:linux-arm64,org.sonarsource.cli:sonarqube-cli:bin:macos-arm64,org.sonarsource.cli:sonarqube-cli:exe:windows-x86-64,org.sonarsource.cli:sonarqube-cli:bin:homebrew-linux-x86-64,org.sonarsource.cli:sonarqube-cli:bin:homebrew-linux-arm64,org.sonarsource.cli:sonarqube-cli:bin:homebrew-macos-arm64,org.sonarsource.cli:sonarqube-cli:exe:homebrew-windows-x86-64' + ARTIFACTS_TO_PUBLISH: 'org.sonarsource.cli:sonarqube-cli:bin:linux-x86-64,org.sonarsource.cli:sonarqube-cli:bin:linux-arm64,org.sonarsource.cli:sonarqube-cli:bin:macos-arm64,org.sonarsource.cli:sonarqube-cli:exe:windows-x86-64' run: | jf config add repox \ --artifactory-url="${ARTIFACTORY_URL}" \ diff --git a/CLAUDE.md b/CLAUDE.md index 9c0c5c314..d9795cacf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,6 +3,7 @@ A CLI tool (`sonar`) that integrates SonarQube Server and Cloud into developer workflows. Release builds publish standalone executables for `linux-x86-64`, `linux-arm64`, `macos-arm64`, and `windows-x86-64`. binaries.sonarsource.com artifacts use the `.bin` suffix on Linux/macOS and `.exe` on Windows (e.g. `sonarqube-cli-{version}-linux-x86-64.bin`); versions published before that convention remain `.exe` on the CDN. Dependency binaries (sonar-secrets, sca-scanner-cli) still use `.exe` in download URLs. The stable installers (`user-scripts/install.sh`, `user-scripts/install.ps1`) resolve the real release version from `Distribution/sonarqube-cli/stable.version`; the shell installers select the Linux artifact using `uname -m` (`aarch64` / `arm64` → `linux-arm64`, `x86_64` / `amd64` → `linux-x86-64`) and try `.bin` then `.exe` when downloading. They also keep a literal compatibility version marker for older `sonar self-update` clients, and `full-release.yml` updates that marker to the latest released version during the post-release bump PR. +Compiled binaries are produced via `build-scripts/build-binary.ts`, which injects `SONARQUBE_CLI_DISTRIBUTION` at compile time. The only supported value is `standalone`, and standalone-only flows such as `self-update` key off that distribution marker. # Running checks diff --git a/src/cli/command-tree.ts b/src/cli/command-tree.ts index d7c9c722e..919fe0fd0 100644 --- a/src/cli/command-tree.ts +++ b/src/cli/command-tree.ts @@ -21,7 +21,7 @@ import { type Command, Help, InvalidArgumentError, Option } from 'commander'; import { version as VERSION } from '../../package.json'; -import { IS_STANDALONE_DISTRIBUTION } from '../lib/distribution'; +import { CURRENT_DISTRIBUTION } from '../lib/distribution'; import { loadState } from '../lib/repository/state-repository'; import { initSentry } from '../lib/sentry'; import { maybeNotifyUpdateAvailable } from '../lib/update-notification'; @@ -574,7 +574,7 @@ system .anonymousAction((options: SystemResetOptions) => systemReset(options)); // Update the CLI to the latest version -if (IS_STANDALONE_DISTRIBUTION) { +if (CURRENT_DISTRIBUTION.enableSelfUpdate) { COMMAND_TREE.command('self-update') .description('Update SonarQube CLI to the latest version') .rootHelp({ diff --git a/src/cli/commands/system/status.ts b/src/cli/commands/system/status.ts index 4dd514965..edda0e2d9 100644 --- a/src/cli/commands/system/status.ts +++ b/src/cli/commands/system/status.ts @@ -36,7 +36,7 @@ import type { ProxyGroup, ResolvedNetworkConfig, } from '../../../lib/connectivity/types'; -import { IS_STANDALONE_DISTRIBUTION } from '../../../lib/distribution'; +import { CURRENT_DISTRIBUTION } from '../../../lib/distribution'; import { CONTEXT_AUGMENTATION_BINARY_NAME, SCA_SCANNER_BINARY_NAME, @@ -362,7 +362,7 @@ function integrationConfigStatusLine(status: IntegrationConfigStatus): string { } async function getCliUpdateInfo(): Promise { - if (!IS_STANDALONE_DISTRIBUTION) { + if (!CURRENT_DISTRIBUTION.enableSelfUpdate) { return null; } diff --git a/src/lib/distribution.ts b/src/lib/distribution.ts index 76078fe75..bf716be87 100644 --- a/src/lib/distribution.ts +++ b/src/lib/distribution.ts @@ -18,11 +18,23 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export const DISTRIBUTIONS = ['standalone', 'homebrew'] as const; +export const DISTRIBUTIONS = ['standalone'] as const; const DEFAULT_DISTRIBUTION = 'standalone'; export type Distribution = (typeof DISTRIBUTIONS)[number]; +export interface DistributionConfig { + id: Distribution; + enableSelfUpdate: boolean; +} + +const DISTRIBUTION_CONFIGS: Record = { + standalone: { + id: 'standalone', + enableSelfUpdate: true, + }, +}; + function invalidDistributionError(rawDistribution: string): Error { return new Error( `Unknown distribution '${rawDistribution}'. Expected one of: ${DISTRIBUTIONS.join(', ')}.`, @@ -44,11 +56,12 @@ export function resolveDistribution(rawDistribution: string | undefined): Distri return rawDistribution; } -const rawDistribution = process.env.SONARQUBE_CLI_DISTRIBUTION; -if (rawDistribution !== undefined) { - assertDistribution(rawDistribution); +export function resolveDistributionConfig(rawDistribution: string | undefined): DistributionConfig { + return DISTRIBUTION_CONFIGS[resolveDistribution(rawDistribution)]; } // Channel builds inject this env access at compile time via Bun's `define`. -export const DISTRIBUTION: Distribution = rawDistribution ?? DEFAULT_DISTRIBUTION; -export const IS_STANDALONE_DISTRIBUTION = DISTRIBUTION === 'standalone'; +export const CURRENT_DISTRIBUTION = resolveDistributionConfig( + process.env.SONARQUBE_CLI_DISTRIBUTION, +); +export const DISTRIBUTION = CURRENT_DISTRIBUTION.id; diff --git a/tests/unit/lib/distribution.test.ts b/tests/unit/lib/distribution.test.ts index aec066b1c..15e530684 100644 --- a/tests/unit/lib/distribution.test.ts +++ b/tests/unit/lib/distribution.test.ts @@ -20,7 +20,7 @@ import { describe, expect, it } from 'bun:test'; -import { resolveDistribution } from '../../../src/lib/distribution'; +import { resolveDistribution, resolveDistributionConfig } from '../../../src/lib/distribution'; describe('distribution', () => { it('defaults to standalone when no distribution is provided', () => { @@ -28,12 +28,19 @@ describe('distribution', () => { }); it('returns the configured distribution for known values', () => { - expect(resolveDistribution('homebrew')).toBe('homebrew'); + expect(resolveDistribution('standalone')).toBe('standalone'); + }); + + it('resolves centralized feature flags for the distribution', () => { + expect(resolveDistributionConfig(undefined)).toEqual({ + id: 'standalone', + enableSelfUpdate: true, + }); }); it('throws for unknown values', () => { expect(() => resolveDistribution('custom-channel')).toThrow( - "Unknown distribution 'custom-channel'. Expected one of: standalone, homebrew.", + "Unknown distribution 'custom-channel'. Expected one of: standalone.", ); }); });