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
4 changes: 2 additions & 2 deletions .archgate/adrs/ARCH-017-multi-ecosystem-distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}...`
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-shims.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
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
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/release-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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` |

Expand Down
1 change: 1 addition & 0 deletions docs/src/content/docs/getting-started/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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` |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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` |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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` |

Expand Down
10 changes: 3 additions & 7 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions shims/go/internal/shim/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down
2 changes: 2 additions & 0 deletions shims/go/internal/shim/shim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down
5 changes: 4 additions & 1 deletion shims/maven/src/main/java/dev/archgate/cli/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand All @@ -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.");
}

/**
Expand Down
6 changes: 6 additions & 0 deletions shims/maven/src/test/java/dev/archgate/cli/ShimTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion shims/npm/archgate.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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.`
);
}

Expand Down
10 changes: 8 additions & 2 deletions shims/npm/test/archgate.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
});
Expand All @@ -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"));
});
Expand Down
4 changes: 3 additions & 1 deletion shims/nuget/Archgate.Tool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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."
);
}

Expand Down
2 changes: 2 additions & 0 deletions shims/nuget/tests/Archgate.Tool.Tests/ShimTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -38,6 +39,7 @@ public void GetArtifactName_ReturnsOneOfKnownArtifacts()
Assert.Contains(artifact, new[]
{
"archgate-darwin-arm64",
"archgate-darwin-x64",
"archgate-linux-x64",
"archgate-win32-x64",
});
Expand Down
3 changes: 2 additions & 1 deletion shims/pypi/archgate/_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions shims/pypi/tests/test_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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",
}
Expand Down
3 changes: 2 additions & 1 deletion shims/rubygem/lib/archgate/shim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions shims/rubygem/test/test_shim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/commands/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ async function upgradeBinary(tag: string): Promise<void> {
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;
Expand Down
7 changes: 7 additions & 0 deletions src/helpers/binary-upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
9 changes: 5 additions & 4 deletions tests/helpers/binary-upgrade-artifact.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,19 @@ 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);
}
);

// 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;
Expand All @@ -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"],
Expand Down
Loading