diff --git a/.archgate/adrs/ARCH-017-multi-ecosystem-distribution.md b/.archgate/adrs/ARCH-017-multi-ecosystem-distribution.md index 3fd09416..d1640f8d 100644 --- a/.archgate/adrs/ARCH-017-multi-ecosystem-distribution.md +++ b/.archgate/adrs/ARCH-017-multi-ecosystem-distribution.md @@ -25,7 +25,7 @@ All distribution shims live under `shims/` in the main repository. Each shim is Every shim implements the same algorithm: -1. Detect platform/architecture and map to artifact name (`archgate-darwin-arm64`, `archgate-linux-x64`, `archgate-win32-x64`) +1. Detect platform/architecture and map to artifact name (`archgate-darwin-arm64`, `archgate-darwin-x64`, `archgate-linux-x64`, `archgate-win32-x64`) 2. Check for cached binary at `~/.archgate/bin/archgate[.exe]` 3. If missing, download from `https://github.com/archgate/cli/releases/download/v{VERSION}/{artifact}.{ext}` 4. Verify SHA256 checksum against the companion `.sha256` file @@ -41,7 +41,7 @@ All shim packages share the same cache directory (`~/.archgate/bin/`). If the bi All shims produce identical user-facing error messages on stderr: -- Unsupported platform: `archgate: Unsupported platform: {os}/{arch}\narchgate supports darwin/arm64, linux/x64, and win32/x64.` +- Unsupported platform: `archgate: Unsupported platform: {os}/{arch}\narchgate supports darwin/arm64, darwin/x64, linux/x64, and win32/x64.` - Download failure: `archgate: failed to download binary: {detail}\nVisit https://cli.archgate.dev/getting-started/installation/ for alternative install methods.` - Checksum mismatch: `archgate: checksum verification failed for v{version} (expected {expected}, got {actual})` - Download started: `archgate: binary not found, downloading v{version}...` diff --git a/.github/workflows/publish-shims.yml b/.github/workflows/publish-shims.yml index c1eab9a9..e24c4e75 100644 --- a/.github/workflows/publish-shims.yml +++ b/.github/workflows/publish-shims.yml @@ -29,12 +29,12 @@ jobs: GH_TOKEN: ${{ github.token }} TAG: ${{ inputs.tag }} run: | - REQUIRED_ASSETS=("archgate-darwin-arm64.tar.gz" "archgate-linux-x64.tar.gz" "archgate-win32-x64.zip" "archgate-shim-win32-x64.exe") + REQUIRED_ASSETS=("archgate-darwin-arm64.tar.gz" "archgate-darwin-x64.tar.gz" "archgate-linux-x64.tar.gz" "archgate-win32-x64.zip" "archgate-shim-win32-x64.exe") for i in $(seq 1 10); do ASSETS=$(gh release view "$TAG" --repo archgate/cli --json assets --jq '.assets[].name') ALL_FOUND=true for asset in "${REQUIRED_ASSETS[@]}"; do - if ! echo "$ASSETS" | grep -qF "$asset"; then + if ! echo "$ASSETS" | grep -qxF "$asset"; then ALL_FOUND=false break fi diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index 7866051f..e3e26218 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -30,6 +30,10 @@ jobs: artifact: archgate-darwin-arm64 os: macos-latest binary_name: archgate + - target: bun-darwin-x64 + artifact: archgate-darwin-x64 + os: macos-15-intel + binary_name: archgate - target: bun-linux-x64 artifact: archgate-linux-x64 os: ubuntu-latest diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt index c33cdad1..f7734c85 100644 --- a/docs/public/llms-full.txt +++ b/docs/public/llms-full.txt @@ -290,6 +290,7 @@ Archgate ships pre-built binaries for the following platforms: | Platform | Architecture | Artifact | | -------- | ------------ | ----------------------- | | macOS | arm64 | `archgate-darwin-arm64` | +| macOS | x86_64 | `archgate-darwin-x64` | | Linux | x86_64 | `archgate-linux-x64` | | Windows | x86_64 | `archgate-win32-x64` | diff --git a/docs/src/content/docs/getting-started/installation.mdx b/docs/src/content/docs/getting-started/installation.mdx index c9302608..b72fa580 100644 --- a/docs/src/content/docs/getting-started/installation.mdx +++ b/docs/src/content/docs/getting-started/installation.mdx @@ -176,6 +176,7 @@ Archgate ships pre-built binaries for the following platforms: | Platform | Architecture | Artifact | | -------- | ------------ | ----------------------- | | macOS | arm64 | `archgate-darwin-arm64` | +| macOS | x86_64 | `archgate-darwin-x64` | | Linux | x86_64 | `archgate-linux-x64` | | Windows | x86_64 | `archgate-win32-x64` | diff --git a/docs/src/content/docs/nb/getting-started/installation.mdx b/docs/src/content/docs/nb/getting-started/installation.mdx index 769d4a32..8f9d244d 100644 --- a/docs/src/content/docs/nb/getting-started/installation.mdx +++ b/docs/src/content/docs/nb/getting-started/installation.mdx @@ -176,6 +176,7 @@ Archgate leverer forhåndskompilerte binærfiler for følgende plattformer: | Plattform | Arkitektur | Artefakt | | --------- | ---------- | ----------------------- | | macOS | arm64 | `archgate-darwin-arm64` | +| macOS | x86_64 | `archgate-darwin-x64` | | Linux | x86_64 | `archgate-linux-x64` | | Windows | x86_64 | `archgate-win32-x64` | diff --git a/docs/src/content/docs/pt-br/getting-started/installation.mdx b/docs/src/content/docs/pt-br/getting-started/installation.mdx index 7f888add..5d95058d 100644 --- a/docs/src/content/docs/pt-br/getting-started/installation.mdx +++ b/docs/src/content/docs/pt-br/getting-started/installation.mdx @@ -176,6 +176,7 @@ O Archgate disponibiliza binários pré-compilados para as seguintes plataformas | Plataforma | Arquitetura | Artefato | | ---------- | ----------- | ----------------------- | | macOS | arm64 | `archgate-darwin-arm64` | +| macOS | x86_64 | `archgate-darwin-x64` | | Linux | x86_64 | `archgate-linux-x64` | | Windows | x86_64 | `archgate-win32-x64` | diff --git a/install.sh b/install.sh index fd92e768..bfbad05e 100644 --- a/install.sh +++ b/install.sh @@ -18,7 +18,7 @@ detect_platform() { MINGW*|MSYS*) platform="win32" ;; *) echo "Error: unsupported OS: $os" >&2 - echo "archgate supports macOS (ARM64), Linux (x86_64), and Windows (x64)." >&2 + echo "archgate supports macOS (ARM64, x86_64), Linux (x86_64), and Windows (x64)." >&2 exit 1 ;; esac @@ -28,16 +28,12 @@ detect_platform() { x86_64|amd64) arch="x64" ;; *) echo "Error: unsupported architecture: $arch" >&2 - echo "archgate supports arm64 (macOS) and x64 (Linux, Windows)." >&2 + echo "archgate supports arm64 (macOS) and x64 (macOS, Linux, Windows)." >&2 exit 1 ;; esac - # Validate supported combinations - if [ "$platform" = "darwin" ] && [ "$arch" != "arm64" ]; then - echo "Error: macOS is only supported on ARM64 (Apple Silicon)." >&2 - exit 1 - fi + # Validate supported combinations (macOS ships both arm64 and x64) if [ "$platform" = "linux" ] && [ "$arch" != "x64" ]; then echo "Error: Linux is only supported on x86_64." >&2 exit 1 diff --git a/shims/go/internal/shim/platform.go b/shims/go/internal/shim/platform.go index 02ca7390..b90228b3 100644 --- a/shims/go/internal/shim/platform.go +++ b/shims/go/internal/shim/platform.go @@ -14,6 +14,8 @@ func GetArtifactName() (string, error) { switch key { case "darwin/arm64": return "archgate-darwin-arm64", nil + case "darwin/amd64": + return "archgate-darwin-x64", nil case "linux/amd64": return "archgate-linux-x64", nil case "windows/amd64": diff --git a/shims/go/internal/shim/shim_test.go b/shims/go/internal/shim/shim_test.go index ecf3a764..12426991 100644 --- a/shims/go/internal/shim/shim_test.go +++ b/shims/go/internal/shim/shim_test.go @@ -17,6 +17,8 @@ func TestGetArtifactName(t *testing.T) { switch runtime.GOOS + "/" + runtime.GOARCH { case "darwin/arm64": expected = "archgate-darwin-arm64" + case "darwin/amd64": + expected = "archgate-darwin-x64" case "linux/amd64": expected = "archgate-linux-x64" case "windows/amd64": diff --git a/shims/maven/src/main/java/dev/archgate/cli/Platform.java b/shims/maven/src/main/java/dev/archgate/cli/Platform.java index e5507fc3..107612dc 100644 --- a/shims/maven/src/main/java/dev/archgate/cli/Platform.java +++ b/shims/maven/src/main/java/dev/archgate/cli/Platform.java @@ -23,6 +23,9 @@ public static String getArtifactName() { if (osName.startsWith("Mac") && "aarch64".equals(osArch)) { return "archgate-darwin-arm64"; } + if (osName.startsWith("Mac") && ("x86_64".equals(osArch) || "amd64".equals(osArch))) { + return "archgate-darwin-x64"; + } if (osName.startsWith("Linux") && "amd64".equals(osArch)) { return "archgate-linux-x64"; } @@ -32,7 +35,7 @@ public static String getArtifactName() { throw new UnsupportedOperationException( "Unsupported platform: " + osName + "/" + osArch - + "\narchgate supports darwin/arm64, linux/x64, and win32/x64."); + + "\narchgate supports darwin/arm64, darwin/x64, linux/x64, and win32/x64."); } /** diff --git a/shims/maven/src/test/java/dev/archgate/cli/ShimTest.java b/shims/maven/src/test/java/dev/archgate/cli/ShimTest.java index 1a3c8e8d..242deb7f 100644 --- a/shims/maven/src/test/java/dev/archgate/cli/ShimTest.java +++ b/shims/maven/src/test/java/dev/archgate/cli/ShimTest.java @@ -19,6 +19,12 @@ void darwinArm64ArtifactName() { assertEquals("archgate-darwin-arm64", result); } + @Test + void darwinX64ArtifactName() { + String result = withSystemProperties("Mac OS X", "x86_64", Platform::getArtifactName); + assertEquals("archgate-darwin-x64", result); + } + @Test void linuxX64ArtifactName() { String result = withSystemProperties("Linux", "amd64", Platform::getArtifactName); diff --git a/shims/npm/archgate.cjs b/shims/npm/archgate.cjs index c39942fe..3261762e 100644 --- a/shims/npm/archgate.cjs +++ b/shims/npm/archgate.cjs @@ -13,10 +13,11 @@ function getArtifactName(platform, arch) { const p = platform || process.platform; const a = arch || process.arch; if (p === "darwin" && a === "arm64") return "archgate-darwin-arm64"; + if (p === "darwin" && a === "x64") return "archgate-darwin-x64"; if (p === "linux" && a === "x64") return "archgate-linux-x64"; if (p === "win32" && a === "x64") return "archgate-win32-x64"; throw new Error( - `Unsupported platform: ${p}/${a}\narchgate supports darwin/arm64, linux/x64, and win32/x64.` + `Unsupported platform: ${p}/${a}\narchgate supports darwin/arm64, darwin/x64, linux/x64, and win32/x64.` ); } diff --git a/shims/npm/test/archgate.test.cjs b/shims/npm/test/archgate.test.cjs index 7be9250a..664e77db 100644 --- a/shims/npm/test/archgate.test.cjs +++ b/shims/npm/test/archgate.test.cjs @@ -26,6 +26,10 @@ describe("getArtifactName", () => { assert.equal(getArtifactName("darwin", "arm64"), "archgate-darwin-arm64"); }); + it("darwin/x64 → archgate-darwin-x64", () => { + assert.equal(getArtifactName("darwin", "x64"), "archgate-darwin-x64"); + }); + it("linux/x64 → archgate-linux-x64", () => { assert.equal(getArtifactName("linux", "x64"), "archgate-linux-x64"); }); @@ -46,14 +50,16 @@ describe("getArtifactName", () => { }); }); - it("covers all three supported artifacts", () => { + it("covers all four supported artifacts", () => { const artifacts = new Set([ getArtifactName("darwin", "arm64"), + getArtifactName("darwin", "x64"), getArtifactName("linux", "x64"), getArtifactName("win32", "x64"), ]); - assert.equal(artifacts.size, 3); + assert.equal(artifacts.size, 4); assert.ok(artifacts.has("archgate-darwin-arm64")); + assert.ok(artifacts.has("archgate-darwin-x64")); assert.ok(artifacts.has("archgate-linux-x64")); assert.ok(artifacts.has("archgate-win32-x64")); }); diff --git a/shims/nuget/Archgate.Tool/Program.cs b/shims/nuget/Archgate.Tool/Program.cs index 07e6ff36..ba42aea8 100644 --- a/shims/nuget/Archgate.Tool/Program.cs +++ b/shims/nuget/Archgate.Tool/Program.cs @@ -76,6 +76,8 @@ internal static string GetArtifactName() if (isMacOS && arch == Architecture.Arm64) return "archgate-darwin-arm64"; + if (isMacOS && arch == Architecture.X64) + return "archgate-darwin-x64"; if (isLinux && arch == Architecture.X64) return "archgate-linux-x64"; if (isWindows && arch == Architecture.X64) @@ -85,7 +87,7 @@ internal static string GetArtifactName() string archName = arch.ToString().ToLowerInvariant(); throw new PlatformNotSupportedException( $"Unsupported platform: {os}/{archName}\n" - + "archgate supports darwin/arm64, linux/x64, and win32/x64." + + "archgate supports darwin/arm64, darwin/x64, linux/x64, and win32/x64." ); } diff --git a/shims/nuget/tests/Archgate.Tool.Tests/ShimTests.cs b/shims/nuget/tests/Archgate.Tool.Tests/ShimTests.cs index f1e358e7..79576c34 100644 --- a/shims/nuget/tests/Archgate.Tool.Tests/ShimTests.cs +++ b/shims/nuget/tests/Archgate.Tool.Tests/ShimTests.cs @@ -7,6 +7,7 @@ public class ShimTests { [Theory] [InlineData("darwin", "Arm64", "archgate-darwin-arm64")] + [InlineData("darwin", "X64", "archgate-darwin-x64")] [InlineData("linux", "X64", "archgate-linux-x64")] [InlineData("win32", "X64", "archgate-win32-x64")] public void GetArtifactName_ReturnsPlatformSpecificName(string expectedOs, string arch, string expectedArtifact) @@ -38,6 +39,7 @@ public void GetArtifactName_ReturnsOneOfKnownArtifacts() Assert.Contains(artifact, new[] { "archgate-darwin-arm64", + "archgate-darwin-x64", "archgate-linux-x64", "archgate-win32-x64", }); diff --git a/shims/pypi/archgate/_shim.py b/shims/pypi/archgate/_shim.py index 8985fb6b..42a28621 100644 --- a/shims/pypi/archgate/_shim.py +++ b/shims/pypi/archgate/_shim.py @@ -25,6 +25,7 @@ _PLATFORM_MAP = { ("Darwin", "arm64"): "archgate-darwin-arm64", ("Darwin", "aarch64"): "archgate-darwin-arm64", + ("Darwin", "x86_64"): "archgate-darwin-x64", ("Linux", "x86_64"): "archgate-linux-x64", ("Linux", "AMD64"): "archgate-linux-x64", ("Windows", "AMD64"): "archgate-win32-x64", @@ -40,7 +41,7 @@ def _detect_artifact(): # type: () -> str if artifact is None: print( "archgate: Unsupported platform: {os}/{arch}\n" - "archgate supports darwin/arm64, linux/x64, and win32/x64.".format( + "archgate supports darwin/arm64, darwin/x64, linux/x64, and win32/x64.".format( os=os_name, arch=arch ), file=sys.stderr, diff --git a/shims/pypi/tests/test_shim.py b/shims/pypi/tests/test_shim.py index 4d7b0b64..69dc1420 100644 --- a/shims/pypi/tests/test_shim.py +++ b/shims/pypi/tests/test_shim.py @@ -39,6 +39,12 @@ def test_darwin_aarch64(self): mp.machine.return_value = "aarch64" self.assertEqual(_detect_artifact(), "archgate-darwin-arm64") + def test_darwin_x86_64(self): + with mock.patch("archgate._shim.platform") as mp: + mp.system.return_value = "Darwin" + mp.machine.return_value = "x86_64" + self.assertEqual(_detect_artifact(), "archgate-darwin-x64") + def test_linux_x86_64(self): with mock.patch("archgate._shim.platform") as mp: mp.system.return_value = "Linux" @@ -78,6 +84,7 @@ class TestArtifactNaming(TestCase): def test_artifact_names_in_platform_map(self): expected_artifacts = { "archgate-darwin-arm64", + "archgate-darwin-x64", "archgate-linux-x64", "archgate-win32-x64", } diff --git a/shims/rubygem/lib/archgate/shim.rb b/shims/rubygem/lib/archgate/shim.rb index fdcd099b..bbb4d512 100644 --- a/shims/rubygem/lib/archgate/shim.rb +++ b/shims/rubygem/lib/archgate/shim.rb @@ -21,6 +21,7 @@ module Shim # Platform mapping: [os_pattern, arch_pattern] => artifact name PLATFORM_MAP = [ [/darwin|mac/i, /arm64|aarch64/i, "archgate-darwin-arm64"], + [/darwin|mac/i, /x86_64|x64|amd64/i, "archgate-darwin-x64"], [/linux/i, /x86_64|x64|amd64/i, "archgate-linux-x64"], [/mswin|mingw|cygwin/i, /x86_64|x64|amd64/i, "archgate-win32-x64"] ].freeze @@ -63,7 +64,7 @@ def detect_artifact end $stderr.puts "archgate: Unsupported platform: #{host_os}/#{host_cpu}" - $stderr.puts "archgate supports darwin/arm64, linux/x64, and win32/x64." + $stderr.puts "archgate supports darwin/arm64, darwin/x64, linux/x64, and win32/x64." exit 2 end diff --git a/shims/rubygem/test/test_shim.rb b/shims/rubygem/test/test_shim.rb index 5dc338cd..75643373 100644 --- a/shims/rubygem/test/test_shim.rb +++ b/shims/rubygem/test/test_shim.rb @@ -27,6 +27,10 @@ def test_darwin_aarch64 assert_equal "archgate-darwin-arm64", detect_with("darwin23", "aarch64") end + def test_darwin_x86_64 + assert_equal "archgate-darwin-x64", detect_with("darwin23", "x86_64") + end + def test_linux_x86_64 assert_equal "archgate-linux-x64", detect_with("linux-gnu", "x86_64") end diff --git a/src/commands/upgrade.ts b/src/commands/upgrade.ts index f32f6b86..3c6c4a5a 100644 --- a/src/commands/upgrade.ts +++ b/src/commands/upgrade.ts @@ -270,7 +270,7 @@ async function upgradeBinary(tag: string): Promise { if (!artifact) { logError( `Unsupported platform: ${getPlatformInfo().runtime}/${process.arch}`, - "archgate supports darwin/arm64, linux/x64, and win32/x64." + "archgate supports darwin/arm64, darwin/x64, linux/x64, and win32/x64." ); await exitWith(1); return; diff --git a/src/helpers/binary-upgrade.ts b/src/helpers/binary-upgrade.ts index 3ff3492b..48e56312 100644 --- a/src/helpers/binary-upgrade.ts +++ b/src/helpers/binary-upgrade.ts @@ -47,6 +47,13 @@ export function getArtifactInfo(): ArtifactInfo | null { binaryName: "archgate", }; } + if (platform === "darwin" && arch === "x64") { + return { + name: "archgate-darwin-x64", + ext: ".tar.gz", + binaryName: "archgate", + }; + } if (platform === "linux" && arch === "x64") { return { name: "archgate-linux-x64", diff --git a/tests/helpers/binary-upgrade-artifact.test.ts b/tests/helpers/binary-upgrade-artifact.test.ts index 316e6a50..22100f2a 100644 --- a/tests/helpers/binary-upgrade-artifact.test.ts +++ b/tests/helpers/binary-upgrade-artifact.test.ts @@ -38,7 +38,7 @@ describe("getArtifactInfo", () => { expect(info).not.toBeNull(); expect(info!.name).toMatch( - /^archgate-(darwin-arm64|linux-x64|win32-x64)$/u + /^archgate-(darwin-arm64|darwin-x64|linux-x64|win32-x64)$/u ); expect(info!.ext).toMatch(/^\.(tar\.gz|zip)$/u); expect(info!.binaryName).toMatch(/^archgate(\.exe)?$/u); @@ -46,10 +46,11 @@ describe("getArtifactInfo", () => { ); // Every published release target, resolved from a single runner. Gating each - // one on the real OS would leave two of the three uncovered on both CI - // platforms, since a skipped test counts for neither. + // one on the real OS would leave most of them uncovered on every CI + // platform, since a skipped test counts for none of them. const targets = [ ["darwin", "arm64", "archgate-darwin-arm64", ".tar.gz", "archgate"], + ["darwin", "x64", "archgate-darwin-x64", ".tar.gz", "archgate"], ["linux", "x64", "archgate-linux-x64", ".tar.gz", "archgate"], ["win32", "x64", "archgate-win32-x64", ".zip", "archgate.exe"], ] as const; @@ -67,7 +68,7 @@ describe("getArtifactInfo", () => { // at all — both fall through to the "no artifact" result that `upgrade` // turns into a manual-install hint. const unsupportedTargets = [ - ["darwin", "x64"], + ["darwin", "ia32"], ["linux", "arm64"], ["win32", "arm64"], ["freebsd", "x64"],