merge: repair cross-platform release CI gating
This commit is contained in:
commit
d1df6fd920
25
.github/workflows/build-and-release.yml
vendored
25
.github/workflows/build-and-release.yml
vendored
@ -164,21 +164,36 @@ jobs:
|
||||
with:
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Set up Java 17 for Android
|
||||
if: ${{ matrix.platform == 'android' }}
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: "17"
|
||||
|
||||
- name: Preflight platform lane
|
||||
id: preflight
|
||||
shell: bash
|
||||
run: bash ./scripts/ci/platform_preflight.sh "$PLATFORM" "$SHOULD_RELEASE"
|
||||
|
||||
- name: Install platform dependencies
|
||||
if: ${{ steps.preflight.outputs.should_build_platform == 'true' }}
|
||||
shell: bash
|
||||
run: bash ./scripts/ci/setup_platform_deps.sh "$PLATFORM"
|
||||
|
||||
- name: Install Go
|
||||
if: ${{ matrix.platform == 'macos' }}
|
||||
if: ${{ matrix.platform == 'macos' && steps.preflight.outputs.should_build_platform == 'true' }}
|
||||
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff
|
||||
with:
|
||||
go-version: "1.24.1"
|
||||
|
||||
- name: Install platform dependencies
|
||||
shell: bash
|
||||
run: bash ./scripts/ci/setup_platform_deps.sh "$PLATFORM"
|
||||
|
||||
- name: Build platform artifacts
|
||||
if: ${{ steps.preflight.outputs.should_build_platform == 'true' }}
|
||||
shell: bash
|
||||
run: bash ./scripts/ci/build_matrix_artifacts.sh "$PLATFORM" "$ARCH" "$SHOULD_RELEASE"
|
||||
|
||||
- name: Upload build artifacts
|
||||
if: ${{ steps.preflight.outputs.should_build_platform == 'true' }}
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}
|
||||
|
||||
84
scripts/ci/apple_signing.sh
Normal file
84
scripts/ci/apple_signing.sh
Normal file
@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
apple_decode_base64() {
|
||||
if base64 --help 2>&1 | grep -q -- '--decode'; then
|
||||
base64 --decode
|
||||
else
|
||||
base64 -D
|
||||
fi
|
||||
}
|
||||
|
||||
apple_require_signing_vars() {
|
||||
local missing=()
|
||||
local var_name=""
|
||||
|
||||
for var_name in "$@"; do
|
||||
if [[ -z "${!var_name:-}" ]]; then
|
||||
missing+=("$var_name")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${#missing[@]}" -gt 0 ]]; then
|
||||
echo "Missing Apple signing secrets: ${missing[*]}" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
apple_register_cleanup() {
|
||||
local command="$1"
|
||||
APPLE_SIGNING_CLEANUP_COMMANDS+=("$command")
|
||||
}
|
||||
|
||||
apple_run_cleanup() {
|
||||
local status=$?
|
||||
local index=0
|
||||
|
||||
for (( index=${#APPLE_SIGNING_CLEANUP_COMMANDS[@]}-1; index>=0; index-- )); do
|
||||
eval "${APPLE_SIGNING_CLEANUP_COMMANDS[index]}" >/dev/null 2>&1 || true
|
||||
done
|
||||
|
||||
return "$status"
|
||||
}
|
||||
|
||||
apple_setup_signing_keychain() {
|
||||
apple_require_signing_vars \
|
||||
APPLE_CERT_P12_BASE64 \
|
||||
APPLE_CERT_PASSWORD \
|
||||
APPLE_KEYCHAIN_PASSWORD
|
||||
|
||||
local tmp_dir
|
||||
tmp_dir="$(mktemp -d "${RUNNER_TEMP:-/tmp}/xworkmate-apple.XXXXXX")"
|
||||
local keychain_name="xworkmate-build.keychain-db"
|
||||
local keychain_path="$HOME/Library/Keychains/$keychain_name"
|
||||
local cert_path="$tmp_dir/dist-cert.p12"
|
||||
|
||||
printf '%s' "$APPLE_CERT_P12_BASE64" | apple_decode_base64 > "$cert_path"
|
||||
|
||||
security create-keychain -p "$APPLE_KEYCHAIN_PASSWORD" "$keychain_name"
|
||||
security set-keychain-settings -lut 21600 "$keychain_path"
|
||||
security unlock-keychain -p "$APPLE_KEYCHAIN_PASSWORD" "$keychain_path"
|
||||
security import "$cert_path" -P "$APPLE_CERT_PASSWORD" -A -t cert -f pkcs12 -k "$keychain_path"
|
||||
security list-keychains -d user -s "$keychain_path"
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k "$APPLE_KEYCHAIN_PASSWORD" "$keychain_path"
|
||||
|
||||
export APPLE_SIGNING_TMP_DIR="$tmp_dir"
|
||||
export APPLE_SIGNING_KEYCHAIN_PATH="$keychain_path"
|
||||
|
||||
apple_register_cleanup "security delete-keychain \"$keychain_path\""
|
||||
apple_register_cleanup "rm -rf \"$tmp_dir\""
|
||||
}
|
||||
|
||||
apple_install_provision_profile() {
|
||||
local profile_name="${1:-xworkmate.mobileprovision}"
|
||||
|
||||
apple_require_signing_vars APPLE_PROVISION_PROFILE_BASE64
|
||||
|
||||
local profile_dir="$HOME/Library/MobileDevice/Provisioning Profiles"
|
||||
local profile_path="$profile_dir/$profile_name"
|
||||
|
||||
mkdir -p "$profile_dir"
|
||||
printf '%s' "$APPLE_PROVISION_PROFILE_BASE64" | apple_decode_base64 > "$profile_path"
|
||||
|
||||
export APPLE_SIGNING_PROFILE_PATH="$profile_path"
|
||||
apple_register_cleanup "rm -f \"$profile_path\""
|
||||
}
|
||||
@ -1,6 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
cd "$repo_root"
|
||||
eval "$(python3 "$repo_root/scripts/ci/build_version.py" --format shell)"
|
||||
platform="${1:?platform is required}"
|
||||
arch="${2:?arch is required}"
|
||||
should_release="${3:-false}"
|
||||
@ -17,7 +20,9 @@ case "$platform" in
|
||||
find dist -maxdepth 1 -name '*.dmg' -exec mv {} dist/macos/ \;
|
||||
;;
|
||||
windows)
|
||||
flutter build windows --release
|
||||
flutter build windows --release \
|
||||
--build-name="$PLATFORM_RELEASE_VERSION" \
|
||||
--build-number="$BUILD_NUMBER"
|
||||
pwsh -File ./scripts/package-windows-msi.ps1 -Arch "$arch"
|
||||
;;
|
||||
ios)
|
||||
@ -25,7 +30,11 @@ case "$platform" in
|
||||
bash ./scripts/package-ios-ipa.sh
|
||||
else
|
||||
echo "Release secrets not required for non-release runs; building unsigned iOS app bundle."
|
||||
flutter build ios --release --no-codesign
|
||||
flutter build ios --release --no-codesign \
|
||||
--build-name="$PLATFORM_RELEASE_VERSION" \
|
||||
--build-number="$BUILD_NUMBER" \
|
||||
--dart-define="XWORKMATE_DISPLAY_VERSION=$DISPLAY_VERSION" \
|
||||
--dart-define="XWORKMATE_BUILD_NUMBER=$BUILD_NUMBER"
|
||||
mkdir -p dist/ios
|
||||
(
|
||||
cd build/ios/iphoneos
|
||||
|
||||
108
scripts/ci/build_version.py
Normal file
108
scripts/ci/build_version.py
Normal file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Resolve platform-safe build versions from pubspec.yaml.
|
||||
|
||||
This repo keeps prerelease semantics in the pubspec version, for example:
|
||||
1.0.0-beta.2+4
|
||||
|
||||
Packaging metadata across Apple/Linux/Windows must use the numeric release
|
||||
portion only, while display-facing surfaces can keep the prerelease label.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import shlex
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
VERSION_PATTERN = re.compile(r"^version:\s*([^\n]+)", re.MULTILINE)
|
||||
RELEASE_PATTERN = re.compile(r"^\d+\.\d+\.\d+$")
|
||||
|
||||
|
||||
def parse_pubspec_version(pubspec_path: Path) -> dict[str, str]:
|
||||
text = pubspec_path.read_text(encoding="utf-8")
|
||||
match = VERSION_PATTERN.search(text)
|
||||
if match is None:
|
||||
raise ValueError(f"Unable to find version in {pubspec_path}")
|
||||
|
||||
raw_version = match.group(1).strip()
|
||||
if not raw_version:
|
||||
raise ValueError(f"Version in {pubspec_path} is empty")
|
||||
|
||||
if "+" in raw_version:
|
||||
display_version, build_number = raw_version.split("+", 1)
|
||||
else:
|
||||
display_version, build_number = raw_version, "1"
|
||||
|
||||
display_version = display_version.strip()
|
||||
build_number = build_number.strip()
|
||||
platform_release_version = display_version.split("-", 1)[0].strip()
|
||||
|
||||
if not RELEASE_PATTERN.fullmatch(platform_release_version):
|
||||
raise ValueError(
|
||||
"Expected pubspec version to expose a three-part numeric release "
|
||||
f"prefix before prerelease/build metadata, got: {raw_version}"
|
||||
)
|
||||
|
||||
if not build_number.isdigit():
|
||||
raise ValueError(f"Expected numeric build number in pubspec version, got: {raw_version}")
|
||||
|
||||
return {
|
||||
"raw_version": raw_version,
|
||||
"display_version": display_version,
|
||||
"platform_release_version": platform_release_version,
|
||||
"build_number": build_number,
|
||||
}
|
||||
|
||||
|
||||
def emit_shell(values: dict[str, str]) -> None:
|
||||
for key, value in values.items():
|
||||
env_key = key.upper()
|
||||
print(f"{env_key}={shlex.quote(value)}")
|
||||
|
||||
|
||||
def emit_json(values: dict[str, str]) -> None:
|
||||
print(json.dumps(values))
|
||||
|
||||
|
||||
def emit_github_output(values: dict[str, str]) -> None:
|
||||
for key, value in values.items():
|
||||
print(f"{key}={value}")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--pubspec",
|
||||
default="pubspec.yaml",
|
||||
help="Path to pubspec.yaml",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--format",
|
||||
choices=("shell", "json", "github-output"),
|
||||
default="json",
|
||||
help="Output format",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
values = parse_pubspec_version(Path(args.pubspec))
|
||||
|
||||
if args.format == "shell":
|
||||
emit_shell(values)
|
||||
elif args.format == "github-output":
|
||||
emit_github_output(values)
|
||||
else:
|
||||
emit_json(values)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
raise SystemExit(main())
|
||||
except Exception as exc: # pragma: no cover - CLI failure path
|
||||
print(str(exc), file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
@ -6,22 +6,25 @@ if [[ -z "${GITHUB_OUTPUT:-}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
eval "$(python3 "$repo_root/scripts/ci/build_version.py" --format shell)"
|
||||
|
||||
if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]]; then
|
||||
release_tag="${GITHUB_REF_NAME}"
|
||||
release_title="Release ${GITHUB_REF_NAME}"
|
||||
release_notes="Automated release for ${GITHUB_REF_NAME}"
|
||||
release_notes="Automated release for ${DISPLAY_VERSION}"
|
||||
elif [[ "${GITHUB_EVENT_NAME:-}" == "workflow_dispatch" ]]; then
|
||||
release_tag="manual-${GITHUB_RUN_NUMBER:-0}"
|
||||
release_title="Manual Build ${GITHUB_RUN_NUMBER:-0}"
|
||||
release_notes="Automated manual build from ${GITHUB_SHA:-unknown}"
|
||||
release_title="Manual Build ${GITHUB_RUN_NUMBER:-0} (${DISPLAY_VERSION})"
|
||||
release_notes="Automated manual build ${DISPLAY_VERSION} from ${GITHUB_SHA:-unknown}"
|
||||
elif [[ "${GITHUB_REF:-}" == "refs/heads/main" ]]; then
|
||||
release_tag="latest"
|
||||
release_title="Latest"
|
||||
release_notes="Automated latest main build from ${GITHUB_SHA:-unknown}"
|
||||
release_notes="Automated latest main build ${DISPLAY_VERSION} from ${GITHUB_SHA:-unknown}"
|
||||
else
|
||||
release_tag="main-${GITHUB_RUN_NUMBER:-0}"
|
||||
release_title="Main Build ${GITHUB_RUN_NUMBER:-0}"
|
||||
release_notes="Automated build from ${GITHUB_SHA:-unknown}"
|
||||
release_title="Main Build ${GITHUB_RUN_NUMBER:-0} (${DISPLAY_VERSION})"
|
||||
release_notes="Automated build ${DISPLAY_VERSION} from ${GITHUB_SHA:-unknown}"
|
||||
fi
|
||||
|
||||
{
|
||||
|
||||
95
scripts/ci/platform_preflight.sh
Normal file
95
scripts/ci/platform_preflight.sh
Normal file
@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
platform="${1:?platform is required}"
|
||||
should_release="${2:-false}"
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
emit_output() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
|
||||
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
|
||||
printf '%s=%s\n' "$key" "$value" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
printf '%s=%s\n' "$key" "$value"
|
||||
fi
|
||||
}
|
||||
|
||||
set_build_state() {
|
||||
local should_build="$1"
|
||||
local reason="$2"
|
||||
|
||||
emit_output "should_build_platform" "$should_build"
|
||||
emit_output "skip_reason" "$reason"
|
||||
|
||||
if [[ "$should_build" == "true" ]]; then
|
||||
echo "Preflight passed for $platform."
|
||||
else
|
||||
echo "Skipping $platform lane: $reason"
|
||||
fi
|
||||
}
|
||||
|
||||
case "$platform" in
|
||||
linux)
|
||||
set_build_state "true" ""
|
||||
;;
|
||||
windows)
|
||||
set_build_state "true" ""
|
||||
;;
|
||||
macos)
|
||||
required_vars=(
|
||||
APPLE_CERT_P12_BASE64
|
||||
APPLE_CERT_PASSWORD
|
||||
APPLE_KEYCHAIN_PASSWORD
|
||||
)
|
||||
|
||||
missing=()
|
||||
for var_name in "${required_vars[@]}"; do
|
||||
if [[ -z "${!var_name:-}" ]]; then
|
||||
missing+=("$var_name")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${#missing[@]}" -gt 0 ]]; then
|
||||
set_build_state "false" "missing macOS signing secrets: ${missing[*]}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set_build_state "true" ""
|
||||
;;
|
||||
ios)
|
||||
if [[ "$should_release" != "true" ]]; then
|
||||
set_build_state "true" ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
required_vars=(
|
||||
APPLE_CERT_P12_BASE64
|
||||
APPLE_CERT_PASSWORD
|
||||
APPLE_PROVISION_PROFILE_BASE64
|
||||
APPLE_KEYCHAIN_PASSWORD
|
||||
)
|
||||
|
||||
missing=()
|
||||
for var_name in "${required_vars[@]}"; do
|
||||
if [[ -z "${!var_name:-}" ]]; then
|
||||
missing+=("$var_name")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${#missing[@]}" -gt 0 ]]; then
|
||||
set_build_state "false" "missing iOS signing secrets: ${missing[*]}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set_build_state "true" ""
|
||||
;;
|
||||
android)
|
||||
set_build_state "true" ""
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported platform: $platform" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@ -2,6 +2,8 @@
|
||||
set -euo pipefail
|
||||
|
||||
platform="${1:?platform is required}"
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
cd "$repo_root"
|
||||
|
||||
case "$platform" in
|
||||
linux)
|
||||
@ -52,16 +54,14 @@ case "$platform" in
|
||||
|
||||
flutter_bin="$(command -v flutter)"
|
||||
flutter_root="$(cd "$(dirname "$flutter_bin")/.." && pwd)"
|
||||
app_version="$(sed -n 's/^version:[[:space:]]*//p' pubspec.yaml | head -n 1)"
|
||||
app_version="${app_version%%+*}"
|
||||
version_code="${GITHUB_RUN_NUMBER:-1}"
|
||||
eval "$(python3 "$repo_root/scripts/ci/build_version.py" --format shell)"
|
||||
|
||||
cat > android/local.properties <<EOF
|
||||
sdk.dir=$android_sdk_root
|
||||
flutter.sdk=$flutter_root
|
||||
flutter.buildMode=release
|
||||
flutter.versionName=$app_version
|
||||
flutter.versionCode=$version_code
|
||||
flutter.versionName=$DISPLAY_VERSION
|
||||
flutter.versionCode=$BUILD_NUMBER
|
||||
EOF
|
||||
;;
|
||||
macos)
|
||||
|
||||
@ -13,6 +13,9 @@ PRODUCTS_DIR_NAME="$(tr '[:lower:]' '[:upper:]' <<< "${BUILD_MODE:0:1}")${BUILD_
|
||||
FLUTTER_BUILD_STATE_DIR="${ROOT_DIR}/.dart_tool/flutter_build"
|
||||
MACOS_BUILD_DIR="${ROOT_DIR}/build/macos"
|
||||
NATIVE_ASSETS_DIR="${ROOT_DIR}/build/native_assets"
|
||||
source "$ROOT_DIR/scripts/ci/apple_signing.sh"
|
||||
APPLE_SIGNING_CLEANUP_COMMANDS=()
|
||||
trap apple_run_cleanup EXIT
|
||||
|
||||
remove_tree_with_retries() {
|
||||
local path="$1"
|
||||
@ -45,19 +48,13 @@ if [[ ! -f "$PUBSPEC_PATH" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION_LINE="$(sed -n 's/^version:[[:space:]]*//p' "$PUBSPEC_PATH" | head -n 1)"
|
||||
if [[ -z "$VERSION_LINE" ]]; then
|
||||
echo "Unable to read version from $PUBSPEC_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
eval "$(python3 "$ROOT_DIR/scripts/ci/build_version.py" --format shell)"
|
||||
BUILD_DATE_LINE="$(sed -n 's/^build-date:[[:space:]]*//p' "$PUBSPEC_PATH" | head -n 1)"
|
||||
BUILD_ID_LINE="$(sed -n 's/^build-id:[[:space:]]*//p' "$PUBSPEC_PATH" | head -n 1)"
|
||||
|
||||
APP_VERSION="${VERSION_LINE%%+*}"
|
||||
APP_BUILD="${VERSION_LINE#*+}"
|
||||
if [[ "$APP_BUILD" == "$VERSION_LINE" ]]; then
|
||||
APP_BUILD="1"
|
||||
fi
|
||||
APP_VERSION="$DISPLAY_VERSION"
|
||||
APP_RELEASE_VERSION="$PLATFORM_RELEASE_VERSION"
|
||||
APP_BUILD="$BUILD_NUMBER"
|
||||
APP_BUILD_DATE="${BUILD_DATE_LINE:-unknown}"
|
||||
APP_BUILD_COMMIT="${BUILD_ID_LINE:-unknown}"
|
||||
|
||||
@ -74,10 +71,19 @@ remove_tree_with_retries "$FLUTTER_BUILD_STATE_DIR"
|
||||
remove_tree_with_retries "$MACOS_BUILD_DIR"
|
||||
remove_tree_with_retries "$NATIVE_ASSETS_DIR"
|
||||
|
||||
if [[ -n "${APPLE_CERT_P12_BASE64:-}" &&
|
||||
-n "${APPLE_CERT_PASSWORD:-}" &&
|
||||
-n "${APPLE_KEYCHAIN_PASSWORD:-}" ]]; then
|
||||
echo "Provisioning Apple signing certificate for macOS build..."
|
||||
apple_setup_signing_keychain
|
||||
else
|
||||
echo "Apple signing secrets not set; using existing local macOS signing context."
|
||||
fi
|
||||
|
||||
BUILD_ARGS=(
|
||||
flutter build macos
|
||||
"--$BUILD_MODE"
|
||||
--build-name="$APP_VERSION"
|
||||
--build-name="$APP_RELEASE_VERSION"
|
||||
--build-number="$APP_BUILD"
|
||||
--dart-define="XWORKMATE_DISPLAY_VERSION=$APP_VERSION"
|
||||
--dart-define="XWORKMATE_BUILD_NUMBER=$APP_BUILD"
|
||||
|
||||
@ -4,17 +4,13 @@ set -euo pipefail
|
||||
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
dist_dir="$root_dir/dist/ios"
|
||||
export_method="${APPLE_EXPORT_METHOD:-ad-hoc}"
|
||||
app_store_define="${APP_STORE_DEFINE:---dart-define=XWORKMATE_APP_STORE=${XWORKMATE_APP_STORE:-true}}"
|
||||
source "$root_dir/scripts/ci/apple_signing.sh"
|
||||
APPLE_SIGNING_CLEANUP_COMMANDS=()
|
||||
trap apple_run_cleanup EXIT
|
||||
|
||||
mkdir -p "$dist_dir"
|
||||
|
||||
decode_base64() {
|
||||
if base64 --help 2>&1 | grep -q -- '--decode'; then
|
||||
base64 --decode
|
||||
else
|
||||
base64 -D
|
||||
fi
|
||||
}
|
||||
|
||||
required_vars=(
|
||||
APPLE_CERT_P12_BASE64
|
||||
APPLE_CERT_PASSWORD
|
||||
@ -34,36 +30,25 @@ if [[ "${#missing[@]}" -gt 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp_dir="$(mktemp -d "${RUNNER_TEMP:-/tmp}/xworkmate-ios.XXXXXX")"
|
||||
keychain_name="xworkmate-build.keychain-db"
|
||||
keychain_path="$HOME/Library/Keychains/$keychain_name"
|
||||
cert_path="$tmp_dir/dist-cert.p12"
|
||||
profile_path="$tmp_dir/profile.mobileprovision"
|
||||
eval "$(python3 "$root_dir/scripts/ci/build_version.py" --format shell)"
|
||||
app_version="$DISPLAY_VERSION"
|
||||
app_build="$BUILD_NUMBER"
|
||||
apple_setup_signing_keychain
|
||||
apple_install_provision_profile "xworkmate.mobileprovision"
|
||||
|
||||
tmp_dir="$APPLE_SIGNING_TMP_DIR"
|
||||
export_options_path="$tmp_dir/ExportOptions.plist"
|
||||
|
||||
cleanup() {
|
||||
security delete-keychain "$keychain_path" >/dev/null 2>&1 || true
|
||||
rm -rf "$tmp_dir"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
printf '%s' "$APPLE_CERT_P12_BASE64" | decode_base64 > "$cert_path"
|
||||
printf '%s' "$APPLE_PROVISION_PROFILE_BASE64" | decode_base64 > "$profile_path"
|
||||
|
||||
security create-keychain -p "$APPLE_KEYCHAIN_PASSWORD" "$keychain_name"
|
||||
security set-keychain-settings -lut 21600 "$keychain_path"
|
||||
security unlock-keychain -p "$APPLE_KEYCHAIN_PASSWORD" "$keychain_path"
|
||||
security import "$cert_path" -P "$APPLE_CERT_PASSWORD" -A -t cert -f pkcs12 -k "$keychain_path"
|
||||
security list-keychains -d user -s "$keychain_path"
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k "$APPLE_KEYCHAIN_PASSWORD" "$keychain_path"
|
||||
|
||||
mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles"
|
||||
cp "$profile_path" "$HOME/Library/MobileDevice/Provisioning Profiles/xworkmate.mobileprovision"
|
||||
|
||||
sed "s|\${EXPORT_METHOD}|$export_method|g" "$root_dir/ios/ExportOptions.plist" > "$export_options_path"
|
||||
|
||||
flutter pub get
|
||||
flutter build ipa --release --export-options-plist="$export_options_path"
|
||||
flutter build ipa --release \
|
||||
--build-name="$PLATFORM_RELEASE_VERSION" \
|
||||
--build-number="$app_build" \
|
||||
--dart-define="XWORKMATE_DISPLAY_VERSION=$app_version" \
|
||||
--dart-define="XWORKMATE_BUILD_NUMBER=$app_build" \
|
||||
"$app_store_define" \
|
||||
--export-options-plist="$export_options_path"
|
||||
|
||||
archive_path="$root_dir/build/ios/archive/Runner.xcarchive"
|
||||
if [[ -d "$archive_path" ]]; then
|
||||
|
||||
@ -3,14 +3,9 @@ set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
app_name="xworkmate"
|
||||
version="$(python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
text = Path("pubspec.yaml").read_text()
|
||||
match = re.search(r"^version:\s*([^\n+]+)", text, re.M)
|
||||
print(match.group(1) if match else "0.0.0")
|
||||
PY
|
||||
)"
|
||||
|
||||
eval "$(python3 "$repo_root/scripts/ci/build_version.py" --format shell)"
|
||||
package_version="${PLATFORM_RELEASE_VERSION}-${BUILD_NUMBER}"
|
||||
|
||||
build_dir="$repo_root/build/linux/x64/release/bundle"
|
||||
stage_dir="$repo_root/build/linux/deb-stage"
|
||||
@ -39,7 +34,7 @@ chmod 0755 "$stage_dir/DEBIAN/postinst" "$stage_dir/DEBIAN/postrm"
|
||||
|
||||
cat > "$stage_dir/DEBIAN/control" <<EOF
|
||||
Package: $app_name
|
||||
Version: $version
|
||||
Version: $package_version
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
@ -49,4 +44,4 @@ Description: XWorkmate Linux desktop shell with GNOME/KDE proxy and tunnel integ
|
||||
EOF
|
||||
|
||||
mkdir -p "$out_dir"
|
||||
dpkg-deb --build "$stage_dir" "$out_dir/${app_name}_${version}_amd64.deb"
|
||||
dpkg-deb --build "$stage_dir" "$out_dir/${app_name}_${package_version}_amd64.deb"
|
||||
|
||||
@ -3,14 +3,8 @@ set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
app_name="xworkmate"
|
||||
version="$(python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
text = Path("pubspec.yaml").read_text()
|
||||
match = re.search(r"^version:\s*([^\n+]+)", text, re.M)
|
||||
print(match.group(1) if match else "0.0.0")
|
||||
PY
|
||||
)"
|
||||
|
||||
eval "$(python3 "$repo_root/scripts/ci/build_version.py" --format shell)"
|
||||
|
||||
bundle_dir="$repo_root/build/linux/x64/release/bundle"
|
||||
rpm_root="$repo_root/build/linux/rpm"
|
||||
@ -34,8 +28,8 @@ cp "$repo_root/linux/packaging/icons/xworkmate.svg" \
|
||||
|
||||
cat > "$spec_file" <<EOF
|
||||
Name: $app_name
|
||||
Version: $version
|
||||
Release: 1%{?dist}
|
||||
Version: $PLATFORM_RELEASE_VERSION
|
||||
Release: $BUILD_NUMBER%{?dist}
|
||||
Summary: XWorkmate Linux desktop shell
|
||||
License: Proprietary
|
||||
BuildArch: x86_64
|
||||
|
||||
@ -3,5 +3,5 @@ set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
"$repo_root/scripts/package-linux-deb.sh"
|
||||
"$repo_root/scripts/package-linux-rpm.sh"
|
||||
bash "$repo_root/scripts/package-linux-deb.sh"
|
||||
bash "$repo_root/scripts/package-linux-rpm.sh"
|
||||
|
||||
@ -8,9 +8,13 @@ $root = Resolve-Path (Join-Path $PSScriptRoot "..")
|
||||
$sourceDir = Join-Path $root "build\windows\x64\runner\Release"
|
||||
$distDir = Join-Path $root "dist\windows"
|
||||
$wxsPath = Join-Path $root "packaging\windows\main.wxs"
|
||||
$versionLine = (Get-Content (Join-Path $root "pubspec.yaml") | Select-String '^version:\s*').ToString()
|
||||
$versionValue = ($versionLine -replace '^version:\s*', '').Split('+')[0]
|
||||
$msiPath = Join-Path $distDir "xworkmate-$versionValue-$Arch.msi"
|
||||
$metadataScript = (Join-Path $root "scripts\ci\build_version.py").Replace('\', '/')
|
||||
$metadata = (& python $metadataScript --format json | ConvertFrom-Json)
|
||||
$displayVersion = $metadata.display_version
|
||||
$platformReleaseVersion = $metadata.platform_release_version
|
||||
$buildNumber = $metadata.build_number
|
||||
Write-Host "Packaging Windows MSI for $displayVersion (build $buildNumber)"
|
||||
$msiPath = Join-Path $distDir "xworkmate-$displayVersion-$Arch.msi"
|
||||
$zipPath = Join-Path $distDir "xworkmate-windows-$Arch.zip"
|
||||
|
||||
if (-not (Test-Path $sourceDir)) {
|
||||
@ -24,15 +28,10 @@ if (Test-Path $zipPath) {
|
||||
}
|
||||
Compress-Archive -Path (Join-Path $sourceDir '*') -DestinationPath $zipPath
|
||||
|
||||
$wixVersion = $versionValue
|
||||
if ($wixVersion -notmatch '^\d+\.\d+\.\d+$') {
|
||||
$wixVersion = "0.0.0"
|
||||
}
|
||||
|
||||
& wix build $wxsPath `
|
||||
-arch x64 `
|
||||
-d SourceDir=$sourceDir `
|
||||
-d ProductVersion=$wixVersion `
|
||||
-d ProductVersion=$platformReleaseVersion `
|
||||
-o $msiPath
|
||||
|
||||
if ($env:WINDOWS_PFX_BASE64 -and $env:WINDOWS_PFX_PASSWORD) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user