diff --git a/README.md b/README.md index 1dac1eb..2c37934 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ jobs: | Name | Type | Default | Description | | ----- | ------- | ------------------------ | ---------------------------------------------------------------------------------------------- | -| tag | String | 0.16.0-dev.312+164c598cd | zig version which will download from [zig-patch](https://github.com/openharmony-zig/zig-patch) | +| tag | String | 0.16.0 | zig version which will download from [zig-patch](https://github.com/openharmony-zig/zig-patch) | | cache | Boolean | true | Uses the GitHub actions cache to cache the SDK when enabled. | ## Support Platforms @@ -34,6 +34,12 @@ jobs: - [x] x86_64 window - [x] x86_64 linux for musl - [x] x86_64 linux for gnu +- [x] aarch64 OpenHarmony +- [x] armv7a OpenHarmony +- [x] x86_64 OpenHarmony + +The installer prefers `.tar.xz` release assets and falls back to `.tar.gz` for +older releases. It exits with an error when neither archive is available. ## License diff --git a/action.yml b/action.yml index d31092a..cb24cf4 100644 --- a/action.yml +++ b/action.yml @@ -4,7 +4,7 @@ inputs: tag: description: 'Zig OHOS release tag' required: false - default: '0.16.0-dev.312+164c598cd' + default: '0.16.0' cache: description: "Whether to cache the Zig installation or not" required: false @@ -43,4 +43,4 @@ runs: env: INPUT_TAG: "${{ inputs.tag }}" INPUT_CACHE: "${{ inputs.cache }}" - INPUT_WAS_CACHED: "${{ steps.cache.outputs.cache-hit }}" \ No newline at end of file + INPUT_WAS_CACHED: "${{ steps.cache.outputs.cache-hit }}" diff --git a/install.sh b/install.sh index d787ef1..4faff35 100755 --- a/install.sh +++ b/install.sh @@ -8,23 +8,43 @@ set -eux # Base URL for Zig OHOS releases URL_BASE="https://github.com/openharmony-zig/zig-patch/releases/download" -# Determine platform and set OS_FILENAME -if [[ "$OSTYPE" == "linux-musl"* ]]; then - OS_FILENAME="zig-x86_64-linux-musl-baseline.tar.gz" +# Determine platform and set the archive basename +if [[ "$OSTYPE" == "linux-ohos"* ]] || [[ "$OSTYPE" == "ohos"* ]]; then + case "$(uname -m)" in + aarch64|arm64) + OS_ARCHIVE_BASENAME="zig-aarch64-linux-ohos-baseline" + OS="ohos-arm64" + ;; + arm|armv7l|armeabi-v7a) + OS_ARCHIVE_BASENAME="zig-arm-linux-ohoseabi-generic+v7a" + OS="ohos-arm" + ;; + x86_64|amd64) + OS_ARCHIVE_BASENAME="zig-x86_64-linux-ohos-baseline" + OS="ohos-x86_64" + ;; + *) + echo "Error: Unsupported OpenHarmony architecture: $(uname -m)" + echo "Supported OpenHarmony architectures: aarch64, armv7a, x86_64" + exit 1 + ;; + esac +elif [[ "$OSTYPE" == "linux-musl"* ]]; then + OS_ARCHIVE_BASENAME="zig-x86_64-linux-musl-baseline" OS="linux-musl" elif [[ "$OSTYPE" == "linux-gnu"* ]]; then - OS_FILENAME="zig-x86_64-linux-gnu-baseline.tar.gz" + OS_ARCHIVE_BASENAME="zig-x86_64-linux-gnu-baseline" OS="linux-gnu" elif [[ "$OSTYPE" == "darwin"* ]]; then if [[ $(uname -m) == 'arm64' ]]; then - OS_FILENAME="zig-aarch64-macos-none-baseline.tar.gz" + OS_ARCHIVE_BASENAME="zig-aarch64-macos-none-baseline" OS="macos-arm64" else echo "Error: Only ARM64 macOS is supported" exit 1 fi elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then - OS_FILENAME="zig-x86_64-windows-gnu-baseline.tar.gz" + OS_ARCHIVE_BASENAME="zig-x86_64-windows-gnu-baseline" OS="windows" else echo "Error: Unsupported OS type. Supported platforms:" @@ -32,6 +52,9 @@ else echo " - x86_64 Windows" echo " - x86_64 Linux (musl)" echo " - x86_64 Linux (gnu)" + echo " - aarch64 OpenHarmony" + echo " - armv7a OpenHarmony" + echo " - x86_64 OpenHarmony" exit 1 fi @@ -105,8 +128,28 @@ fi # URL encode the tag for proper download URL ENCODED_TAG=$(echo "$INPUT_TAG" | sed 's/+/%2B/g') -# Construct download URL -DOWNLOAD_URL="${URL_BASE}/${ENCODED_TAG}/${OS_FILENAME}" +# Prefer the xz archive, while retaining compatibility with older releases +# that only provide a gz archive. +XZ_DOWNLOAD_URL="${URL_BASE}/${ENCODED_TAG}/${OS_ARCHIVE_BASENAME}.tar.xz" +GZ_DOWNLOAD_URL="${URL_BASE}/${ENCODED_TAG}/${OS_ARCHIVE_BASENAME}.tar.gz" + +archive_exists() { + curl -L --fail --silent --head --max-time 60 --output /dev/null "$1" 2>/dev/null +} + +if archive_exists "$XZ_DOWNLOAD_URL"; then + DOWNLOAD_URL="$XZ_DOWNLOAD_URL" + ARCHIVE_FILE="zig-ohos.tar.xz" +elif archive_exists "$GZ_DOWNLOAD_URL"; then + DOWNLOAD_URL="$GZ_DOWNLOAD_URL" + ARCHIVE_FILE="zig-ohos.tar.gz" +else + echo "Error: No Zig OHOS archive found for ${OS} at tag ${INPUT_TAG}" + echo "Checked:" + echo " - ${XZ_DOWNLOAD_URL}" + echo " - ${GZ_DOWNLOAD_URL}" + exit 1 +fi echo "Downloading Zig OHOS from ${DOWNLOAD_URL}" @@ -115,7 +158,7 @@ RETRY_COUNT=0 MAX_RETRIES=3 while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do - if curl -L --fail --show-error --silent --max-time 300 -o "zig-ohos.tar.gz" "$DOWNLOAD_URL"; then + if curl -L --fail --show-error --silent --max-time 300 -o "$ARCHIVE_FILE" "$DOWNLOAD_URL"; then echo "Download completed successfully" break else @@ -133,14 +176,14 @@ while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do done # Verify download -if [[ ! -f "zig-ohos.tar.gz" ]] || [[ ! -s "zig-ohos.tar.gz" ]]; then +if [[ ! -f "$ARCHIVE_FILE" ]] || [[ ! -s "$ARCHIVE_FILE" ]]; then echo "Error: Downloaded file is missing or empty" exit 1 fi # Extract the archive echo "Extracting Zig OHOS..." -tar -xf "zig-ohos.tar.gz" +tar -xf "$ARCHIVE_FILE" # Find the extracted directory (should start with 'zig-') ZIG_EXTRACTED_DIR=$(find . -maxdepth 1 -name "zig-*" -type d | head -n 1) @@ -148,7 +191,7 @@ ZIG_EXTRACTED_DIR=$(find . -maxdepth 1 -name "zig-*" -type d | head -n 1) if [[ -z "$ZIG_EXTRACTED_DIR" ]]; then echo "Error: Could not find extracted Zig directory" echo "Archive contents:" - tar -tzf "zig-ohos.tar.gz" | head -10 + tar -tf "$ARCHIVE_FILE" | head -10 exit 1 fi @@ -166,7 +209,7 @@ else fi # Clean up the archive -rm "zig-ohos.tar.gz" +rm "$ARCHIVE_FILE" # Make sure the executable is executable (for Unix-like systems) if [[ "$OS" != "windows" ]]; then diff --git a/tests/install.bash b/tests/install.bash new file mode 100755 index 0000000..2232f65 --- /dev/null +++ b/tests/install.bash @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +set -euo pipefail +export LC_ALL=C + +ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +MOCK_BIN="${ROOT_DIR}/tests/mocks" +TEST_DIR=$(mktemp -d "${TMPDIR:-/tmp}/setup-zig-ohos-tests.XXXXXX") +trap 'rm -rf "$TEST_DIR"' EXIT + +mkdir -p "$TEST_DIR/fixtures/zig-fixture" +printf '#!/usr/bin/env bash\necho 0.16.0-test\n' > "$TEST_DIR/fixtures/zig-fixture/zig" +chmod +x "$TEST_DIR/fixtures/zig-fixture/zig" +tar -C "$TEST_DIR/fixtures" -cJf "$TEST_DIR/fixtures/zig.tar.xz" zig-fixture +tar -C "$TEST_DIR/fixtures" -czf "$TEST_DIR/fixtures/zig.tar.gz" zig-fixture + +assert_contains() { + local file="$1" + local expected="$2" + + if ! grep -Fq "$expected" "$file"; then + echo "Expected to find '$expected' in $file" >&2 + sed -n '1,200p' "$file" >&2 + exit 1 + fi +} + +run_success_case() { + local name="$1" + local architecture="$2" + local available="$3" + local expected_archive="$4" + local expected_platform="$5" + local case_dir="$TEST_DIR/$name" + + mkdir -p "$case_dir/home" + : > "$case_dir/github-path" + : > "$case_dir/github-output" + : > "$case_dir/curl.log" + + env \ + PATH="$MOCK_BIN:$PATH" \ + HOME="$case_dir/home" \ + OSTYPE="linux-ohos" \ + INPUT_TAG="test+tag" \ + INPUT_CACHE="false" \ + INPUT_WAS_CACHED="false" \ + GITHUB_PATH="$case_dir/github-path" \ + GITHUB_OUTPUT="$case_dir/github-output" \ + MOCK_UNAME_M="$architecture" \ + MOCK_AVAILABLE="$available" \ + MOCK_FIXTURES="$TEST_DIR/fixtures" \ + MOCK_CURL_LOG="$case_dir/curl.log" \ + bash "$ROOT_DIR/install.sh" > "$case_dir/install.log" 2>&1 + + assert_contains "$case_dir/curl.log" "head https://github.com/openharmony-zig/zig-patch/releases/download/test%2Btag/${expected_archive}.tar.xz" + assert_contains "$case_dir/curl.log" "download https://github.com/openharmony-zig/zig-patch/releases/download/test%2Btag/${expected_archive}.tar.${available}" + assert_contains "$case_dir/github-output" "zig-version=0.16.0-test" + assert_contains "$case_dir/github-output" "platform=${expected_platform}" +} + +run_success_case \ + ohos-aarch64 aarch64 xz \ + zig-aarch64-linux-ohos-baseline ohos-arm64 +run_success_case \ + ohos-armv7 armv7l xz \ + 'zig-arm-linux-ohoseabi-generic+v7a' ohos-arm +run_success_case \ + ohos-x86_64 x86_64 xz \ + zig-x86_64-linux-ohos-baseline ohos-x86_64 +run_success_case \ + gz-fallback aarch64 gz \ + zig-aarch64-linux-ohos-baseline ohos-arm64 + +missing_dir="$TEST_DIR/missing" +mkdir -p "$missing_dir/home" +: > "$missing_dir/github-path" +: > "$missing_dir/github-output" +: > "$missing_dir/curl.log" + +if env \ + PATH="$MOCK_BIN:$PATH" \ + HOME="$missing_dir/home" \ + OSTYPE="linux-ohos" \ + INPUT_TAG="missing" \ + INPUT_CACHE="false" \ + INPUT_WAS_CACHED="false" \ + GITHUB_PATH="$missing_dir/github-path" \ + GITHUB_OUTPUT="$missing_dir/github-output" \ + MOCK_UNAME_M="aarch64" \ + MOCK_AVAILABLE="none" \ + MOCK_FIXTURES="$TEST_DIR/fixtures" \ + MOCK_CURL_LOG="$missing_dir/curl.log" \ + bash "$ROOT_DIR/install.sh" > "$missing_dir/install.log" 2>&1; then + echo "Expected the missing archive case to fail" >&2 + exit 1 +fi + +assert_contains "$missing_dir/curl.log" ".tar.xz" +assert_contains "$missing_dir/curl.log" ".tar.gz" +assert_contains "$missing_dir/install.log" "Error: No Zig OHOS archive found" + +echo "All install tests passed" diff --git a/tests/mocks/curl b/tests/mocks/curl new file mode 100755 index 0000000..a612982 --- /dev/null +++ b/tests/mocks/curl @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -eu + +is_head=false +output_file="" +url="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --head) + is_head=true + shift + ;; + -o|--output) + output_file="$2" + shift 2 + ;; + *) + url="$1" + shift + ;; + esac +done + +if [[ "$is_head" == "true" ]]; then + printf 'head %s\n' "$url" >> "$MOCK_CURL_LOG" + case "$MOCK_AVAILABLE" in + xz) + [[ "$url" == *.tar.xz ]] + ;; + gz) + [[ "$url" == *.tar.gz ]] + ;; + none) + exit 22 + ;; + *) + echo "Unknown MOCK_AVAILABLE value: $MOCK_AVAILABLE" >&2 + exit 2 + ;; + esac + exit +fi + +printf 'download %s\n' "$url" >> "$MOCK_CURL_LOG" +case "$url" in + *.tar.xz) + cp "$MOCK_FIXTURES/zig.tar.xz" "$output_file" + ;; + *.tar.gz) + cp "$MOCK_FIXTURES/zig.tar.gz" "$output_file" + ;; + *) + echo "Unexpected download URL: $url" >&2 + exit 2 + ;; +esac diff --git a/tests/mocks/uname b/tests/mocks/uname new file mode 100755 index 0000000..d2e863e --- /dev/null +++ b/tests/mocks/uname @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -eu + +if [[ "${1:-}" == "-m" ]]; then + printf '%s\n' "$MOCK_UNAME_M" +else + /usr/bin/uname "$@" +fi