mirror of
https://github.com/alibaba/open-code-review.git
synced 2026-07-09 17:28:58 +00:00
feat(build): add Windows platform support (#13)
* feat(build): add Windows platform support Add windows/amd64 and windows/arm64 to CI build matrix, Makefile cross-platform targets, and handle .exe suffix in install/update scripts and binary wrapper. Skip chmod on Windows where unsupported. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(README): add Windows download instructions Add Windows x86_64 and ARM64 binary download commands to both English and Chinese README install sections. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
712d562691
commit
89effb6b22
8 changed files with 92 additions and 27 deletions
13
.github/workflows/release.yml
vendored
13
.github/workflows/release.yml
vendored
|
|
@ -21,6 +21,10 @@ jobs:
|
|||
goarch: amd64
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
- goos: windows
|
||||
goarch: amd64
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
|
@ -38,12 +42,17 @@ jobs:
|
|||
GIT_COMMIT=$(git rev-parse --short HEAD)
|
||||
BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
LD_FLAGS="-s -w -X main.Version=${VERSION} -X main.GitCommit=${GIT_COMMIT} -X main.BuildDate=${BUILD_DATE}"
|
||||
go build -ldflags "${LD_FLAGS}" -o opencodereview-${{ matrix.goos }}-${{ matrix.goarch }} ./cmd/opencodereview
|
||||
BIN_NAME=opencodereview-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
if [ "${{ matrix.goos }}" = "windows" ]; then
|
||||
BIN_NAME="${BIN_NAME}.exe"
|
||||
fi
|
||||
go build -ldflags "${LD_FLAGS}" -o "${BIN_NAME}" ./cmd/opencodereview
|
||||
echo "bin_name=${BIN_NAME}" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: binary-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
path: opencodereview-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
path: ${{ env.bin_name }}
|
||||
|
||||
release:
|
||||
needs: build
|
||||
|
|
|
|||
15
Makefile
15
Makefile
|
|
@ -1,6 +1,7 @@
|
|||
.PHONY: build test clean run help \
|
||||
build-all dist sha256sum version-info \
|
||||
build-linux-amd64 build-linux-arm64 build-darwin-amd64 build-darwin-arm64
|
||||
build-linux-amd64 build-linux-arm64 build-darwin-amd64 build-darwin-arm64 \
|
||||
build-windows-amd64 build-windows-arm64
|
||||
|
||||
BINARY_NAME := opencodereview
|
||||
GO := go
|
||||
|
|
@ -53,7 +54,17 @@ build-darwin-amd64:
|
|||
build-darwin-arm64:
|
||||
$(call BUILD_PLATFORM,darwin,arm64)
|
||||
|
||||
build-all: build-linux-amd64 build-linux-arm64 build-darwin-amd64 build-darwin-arm64
|
||||
build-windows-amd64:
|
||||
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 $(GO) build -ldflags "$(LD_FLAGS)" \
|
||||
-o $(DIST_DIR)/$(BINARY_NAME)-windows-amd64.exe \
|
||||
./cmd/opencodereview
|
||||
|
||||
build-windows-arm64:
|
||||
GOOS=windows GOARCH=arm64 CGO_ENABLED=0 $(GO) build -ldflags "$(LD_FLAGS)" \
|
||||
-o $(DIST_DIR)/$(BINARY_NAME)-windows-arm64.exe \
|
||||
./cmd/opencodereview
|
||||
|
||||
build-all: build-linux-amd64 build-linux-arm64 build-darwin-amd64 build-darwin-arm64 build-windows-amd64 build-windows-arm64
|
||||
|
||||
# Generate SHA256 checksums for all release binaries
|
||||
sha256sum: build-all
|
||||
|
|
|
|||
|
|
@ -89,6 +89,12 @@ chmod +x ocr && sudo mv ocr /usr/local/bin/ocr
|
|||
# Linux (ARM64)
|
||||
curl -Lo ocr https://github.com/alibaba/open-code-review/releases/latest/download/opencodereview-linux-arm64
|
||||
chmod +x ocr && sudo mv ocr /usr/local/bin/ocr
|
||||
|
||||
# Windows (x86_64)
|
||||
curl -Lo ocr.exe https://github.com/alibaba/open-code-review/releases/latest/download/opencodereview-windows-amd64.exe
|
||||
|
||||
# Windows (ARM64)
|
||||
curl -Lo ocr.exe https://github.com/alibaba/open-code-review/releases/latest/download/opencodereview-windows-arm64.exe
|
||||
```
|
||||
|
||||
**From Source**
|
||||
|
|
|
|||
|
|
@ -89,6 +89,12 @@ chmod +x ocr && sudo mv ocr /usr/local/bin/ocr
|
|||
# Linux (ARM64)
|
||||
curl -Lo ocr https://github.com/alibaba/open-code-review/releases/latest/download/opencodereview-linux-arm64
|
||||
chmod +x ocr && sudo mv ocr /usr/local/bin/ocr
|
||||
|
||||
# Windows (x86_64)
|
||||
curl -Lo ocr.exe https://github.com/alibaba/open-code-review/releases/latest/download/opencodereview-windows-amd64.exe
|
||||
|
||||
# Windows (ARM64)
|
||||
curl -Lo ocr.exe https://github.com/alibaba/open-code-review/releases/latest/download/opencodereview-windows-arm64.exe
|
||||
```
|
||||
|
||||
**从源码构建**
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ const path = require("path");
|
|||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
|
||||
const binaryPath = path.join(__dirname, "opencodereview");
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
const binaryPath = path.join(__dirname, IS_WINDOWS ? "opencodereview.exe" : "opencodereview");
|
||||
|
||||
if (!process.env.OCR_NO_UPDATE) {
|
||||
const stateDir = path.join(os.homedir(), ".opencodereview");
|
||||
|
|
|
|||
|
|
@ -89,30 +89,40 @@ func TestReleaseYmlMatchesURLPattern(t *testing.T) {
|
|||
pkg := loadPackageJSON(t)
|
||||
yml := loadFile(t, ".github/workflows/release.yml")
|
||||
|
||||
// Match: -o opencodereview-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
re := regexp.MustCompile(`go build[^\n]*-o\s+(opencodereview[^\n]*\}\})`)
|
||||
// Match: BIN_NAME=opencodereview-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
re := regexp.MustCompile(`BIN_NAME=(opencodereview[^\n]*\}\})`)
|
||||
m := re.FindStringSubmatch(yml)
|
||||
if m == nil {
|
||||
t.Fatal("cannot find 'go build -o' output pattern in release.yml")
|
||||
t.Fatal("cannot find BIN_NAME pattern in release.yml")
|
||||
}
|
||||
outputTemplate := strings.TrimSpace(strings.Split(m[1], " ./")[0])
|
||||
baseTemplate := strings.TrimSpace(m[1])
|
||||
|
||||
hasWindowsExe := strings.Contains(yml, `BIN_NAME="${BIN_NAME}.exe"`)
|
||||
|
||||
platforms := []struct{ os, arch string }{
|
||||
{"linux", "amd64"},
|
||||
{"linux", "arm64"},
|
||||
{"darwin", "amd64"},
|
||||
{"darwin", "arm64"},
|
||||
{"windows", "amd64"},
|
||||
{"windows", "arm64"},
|
||||
}
|
||||
for _, p := range platforms {
|
||||
rendered := outputTemplate
|
||||
rendered := baseTemplate
|
||||
rendered = strings.ReplaceAll(rendered, "${{ matrix.goos }}", p.os)
|
||||
rendered = strings.ReplaceAll(rendered, "${{ matrix.goarch }}", p.arch)
|
||||
if p.os == "windows" && hasWindowsExe {
|
||||
rendered += ".exe"
|
||||
}
|
||||
|
||||
url := pkg.OcrConfig.URLPattern
|
||||
url = strings.ReplaceAll(url, "{version}", "1.0.7")
|
||||
url = strings.ReplaceAll(url, "{os}", p.os)
|
||||
url = strings.ReplaceAll(url, "{arch}", p.arch)
|
||||
expected := extractFilenameFromURL(url)
|
||||
if p.os == "windows" {
|
||||
expected += ".exe"
|
||||
}
|
||||
|
||||
if rendered != expected {
|
||||
t.Errorf("release.yml produces %q, urlPattern expects %q", rendered, expected)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ const path = require("path");
|
|||
const https = require("https");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const BINARY_NAME = "opencodereview";
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
const BINARY_NAME = IS_WINDOWS ? "opencodereview.exe" : "opencodereview";
|
||||
|
||||
const packageRoot = path.join(__dirname, "..");
|
||||
const binDir = path.join(packageRoot, "bin");
|
||||
|
|
@ -25,7 +26,7 @@ function error(msg) {
|
|||
}
|
||||
|
||||
function detectPlatform() {
|
||||
const os = process.platform;
|
||||
let os = process.platform;
|
||||
let arch = process.arch;
|
||||
|
||||
switch (arch) {
|
||||
|
|
@ -41,10 +42,17 @@ function detectPlatform() {
|
|||
);
|
||||
}
|
||||
|
||||
if (os !== "linux" && os !== "darwin") {
|
||||
throw new Error(
|
||||
`Unsupported operating system: ${os}. Supported: linux, darwin`
|
||||
);
|
||||
switch (os) {
|
||||
case "linux":
|
||||
case "darwin":
|
||||
break;
|
||||
case "win32":
|
||||
os = "windows";
|
||||
break;
|
||||
default:
|
||||
throw new Error(
|
||||
`Unsupported operating system: ${os}. Supported: linux, darwin, win32`
|
||||
);
|
||||
}
|
||||
|
||||
return { os, arch };
|
||||
|
|
@ -157,21 +165,28 @@ async function main() {
|
|||
fs.mkdirSync(binDir, { recursive: true });
|
||||
}
|
||||
|
||||
const jsWrapper = path.join(binDir, "ocr.js");
|
||||
if (fs.existsSync(jsWrapper)) {
|
||||
try {
|
||||
fs.chmodSync(jsWrapper, 0o755);
|
||||
} catch (e) {
|
||||
warn(`Could not make ocr.js executable: ${e.message}`);
|
||||
if (!IS_WINDOWS) {
|
||||
const jsWrapper = path.join(binDir, "ocr.js");
|
||||
if (fs.existsSync(jsWrapper)) {
|
||||
try {
|
||||
fs.chmodSync(jsWrapper, 0o755);
|
||||
} catch (e) {
|
||||
warn(`Could not make ocr.js executable: ${e.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const vars = { version, os, arch };
|
||||
const downloadUrl = buildUrl(config.urlPattern, vars);
|
||||
let downloadUrl = buildUrl(config.urlPattern, vars);
|
||||
if (IS_WINDOWS) {
|
||||
downloadUrl += ".exe";
|
||||
}
|
||||
info(`Downloading ${downloadUrl} ...`);
|
||||
|
||||
await downloadBinary(downloadUrl, binaryDest);
|
||||
fs.chmodSync(binaryDest, 0o755);
|
||||
if (!IS_WINDOWS) {
|
||||
fs.chmodSync(binaryDest, 0o755);
|
||||
}
|
||||
|
||||
if (config.checksumPattern) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@ const {
|
|||
computeChecksum,
|
||||
} = require("./install.js");
|
||||
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
const BINARY_NAME = IS_WINDOWS ? "opencodereview.exe" : "opencodereview";
|
||||
const packageRoot = path.join(__dirname, "..");
|
||||
const binDir = path.join(packageRoot, "bin");
|
||||
const binaryPath = path.join(binDir, "opencodereview");
|
||||
const binaryPath = path.join(binDir, BINARY_NAME);
|
||||
const stateDir = path.join(os.homedir(), ".opencodereview");
|
||||
const tsFile = path.join(stateDir, "last-update-check");
|
||||
const lockFile = path.join(stateDir, "update.lock");
|
||||
|
|
@ -160,11 +162,16 @@ async function main() {
|
|||
const config = pkg.ocrConfig;
|
||||
|
||||
const vars = { version: latestVersion, os: platform, arch };
|
||||
const downloadUrl = buildUrl(config.urlPattern, vars);
|
||||
let downloadUrl = buildUrl(config.urlPattern, vars);
|
||||
if (IS_WINDOWS) {
|
||||
downloadUrl += ".exe";
|
||||
}
|
||||
|
||||
const tempPath = path.join(binDir, `.opencodereview.tmp.${process.pid}`);
|
||||
await downloadBinary(downloadUrl, tempPath);
|
||||
fs.chmodSync(tempPath, 0o755);
|
||||
if (!IS_WINDOWS) {
|
||||
fs.chmodSync(tempPath, 0o755);
|
||||
}
|
||||
|
||||
if (config.checksumPattern) {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue