diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
@@ -19,6 +19,16 @@ jobs:
- name: shellcheck
run: sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck
+ - name: version strings must match the tag being released
+ if: startsWith(github.ref, 'refs/tags/v')
+ run: |
+ want="${GITHUB_REF_NAME}"
+ got=$(sed -n 's/^VERSION=${TT_VERSION:-\(v[0-9.]*\)}.*/\1/p' install.sh)
+ echo "tag=$want install.sh=$got"
+ [ "$want" = "$got" ] || { echo "::error::install.sh pins $got but the tag is $want"; exit 1; }
+ bad=$(grep -oE 'v1\.[0-9]+\.[0-9]+' install.sh README.md | grep -v ":$want$" || true)
+ [ -z "$bad" ] || { echo "::error::stale version strings:"; echo "$bad"; exit 1; }
+
# Builds both images for amd64 only and runs their offline self-checks.
# Everything runs with --network none, so CI never registers a WARP
# identity: hammering Cloudflare's registration endpoint from shared
diff --git a/README.md b/README.md
@@ -4,8 +4,8 @@ Your own VLESS + REALITY proxy, with optional Cloudflare WARP egress, in one
container on any Linux box that has Docker.
```
-curl -fsSLO https://raw.githubusercontent.com/sqzer-x/transtation/v1.0.2/install.sh
-sha256sum install.sh # compare against the hash in the v1.0.2 release notes
+curl -fsSLO https://raw.githubusercontent.com/sqzer-x/transtation/v1.0.8/install.sh
+sha256sum install.sh # compare against the hash in the v1.0.8 release notes
less install.sh # please actually read it
sudo sh install.sh
```
@@ -45,7 +45,7 @@ transtation exists because of a narrower set of preferences:
Two-step form above is the recommended one. If you are going to pipe it anyway:
```
-curl -fsSL https://raw.githubusercontent.com/sqzer-x/transtation/v1.0.2/install.sh | sudo sh
+curl -fsSL https://raw.githubusercontent.com/sqzer-x/transtation/v1.0.8/install.sh | sudo sh
```
The installer needs root, refuses anything other than x86_64/aarch64, installs
@@ -59,7 +59,7 @@ If you already run Docker and prefer to do it yourself:
# /opt/transtation/docker-compose.yml
services:
proxy:
- image: ghcr.io/sqzer-x/transtation:v1.0.2
+ image: ghcr.io/sqzer-x/transtation:v1.0.8
container_name: transtation
restart: unless-stopped
ports: ["443:8443"]
@@ -132,7 +132,7 @@ install -Dm600 /dev/stdin /etc/transtation/uri # paste the vless:// link, then
docker run -d --name transtation-client --restart unless-stopped \
-p 127.0.0.1:1080:1080 \
-v /etc/transtation:/etc/transtation:ro \
- ghcr.io/sqzer-x/transtation-client:v1.0.2
+ ghcr.io/sqzer-x/transtation-client:v1.0.8
```
```
@@ -166,7 +166,7 @@ docker run -d --name transtation-client --restart unless-stopped \
-e MODE=tun \
-e DIRECT_SUFFIXES=example.com,example.net \
-v /etc/transtation:/etc/transtation:ro \
- ghcr.io/sqzer-x/transtation-client:v1.0.2
+ ghcr.io/sqzer-x/transtation-client:v1.0.8
```
Exactly three extra flags. `--privileged` is **not** needed and must not be
diff --git a/install.sh b/install.sh
@@ -15,12 +15,12 @@
# last line. If the download is truncated, nothing runs.
set -eu
-VERSION=${TT_VERSION:-v1.0.2}
+VERSION=${TT_VERSION:-v1.0.8}
IMAGE_SERVER=${TT_IMAGE_SERVER:-ghcr.io/sqzer-x/transtation}
IMAGE_CLIENT=${TT_IMAGE_CLIENT:-ghcr.io/sqzer-x/transtation-client}
# Filled in by the release workflow. A tag is mutable -- the same stolen-token
# compromise we already concede for Xray's .dgst would let someone retag
-# v1.0.2, and the hash-verified installer you read would vouch for nothing.
+# v1.0.8, and the hash-verified installer you read would vouch for nothing.
SERVER_DIGEST=${TT_SERVER_DIGEST:-}
CLIENT_DIGEST=${TT_CLIENT_DIGEST:-}
diff --git a/test.sh b/test.sh
@@ -56,6 +56,17 @@ present_in_compose() { server_compose | grep -qE "$1"; }
check "the compose block caps the log size (xray logs to stdout)" present_in_compose 'max-size'
check "the compose block uses a named volume, not a bind mount" present_in_compose 'transtation-data:/data'
check "no script ever runs 'nft flush ruleset'" uncommented_absent 'flush ruleset' host/transtation-killswitch
+
+# The version is repeated in the installer and in every documented command.
+# It drifted five releases once, because bumping it was a hand-run sed, and the
+# README ended up telling people to install a version without the security
+# fixes. One check is cheaper than remembering.
+versions_agree() {
+ _v=$(sed -n 's/^VERSION=${TT_VERSION:-\(v[0-9.]*\)}.*/\1/p' install.sh)
+ [ -n "$_v" ] || return 1
+ ! grep -oE 'v1\.[0-9]+\.[0-9]+' install.sh README.md | grep -v ":$_v$" | grep -q .
+}
+check "every documented version string matches install.sh" versions_agree
# Hardening the compose file grants. The running process was verified to hold
# CapEff 0000000000000000 with these in place.
check "the compose block drops all capabilities" present_in_compose "cap_drop"
|