From f6b4096adb34ed35bac9f973c16d99384f8875f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Pomyka=C5=82a?= Date: Wed, 22 Jul 2026 14:43:01 +0200 Subject: [PATCH 1/3] Update version to 2.10 --- .github/workflows/test-executables.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-executables.yml b/.github/workflows/test-executables.yml index 069f205..ed069a0 100644 --- a/.github/workflows/test-executables.yml +++ b/.github/workflows/test-executables.yml @@ -17,8 +17,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ macos-11, macos-12, macos-13, ubuntu-22.04 ] - version: [ '2.9', '2.8', '2.7', '2.6' ] + os: [ macos-26, macos-26-intel, ubuntu-24.04-arm, ubuntu-latest ] + version: [ '2.10', '2.9', '2.8' ] steps: - uses: actions/checkout@v3 - name: Test on ${{ matrix.os }} @@ -31,8 +31,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ windows-2019, windows-2022 ] - version: [ '2.5', '2.4', '2.3', '2.2'] + os: [ windows-latest ] + version: [ '2.10', '2.9', '2.8' ] steps: - uses: actions/checkout@v3 - name: Test on ${{ matrix.os }} From 0ea998892d6a5db54465fbc267179fe1220bc91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Pomyka=C5=82a?= Date: Wed, 22 Jul 2026 15:14:35 +0200 Subject: [PATCH 2/3] Add ad-hoc signing for macOS builds --- .github/workflows/build-release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 7da1304..6bd7a5d 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -94,6 +94,12 @@ jobs: run: ./target/${{ matrix.filename }} --version - name: "Rename executable" run: mv ./target/${{ matrix.filename }} ./target/${{ matrix.downloadFilename }} + - name: "Ad-hoc sign executable (macOS)" + if: startsWith(matrix.os, 'macos') + run: | + xattr -d com.apple.quarantine ./target/${{ matrix.downloadFilename }} 2>/dev/null || true + codesign --force --deep --sign - ./target/${{ matrix.downloadFilename }} + codesign --verify --verbose ./target/${{ matrix.downloadFilename }} - name: "Upload artifact" uses: actions/upload-artifact@v4 with: From b6e93279d3d1612fd12c1eb25054523dd9efa893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Pomyka=C5=82a?= Date: Wed, 22 Jul 2026 15:34:37 +0200 Subject: [PATCH 3/3] Add smoke tests --- .github/workflows/build-release.yml | 7 +- scripts/smoke-test.sh | 158 ++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 2 deletions(-) create mode 100755 scripts/smoke-test.sh diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 6bd7a5d..20eed5a 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -36,6 +36,8 @@ jobs: VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) echo "VERSION=$VERSION" >> $GITHUB_ENV echo "version=$VERSION" >> $GITHUB_OUTPUT + - name: 'Smoke test JAR' + run: ./scripts/smoke-test.sh java -jar target/simplelocalize-cli-${{env.VERSION}}.jar - name: 'Upload artifact' uses: actions/upload-artifact@v4 with: @@ -90,8 +92,9 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: "Build executable" run: mvn -DskipTests -Pnative clean package - - name: "Test executable" - run: ./target/${{ matrix.filename }} --version + - name: "Smoke test executable" + shell: bash + run: ./scripts/smoke-test.sh ./target/${{ matrix.filename }} - name: "Rename executable" run: mv ./target/${{ matrix.filename }} ./target/${{ matrix.downloadFilename }} - name: "Ad-hoc sign executable (macOS)" diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh new file mode 100755 index 0000000..2c269bc --- /dev/null +++ b/scripts/smoke-test.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +# +# Smoke-tests a built simplelocalize-cli binary (native executable or JAR). +# Confirms the app starts and every command runs without crashing (segfault, +# missing native-image reflection config, etc). This does NOT verify business +# logic correctness - only that the process doesn't die from a signal. +# +# Usage: +# ./scripts/smoke-test.sh ./target/simplelocalize-cli-linux +# ./scripts/smoke-test.sh java -jar ./target/simplelocalize-cli-2.10.0.jar +# +# Optional: set SIMPLELOCALIZE_TEST_API_KEY to also exercise network-calling +# commands (status/download/upload/pull/auto-translate/publish) against a +# real test project, in addition to the argument-less invocation that always +# runs (which uses whatever apiKey is in the repo's tracked simplelocalize.yml +# and is expected to fail with an auth error - that's fine, we only care that +# it doesn't crash). +# +# 'purge' deletes translations, so it is never invoked for real here. + +set -uo pipefail + +if [ "$#" -lt 1 ]; then + echo "Usage: $0 [args...]" + echo "Example: $0 ./target/simplelocalize-cli-linux" + echo "Example: $0 java -jar ./target/simplelocalize-cli-2.10.0.jar" + exit 1 +fi + +# Resolve any argument that is an existing file to an absolute path, since +# some checks below run with a different working directory (e.g. 'init'). +CMD=() +for arg in "$@"; do + if [ -e "$arg" ]; then + CMD+=("$(cd "$(dirname "$arg")" && pwd)/$(basename "$arg")") + else + CMD+=("$arg") + fi +done + +FAILED=0 +LOG_DIR="$(mktemp -d)" +WORK_DIR="$(mktemp -d)" +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +echo "Testing command: ${CMD[*]}" +echo "Work dir: $WORK_DIR" +echo "Log dir: $LOG_DIR" + +# run_check [args...] +# Runs CMD with the given args, captures output, and flags SIGSEGV/SIGABRT/etc. +# A non-zero "normal" exit code (usage errors, auth failures) is NOT a failure - +# only a signal-terminated process (exit code >= 128) is treated as a crash. +# Stdin is always /dev/null so a command can never block waiting for input. +run_check() +{ + local description="$1" + shift + local slug + slug=$(echo "$description" | tr -c 'a-zA-Z0-9' '_') + local logfile="$LOG_DIR/${slug}.log" + + echo "::group::${description}" + echo "+ ${CMD[*]} $*" + + "${CMD[@]}" "$@" >"$logfile" 2>&1 /dev/null || exit 1 +run_check "Init (real)" init +popd >/dev/null || exit 1 + +run_check "Extract i18next (real)" extract \ + --projectType "i18next/i18next" \ + --searchDir "$REPO_ROOT/src/test/resources/i18next" \ + --output "$WORK_DIR/extraction-i18next.json" + +run_check "Extract data-i18n-key (real)" extract \ + --projectType "simplelocalize/data-i18n-key" \ + --searchDir "$REPO_ROOT/src/test/resources/extract-data-i18n" \ + --output "$WORK_DIR/extraction-data-i18n.json" + +# --- Argument-less invocation of every remaining command -------------------- +# These run for real (no --help mixin on subcommands, so we can't rely on +# that). Without SIMPLELOCALIZE_TEST_API_KEY they'll use whatever apiKey is in +# the repo's tracked simplelocalize.yml (a placeholder) and are expected to +# fail with a handled auth/validation error - we only check they don't crash. +# 'purge' is intentionally excluded: it can delete real translations. + +run_check "Upload (no args)" upload +run_check "Download (no args)" download +run_check "Pull (no args)" pull +run_check "Status (no args)" status +run_check "Publish (no args)" publish +run_check "Auto-translate (no args)" auto-translate + +# --- Real, network-calling commands against a real test project ------------ + +if [ -n "${SIMPLELOCALIZE_TEST_API_KEY:-}" ]; then + echo "SIMPLELOCALIZE_TEST_API_KEY is set, running network-calling commands for real" + + run_check "Status (real)" status --apiKey "$SIMPLELOCALIZE_TEST_API_KEY" + run_check "Download (real)" download \ + --apiKey "$SIMPLELOCALIZE_TEST_API_KEY" \ + --downloadFormat yaml \ + --downloadPath "$WORK_DIR/translations_{lang}.yml" + run_check "Pull (real)" pull \ + --apiKey "$SIMPLELOCALIZE_TEST_API_KEY" \ + --environment _latest \ + --pullPath "$WORK_DIR/hosting/" + + echo "en:" >"$WORK_DIR/translations_en.yml" + echo " HELLO: Hello" >>"$WORK_DIR/translations_en.yml" + run_check "Upload (real)" upload \ + --apiKey "$SIMPLELOCALIZE_TEST_API_KEY" \ + --uploadFormat yaml \ + --languageKey en \ + --uploadPath "$WORK_DIR/translations_en.yml" \ + --dryRun + + run_check "Auto-translate (real)" auto-translate --apiKey "$SIMPLELOCALIZE_TEST_API_KEY" + run_check "Publish (real)" publish --apiKey "$SIMPLELOCALIZE_TEST_API_KEY" --environment _latest +else + echo "SIMPLELOCALIZE_TEST_API_KEY not set - skipping authenticated network commands (argument-less variants above already covered the code path)" +fi + +# --- Summary ----------------------------------------------------------------- + +rm -rf "$WORK_DIR" + +if [ "$FAILED" -ne 0 ]; then + echo "::error::Smoke test FAILED - one or more commands crashed. Logs kept at: $LOG_DIR" + exit 1 +fi + +echo "Smoke test PASSED - no crashes detected across all commands." +rm -rf "$LOG_DIR" +exit 0