chore: prepare v1.1.3 release metadata

This commit is contained in:
Haitao Pan 2026-05-28 13:20:57 +08:00
parent 9dad6125b1
commit 8469537060
7 changed files with 107 additions and 76 deletions

View File

@ -20,7 +20,7 @@ APP_DART_DEFINE_BUILD ?= --dart-define=XWORKMATE_BUILD_NUMBER=$(APP_BUILD_NUMBER
APP_DART_DEFINE_BUILD_DATE ?= --dart-define=XWORKMATE_BUILD_DATE=$(APP_BUILD_DATE) APP_DART_DEFINE_BUILD_DATE ?= --dart-define=XWORKMATE_BUILD_DATE=$(APP_BUILD_DATE)
APP_DART_DEFINE_BUILD_COMMIT ?= --dart-define=XWORKMATE_BUILD_COMMIT=$(APP_BUILD_COMMIT) APP_DART_DEFINE_BUILD_COMMIT ?= --dart-define=XWORKMATE_BUILD_COMMIT=$(APP_BUILD_COMMIT)
.PHONY: help deps analyze test test-all test-flutter test-golden test-integration test-integration-macos test-patrol test-go test-ci check format run open-macos-xcode sync-version build-linux build-macos build-ios-sim ios-pods ios-pods-check build-ios-release-no-codesign verify-ios-release package-deb package-rpm package-linux package-mac install-mac clean build-go-core render-release-docs docs-public-api check-export-compliance test-real-env-login-chain inspect-xworkmate-bridge-service test-api-contract test-api-scenario-contract check-api-external .PHONY: help deps analyze test test-all test-flutter test-golden test-integration test-integration-macos test-patrol test-go test-ci check format run open-macos-xcode sync-version build-linux build-macos build-ios-sim ios-pods ios-pods-check build-ios-release-no-codesign verify-ios-release package-deb package-rpm package-linux package-mac install-mac clean render-release-docs docs-public-api check-export-compliance test-real-env-login-chain inspect-xworkmate-bridge-service test-api-contract test-api-scenario-contract check-api-external
help: ## Show available targets help: ## Show available targets
@grep -E '^[a-zA-Z0-9_.-]+:.*?## ' Makefile | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-18s %s\n", $$1, $$2}' @grep -E '^[a-zA-Z0-9_.-]+:.*?## ' Makefile | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-18s %s\n", $$1, $$2}'
@ -119,9 +119,6 @@ build-ios-release-no-codesign: ios-pods-check ## Build the iOS device app in rel
verify-ios-release: ios-pods-check build-ios-release-no-codesign analyze ## Regenerate pods, build iOS release without codesigning, and run static analysis verify-ios-release: ios-pods-check build-ios-release-no-codesign analyze ## Regenerate pods, build iOS release without codesigning, and run static analysis
build-go-core: ## Build the external ACP bridge helper from xworkmate-bridge
bash scripts/build-go-core.sh
package-deb: ## Create the Linux .deb package package-deb: ## Create the Linux .deb package
bash scripts/package-linux-deb.sh bash scripts/package-linux-deb.sh
@ -131,7 +128,7 @@ package-rpm: ## Create the Linux .rpm package
package-linux: ## Create both Linux packages package-linux: ## Create both Linux packages
bash scripts/package-linux.sh bash scripts/package-linux.sh
package-mac: build-go-core ## Create the macOS .app and DMG package-mac: ## Create the macOS .app and DMG
XWORKMATE_APP_STORE=true bash scripts/package-flutter-mac-app.sh XWORKMATE_APP_STORE=true bash scripts/package-flutter-mac-app.sh
install-mac: package-mac ## Package and install the macOS app into /Applications install-mac: package-mac ## Package and install the macOS app into /Applications

View File

@ -41,13 +41,13 @@ Last Updated: 2026-04-13
## Build Contract ## Build Contract
`xworkmate-app` 仍然消费名为 `xworkmate-go-core` 的 helper artifact `xworkmate-app` 不再构建、嵌入或启动本地 ACP bridge helper
这表示: 这表示:
- helper 从 `xworkmate-bridge` 构建 - macOS 打包不再从 `xworkmate-bridge` sibling repo 构建 `xworkmate-go-core`
- app 负责定位与调用 helper - app bundle 不再携带 `xworkmate-go-core` 或本地 ACP bridge 启动脚本
- helper 内部的 bridge/runtime 行为以 bridge repo 为准,不再在 app repo 内保留并列设计文档 - app 端只消费托管 `xworkmate-bridge` capability、routing、gateway runtime 合同
## Operational Note ## Operational Note

View File

@ -548,9 +548,9 @@ class GatewayRuntime extends ChangeNotifier with GatewayRuntimeHelpersInternal {
await connectProfile( await connectProfile(
GatewayConnectionProfile.defaultsGateway().copyWith( GatewayConnectionProfile.defaultsGateway().copyWith(
mode: RuntimeConnectionMode.remote, mode: RuntimeConnectionMode.remote,
host: '127.0.0.1', host: Uri.parse(kManagedBridgeServerUrl).host,
port: 18789, port: 443,
tls: false, tls: true,
selectedAgentId: selectedAgentId, selectedAgentId: selectedAgentId,
), ),
); );

View File

@ -3,8 +3,8 @@ description: "XWorkmate desktop-first AI workspace shell."
publish_to: 'none' publish_to: 'none'
version: 1.1.3+1 version: 1.1.3+1
build-date: 2026-05-27 build-date: 2026-05-28
build-id: 8cb97a0 build-id: 82d46f5
environment: environment:
sdk: ^3.11.0 sdk: ^3.11.0

View File

@ -1,42 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
DEFAULT_BRIDGE_DIR=""
for candidate in "$ROOT_DIR/../xworkmate-bridge" "$ROOT_DIR/../../xworkmate-bridge"
do
if [[ -f "$candidate/go.mod" ]]; then
DEFAULT_BRIDGE_DIR="$candidate"
break
fi
done
BRIDGE_DIR="${XWORKMATE_BRIDGE_DIR:-$DEFAULT_BRIDGE_DIR}"
OUTPUT_DIR="${OUTPUT_DIR:-$ROOT_DIR/build/bin}"
OUTPUT_PATH_BASE="${OUTPUT_DIR}/xworkmate-go-core"
if [[ "$(uname -s)" == *MINGW* || "$(uname -s)" == *MSYS* || "$(uname -s)" == *CYGWIN* ]]; then
OUTPUT_PATH="${OUTPUT_PATH:-${OUTPUT_PATH_BASE}.exe}"
else
OUTPUT_PATH="${OUTPUT_PATH:-${OUTPUT_PATH_BASE}}"
fi
if [[ ! -f "$BRIDGE_DIR/go.mod" ]]; then
echo "Missing xworkmate-bridge repo or go.mod in $BRIDGE_DIR" >&2
exit 1
fi
if ! command -v go >/dev/null 2>&1; then
echo "Go toolchain is required to build xworkmate-go-core" >&2
exit 1
fi
mkdir -p "$OUTPUT_DIR"
echo "Building xworkmate-go-core from xworkmate-bridge..."
(
cd "$BRIDGE_DIR"
GO111MODULE=on go build -o "$OUTPUT_PATH" .
)
chmod +x "$OUTPUT_PATH"
echo "Built: $OUTPUT_PATH"

View File

@ -104,18 +104,6 @@ if [[ ! -d "$BUILD_APP_PATH" ]]; then
exit 1 exit 1
fi fi
# Embed xworkmate-go-core for local/non-App-Store builds if available
if [[ "${XWORKMATE_APP_STORE:-}" != "true" ]]; then
SOURCE_GO_CORE="$ROOT_DIR/build/bin/xworkmate-go-core"
# lib/runtime/go_core.dart expects it under build/bin relative to one of the roots
TARGET_GO_CORE="$BUILD_APP_PATH/Contents/MacOS/build/bin/xworkmate-go-core"
if [[ -f "$SOURCE_GO_CORE" ]]; then
echo "Embedding xworkmate-go-core into app bundle..."
mkdir -p "$(dirname "$TARGET_GO_CORE")"
cp "$SOURCE_GO_CORE" "$TARGET_GO_CORE"
fi
fi
verify_bundle_signature() { verify_bundle_signature() {
local app_path="$1" local app_path="$1"
echo "Verifying code signature: $app_path" echo "Verifying code signature: $app_path"
@ -147,17 +135,11 @@ find "$DIST_APP_PATH/Contents/Frameworks" -name "*.framework" -type d | while re
codesign --force --sign "${SIGN_IDENTITY:--}" --timestamp=none "$framework" codesign --force --sign "${SIGN_IDENTITY:--}" --timestamp=none "$framework"
done done
# 2. Sign our manually added binaries if any # 2. Sign the main executable
if [[ -f "$DIST_APP_PATH/Contents/MacOS/build/bin/xworkmate-go-core" ]]; then
echo "Signing embedded helper: xworkmate-go-core"
codesign --force --sign "${SIGN_IDENTITY:--}" --timestamp=none "$DIST_APP_PATH/Contents/MacOS/build/bin/xworkmate-go-core"
fi
# 3. Sign the main executable
echo "Signing main executable..." echo "Signing main executable..."
codesign --force --sign "${SIGN_IDENTITY:--}" --timestamp=none "$DIST_APP_PATH/Contents/MacOS/$APP_NAME" codesign --force --sign "${SIGN_IDENTITY:--}" --timestamp=none "$DIST_APP_PATH/Contents/MacOS/$APP_NAME"
# 4. Finally sign the app bundle itself # 3. Finally sign the app bundle itself
echo "Signing app bundle..." echo "Signing app bundle..."
codesign --force --sign "${SIGN_IDENTITY:--}" --timestamp=none "$DIST_APP_PATH" codesign --force --sign "${SIGN_IDENTITY:--}" --timestamp=none "$DIST_APP_PATH"

View File

@ -1,7 +1,11 @@
import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:xworkmate/app/app_controller.dart'; import 'package:xworkmate/app/app_controller.dart';
import 'package:xworkmate/runtime/device_identity_store.dart';
import 'package:xworkmate/runtime/gateway_runtime.dart';
import 'package:xworkmate/runtime/gateway_runtime_session_client.dart';
import 'package:xworkmate/runtime/mode_switcher.dart'; import 'package:xworkmate/runtime/mode_switcher.dart';
import 'package:xworkmate/runtime/runtime_models.dart'; import 'package:xworkmate/runtime/runtime_models.dart';
import 'package:xworkmate/runtime/secure_config_store.dart'; import 'package:xworkmate/runtime/secure_config_store.dart';
@ -178,5 +182,95 @@ void main() {
); );
}, },
); );
test(
'session client bootstrap uses the managed bridge instead of local ACP',
() async {
final storeRoot = await Directory.systemTemp.createTemp(
'xworkmate-bridge-session-bootstrap-',
);
addTearDown(() async {
if (await storeRoot.exists()) {
try {
await storeRoot.delete(recursive: true);
} on FileSystemException {
// Temp cleanup is best effort while Flutter test teardown releases IO.
}
}
});
final store = SecureConfigStore(
secretRootPathResolver: () async => '${storeRoot.path}/secrets',
appDataRootPathResolver: () async => '${storeRoot.path}/app-data',
supportRootPathResolver: () async => '${storeRoot.path}/support',
enableSecureStorage: false,
);
await store.initialize();
final sessionClient = _CapturingGatewayRuntimeSessionClient();
final runtime = GatewayRuntime(
store: store,
identityStore: DeviceIdentityStore(store),
sessionClient: sessionClient,
runtimeId: 'runtime-session-bootstrap-test',
);
addTearDown(runtime.dispose);
await runtime.initialize();
await runtime.ensureBridgeSessionConnected(selectedAgentId: 'codex');
final request = sessionClient.lastConnectRequest;
expect(request, isNotNull);
expect(request!.mode, RuntimeConnectionMode.remote);
expect(request.host, Uri.parse(kManagedBridgeServerUrl).host);
expect(request.port, 443);
expect(request.tls, isTrue);
expect(request.host, isNot(anyOf('127.0.0.1', 'localhost')));
},
);
}); });
} }
class _CapturingGatewayRuntimeSessionClient
implements GatewayRuntimeSessionClient {
final StreamController<GatewayRuntimeSessionUpdate> _updates =
StreamController<GatewayRuntimeSessionUpdate>.broadcast();
GatewayRuntimeSessionConnectRequest? lastConnectRequest;
@override
Stream<GatewayRuntimeSessionUpdate> get updates => _updates.stream;
@override
Future<GatewayRuntimeSessionConnectResult> connect(
GatewayRuntimeSessionConnectRequest request,
) async {
lastConnectRequest = request;
return GatewayRuntimeSessionConnectResult(
snapshot: GatewayConnectionSnapshot.initial(mode: request.mode).copyWith(
status: RuntimeConnectionStatus.connected,
statusText: 'Connected',
remoteAddress: '${request.host}:${request.port}',
deviceId: request.identity.deviceId,
),
auth: const <String, dynamic>{'role': 'operator'},
returnedDeviceToken: '',
raw: const <String, dynamic>{},
);
}
@override
Future<void> disconnect({required String runtimeId}) async {}
@override
Future<dynamic> request({
required String runtimeId,
required String method,
Map<String, dynamic>? params,
Duration timeout = const Duration(seconds: 15),
}) {
throw UnimplementedError('request is not used by this cleanup test');
}
@override
Future<void> dispose() => _updates.close();
}