diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b23ed3c..5a4cf4d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,22 +13,22 @@ jobs: build: strategy: matrix: - # The "reproducible" entry is used to build the project with the LTS Java version used in reproducible builds script. + # java="25" is the LTS Java version used in reproducible builds script (default in Containerfile). # More Java versions can be added to test compatibility, eg. "26". - java: ["reproducible", "26"] + java: ["25", "26"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Build run: | - if [ "${{ matrix.java }}" != "reproducible" ]; then + if [ "${{ matrix.java }}" != "25" ]; then export OVERRIDE_JAVA_VERSION="${{ matrix.java }}" fi ./reproducible-builds/build.sh - name: Upload build artifacts uses: actions/upload-artifact@v7 with: - name: signal-cli-${{ matrix.java }}-${{ github.job }} + name: signal-cli-archive-${{ matrix.java }} path: dist/* build-client: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a18b953f..621581f9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,10 +12,11 @@ env: IMAGE_REGISTRY: ghcr.io/asamk REGISTRY_USER: ${{ github.actor }} REGISTRY_PASSWORD: ${{ github.token }} + ARCHIVE_JAVA_VERSION: 25 jobs: build: - uses: AsamK/signal-cli/.github/workflows/build.yml@master + uses: ./.github/workflows/build.yml release: needs: build @@ -31,7 +32,7 @@ jobs: - name: Get signal-cli version id: version run: | - mv ./signal-cli-reproducible-build/* . + mv ./signal-cli-archive-${{ env.ARCHIVE_JAVA_VERSION }}/* . echo "version=$(cat VERSION)" >> $GITHUB_OUTPUT - name: Create release @@ -87,7 +88,7 @@ jobs: - name: Move archive file run: | - tar xf ./signal-cli-reproducible-build/signal-cli-${{ needs.release.outputs.version }}.tar.gz + tar xf signal-cli-archive-${{ env.ARCHIVE_JAVA_VERSION }}/signal-cli-${{ needs.release.outputs.version }}.tar.gz mkdir -p build/install/ mv ./signal-cli-"${{ needs.release.outputs.version }}"/ build/install/signal-cli @@ -127,7 +128,7 @@ jobs: - name: Move archive file run: | - tar xf ./signal-cli-reproducible-build/signal-cli-${{ needs.release.outputs.version }}-Linux-native.tar.gz + tar xf signal-cli-archive-${{ env.ARCHIVE_JAVA_VERSION }}/signal-cli-${{ needs.release.outputs.version }}-Linux-native.tar.gz mkdir -p build/native/nativeCompile/ mv signal-cli build/native/nativeCompile/ chmod +x build/native/nativeCompile/signal-cli @@ -168,7 +169,7 @@ jobs: - name: Move archive file run: | - tar xf ./signal-cli-reproducible-build/signal-cli-${{ needs.release.outputs.version }}-Linux-client.tar.gz + tar xf signal-cli-archive-${{ env.ARCHIVE_JAVA_VERSION }}/signal-cli-${{ needs.release.outputs.version }}-Linux-client.tar.gz mkdir -p client/target/release/ mv signal-cli-client client/target/release/ chmod +x client/target/release/signal-cli-client diff --git a/CHANGELOG.md b/CHANGELOG.md index 44478806..90d02420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,22 @@ # Changelog -## [Unreleased] +## [0.14.3] - 2026-04-22 + +### Fixed + +- Fix sender key re-distribution on every group message (Thanks @meinecke) + +### Improved + +- Performance improvement when assigning admin role to multiple group members +- Increase disconnect timeout for websocket connections +- Release builds are now reproducible ### Changed - Send message results now surface server-advised retry time for plain rate-limit (HTTP 413) failures, not only for proof-required challenges. The `retryAfterSeconds` field in JSON-RPC `SendMessageResult` is populated whenever the server sends a `Retry-After` header. The canonical way to distinguish proof-required failures remains `token != null`. Text output includes "retry after N seconds" when known. +- Add distinct JSON-RPC error code (6) for captcha rejection (Thanks @tonycpsu) +- No longer sends busy call response to allow linked devices to accept call ## [0.14.2] - 2026-04-04 diff --git a/build.gradle.kts b/build.gradle.kts index f1e10f4d..64e29294 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { allprojects { group = "org.asamk" - version = "0.14.3-SNAPSHOT" + version = "0.14.3" } java { diff --git a/data/org.asamk.SignalCli.metainfo.xml b/data/org.asamk.SignalCli.metainfo.xml index c1730192..3bf04d8c 100644 --- a/data/org.asamk.SignalCli.metainfo.xml +++ b/data/org.asamk.SignalCli.metainfo.xml @@ -45,6 +45,9 @@ intense + + https://github.com/AsamK/signal-cli/releases/tag/v0.14.3 + https://github.com/AsamK/signal-cli/releases/tag/v0.14.2 diff --git a/libsignal-version b/libsignal-version index ae02209b..da011ce4 100644 --- a/libsignal-version +++ b/libsignal-version @@ -1 +1 @@ -0.90.0 +0.92.1 diff --git a/reproducible-builds/build.Containerfile b/reproducible-builds/build.Containerfile index 0e73ddc5..38626266 100644 --- a/reproducible-builds/build.Containerfile +++ b/reproducible-builds/build.Containerfile @@ -1,13 +1,12 @@ -ARG ZULU_TAG="25.0.2-jdk@sha256:9582df6c4415d9c770eb5ff8fce426ebba53631149c9eb083ee126568d32fab3" +ARG ZULU_TAG="25-latest@sha256:8eca9375451a392bff01efe946f2e9263c50aa71a9d68423c068cc1061a41b7e" FROM docker.io/azul/zulu-openjdk:$ZULU_TAG -ENV SOURCE_DATE_EPOCH=1767225600 +ARG SOURCE_DATE_EPOCH="1776889382" +ENV SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH ENV LANG=C.UTF-8 ENV LC_CTYPE=en_US.UTF-8 -ARG SNAPSHOT=20260101T000000Z -RUN echo "deb http://snapshot.ubuntu.com/ubuntu/${SNAPSHOT}/ jammy main" > /etc/apt/sources.list \ - && echo "deb http://snapshot.ubuntu.com/ubuntu/${SNAPSHOT}/ jammy universe" >> /etc/apt/sources.list -RUN apt update && apt install -y make asciidoc-base +RUN SNAPSHOT="$(date -u -d "@$SOURCE_DATE_EPOCH" +%Y%m%dT%H%M%SZ)" \ + && apt install -y make asciidoc-base --update --snapshot "$SNAPSHOT" --no-install-recommends --no-install-suggests COPY --chmod=0700 reproducible-builds/entrypoint.sh /usr/local/bin/entrypoint.sh WORKDIR /signal-cli ENTRYPOINT [ "/usr/local/bin/entrypoint.sh", "build" ] diff --git a/reproducible-builds/build.sh b/reproducible-builds/build.sh index 8a3878ce..2a46edaa 100755 --- a/reproducible-builds/build.sh +++ b/reproducible-builds/build.sh @@ -18,11 +18,8 @@ fi VERSION=$(sed -n 's/\s*version\s*=\s*"\(.*\)".*/\1/p' build.gradle.kts | tail -n1) echo "$VERSION" >dist/VERSION -$ENGINE build -t signal-cli:build ${OVERRIDE_JAVA_VERSION:+--build-arg ZULU_TAG=$OVERRIDE_JAVA_VERSION} -f reproducible-builds/build.Containerfile . -$ENGINE build -t signal-cli:native -f reproducible-builds/native.Containerfile . -$ENGINE build -t signal-cli:client -f reproducible-builds/client.Containerfile . - # Build jar +$ENGINE build -t signal-cli:build ${OVERRIDE_JAVA_VERSION:+--build-arg ZULU_TAG=$OVERRIDE_JAVA_VERSION} -f reproducible-builds/build.Containerfile . git clean -Xfd -e '!/dist/' -e '!/dist/**' -e '!/github/' -e '!/github/**' # shellcheck disable=SC2086 $ENGINE run --pull=never --rm -v "$(pwd)":/signal-cli:Z -e VERSION="$VERSION" $USER signal-cli:build @@ -34,12 +31,14 @@ if [ -n "${OVERRIDE_JAVA_VERSION:-}" ]; then fi # Build native-image +$ENGINE build -t signal-cli:native -f reproducible-builds/native.Containerfile . git clean -Xfd -e '!/dist/' -e '!/dist/**' -e '!/github/' -e '!/github/**' # shellcheck disable=SC2086 $ENGINE run --pull=never --rm -v "$(pwd)":/signal-cli:Z -e VERSION="$VERSION" $USER signal-cli:native mv build/signal-cli-*-Linux-native.tar.gz dist/ # Build rust client +$ENGINE build -t signal-cli:client -f reproducible-builds/client.Containerfile . git clean -Xfd -e '!/dist/' -e '!/dist/**' -e '!/github/' -e '!/github/**' # shellcheck disable=SC2086 $ENGINE run --pull=never --rm -v "$(pwd)":/signal-cli:Z -e VERSION="$VERSION" $USER signal-cli:client diff --git a/reproducible-builds/client.Containerfile b/reproducible-builds/client.Containerfile index 8a8dfa34..59d85db8 100644 --- a/reproducible-builds/client.Containerfile +++ b/reproducible-builds/client.Containerfile @@ -1,5 +1,8 @@ -FROM docker.io/rust:1.94.1-slim-trixie@sha256:c6a474d7164ea2455e09b60a759b1edca38db7373c5689c1dae31780de4e71ac -ENV SOURCE_DATE_EPOCH=1767225600 +ARG RUST_TAG="1-slim@sha256:715efd1ccdc4a63bd6a6e2f54387fff73f904b70e610d41b4d9d74ff38e13ad3" + +FROM docker.io/rust:$RUST_TAG +ARG SOURCE_DATE_EPOCH="1776889382" +ENV SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH ENV LANG=C.UTF-8 ENV LC_CTYPE=en_US.UTF-8 COPY --chmod=0700 reproducible-builds/entrypoint.sh /usr/local/bin/entrypoint.sh diff --git a/reproducible-builds/native.Containerfile b/reproducible-builds/native.Containerfile index 47cd5ce3..a242538d 100644 --- a/reproducible-builds/native.Containerfile +++ b/reproducible-builds/native.Containerfile @@ -1,5 +1,8 @@ -FROM container-registry.oracle.com/graalvm/native-image:25.0.2@sha256:4c0d5919f6840d89721274eb8cf81962faa2f870b816967e6732e2a151b150d8 -ENV SOURCE_DATE_EPOCH=1767225600 +ARG GRAALVM_TAG="25@sha256:38f835ccb37d4a106c37376a98e8713999077a8c8173d9876505f77da438332c" + +FROM container-registry.oracle.com/graalvm/native-image:$GRAALVM_TAG +ARG SOURCE_DATE_EPOCH="1776889382" +ENV SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH ENV LANG=C.UTF-8 ENV LC_CTYPE=en_US.UTF-8 COPY --chmod=0700 reproducible-builds/entrypoint.sh /usr/local/bin/entrypoint.sh diff --git a/reproducible-builds/update-pinned-container-versions.sh b/reproducible-builds/update-pinned-container-versions.sh new file mode 100755 index 00000000..f03c4333 --- /dev/null +++ b/reproducible-builds/update-pinned-container-versions.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" +cd "$ROOT_DIR" + +if command -v podman >/dev/null; then + ENGINE=podman +elif command -v docker >/dev/null; then + ENGINE=docker +else + echo "error: neither podman nor docker is available" >&2 + exit 1 +fi + +resolve_digest() { + local image_ref="$1" + "$ENGINE" pull "$image_ref" >/dev/null + "$ENGINE" image inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' "$image_ref" \ + | grep -m1 -E '@sha256:[0-9a-f]{64}$' \ + | sed -E 's|.*(@sha256:[0-9a-f]{64})$|\1|' +} + +update_arg_tag() { + local file="$1" + local arg_name="$2" + local image_prefix="$3" + local current + current="$(sed -n "s/^ARG ${arg_name}=\"\([^\"]*\)\"$/\\1/p" "$file")" + if [[ -z "$current" ]]; then + echo "error: could not find ARG ${arg_name} in $file" >&2 + exit 1 + fi + local tag + tag="${current%@*}" + local digest + digest="$(resolve_digest "${image_prefix}${tag}")" + sed -i -E "s|^ARG ${arg_name}=\"[^\"]+\"$|ARG ${arg_name}=\"${tag}${digest}\"|" "$file" + echo "updated $file -> ${tag}${digest}" +} + +update_source_date_epoch() { + local file="$1" + local current_timestamp + current_timestamp="$(date +%s)" + sed -i -E "s|^ARG SOURCE_DATE_EPOCH=\"[^\"]+\"$|ARG SOURCE_DATE_EPOCH=\"${current_timestamp}\"|" "$file" + echo "updated $file SOURCE_DATE_EPOCH -> ${current_timestamp}" +} + +update_arg_tag reproducible-builds/build.Containerfile ZULU_TAG docker.io/azul/zulu-openjdk: +update_arg_tag reproducible-builds/native.Containerfile GRAALVM_TAG container-registry.oracle.com/graalvm/native-image: +update_arg_tag reproducible-builds/client.Containerfile RUST_TAG docker.io/rust: + +update_source_date_epoch reproducible-builds/build.Containerfile +update_source_date_epoch reproducible-builds/native.Containerfile +update_source_date_epoch reproducible-builds/client.Containerfile