From 85659161784779f1ea29bc068305f8358d612efb Mon Sep 17 00:00:00 2001 From: juanarias8 Date: Tue, 10 Mar 2026 14:25:52 -0500 Subject: [PATCH 1/3] feat(install): improve version tag validation and update download URL - ensure valid semver tags when fetching version - validate fallback version tag format - switch download URL to Gitea releases --- install.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/install.sh b/install.sh index d0f53dd..41e7e14 100644 --- a/install.sh +++ b/install.sh @@ -47,12 +47,17 @@ if [ -n "$REQUESTED_VERSION" ]; then *) VERSION_TAG="v$REQUESTED_VERSION" ;; esac else - # Try manifest first (fast, no rate limits) - VERSION_TAG=$(curl -sL "https://gitea.app.monadical.io/monadical/greywall/latest.txt" 2>/dev/null || echo "") - - # Fallback to GitHub API if manifest fails + # Try manifest first (fast, no rate limits) — only accept valid semver tags + VERSION_TAG=$(curl -sL "https://gitea.app.monadical.io/monadical/greywall/raw/branch/gh-pages/latest.txt" 2>/dev/null | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "") + + # Fallback to Gitea API if manifest fails if [ -z "$VERSION_TAG" ]; then VERSION_TAG=$(curl -s "https://gitea.app.monadical.io/api/v1/repos/$REPO/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + # Validate it looks like a version tag + case "$VERSION_TAG" in + v[0-9]*) ;; + *) VERSION_TAG="" ;; + esac fi fi @@ -69,7 +74,7 @@ case "$OS" in *) OS_TITLE="$OS" ;; esac -DOWNLOAD_URL="https://github.com/$REPO/releases/download/${VERSION_TAG}/${BINARY_NAME}_${VERSION_NUMBER}_${OS_TITLE}_${ARCH}.tar.gz" +DOWNLOAD_URL="https://gitea.app.monadical.io/$REPO/releases/download/${VERSION_TAG}/${BINARY_NAME}_${VERSION_NUMBER}_${OS_TITLE}_${ARCH}.tar.gz" TMP_DIR=$(mktemp -d) cd "$TMP_DIR" -- 2.49.1 From 9a3d863696ff3017b8ff21edd2d47be8048c392e Mon Sep 17 00:00:00 2001 From: juanarias8 Date: Tue, 10 Mar 2026 14:26:18 -0500 Subject: [PATCH 2/3] test(install): add script to test install logic - verify version detection and error handling - check URL construction and download tests - include optional live install integration tests --- scripts/test_install.sh | 185 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100755 scripts/test_install.sh diff --git a/scripts/test_install.sh b/scripts/test_install.sh new file mode 100755 index 0000000..4b3cbc6 --- /dev/null +++ b/scripts/test_install.sh @@ -0,0 +1,185 @@ +#!/bin/bash +# test_install.sh - Test the install.sh script logic +# +# Tests version detection, URL construction, and error handling +# without requiring a published release. +# +# Usage: +# ./scripts/test_install.sh +# +# Set GREYWALL_TEST_INSTALL_LIVE=1 to also test against a real release +# (requires a published release on Gitea). + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +INSTALL_SCRIPT="$SCRIPT_DIR/../install.sh" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +PASSED=0 +FAILED=0 +SKIPPED=0 + +pass() { echo -e "Testing: $1... ${GREEN}PASS${NC}"; PASSED=$((PASSED + 1)); } +fail() { echo -e "Testing: $1... ${RED}FAIL${NC} ($2)"; FAILED=$((FAILED + 1)); } +skip() { echo -e "Testing: $1... ${YELLOW}SKIPPED${NC} ($2)"; SKIPPED=$((SKIPPED + 1)); } + +echo "Install script: $INSTALL_SCRIPT" +echo "==============================================" + +# ============================================================ +echo "" +echo "=== Script Sanity ===" +echo "" + +# Script exists and is executable +if [[ -f "$INSTALL_SCRIPT" ]]; then + pass "install.sh exists" +else + fail "install.sh exists" "file not found at $INSTALL_SCRIPT" +fi + +if sh -n "$INSTALL_SCRIPT" 2>/dev/null; then + pass "install.sh has valid shell syntax" +else + fail "install.sh has valid shell syntax" "syntax error reported by sh -n" +fi + +# ============================================================ +echo "" +echo "=== Version Detection ===" +echo "" + +# No releases → must fail with clean error (not malformed URL garbage) +output=$(sh "$INSTALL_SCRIPT" 2>&1) || true +if echo "$output" | grep -q "Error: Unable to determine version to install"; then + pass "no releases → clean error message" +elif echo "$output" | grep -q "Not found\|null\|undefined"; then + fail "no releases → clean error message" "leaked raw API/HTTP response: $output" +else + # Could be passing if a real release now exists — check if it downloaded correctly + if echo "$output" | grep -q "installed successfully"; then + pass "no releases → clean error message (release exists, install succeeded)" + else + fail "no releases → clean error message" "unexpected output: $output" + fi +fi + +# Explicit version arg (v-prefixed) → used as-is +output=$(sh "$INSTALL_SCRIPT" v99.0.0 2>&1) || true +if echo "$output" | grep -q "v99.0.0"; then + pass "explicit version (v-prefixed) passed through" +else + fail "explicit version (v-prefixed) passed through" "version not found in output: $output" +fi + +# Explicit version arg (no v prefix) → v added automatically +output=$(sh "$INSTALL_SCRIPT" 99.0.0 2>&1) || true +if echo "$output" | grep -q "v99.0.0"; then + pass "explicit version (no v-prefix) gets v added" +else + fail "explicit version (no v-prefix) gets v added" "output: $output" +fi + +# GREYWALL_VERSION env var respected +output=$(GREYWALL_VERSION=99.1.0 sh "$INSTALL_SCRIPT" 2>&1) || true +if echo "$output" | grep -q "v99.1.0"; then + pass "GREYWALL_VERSION env var respected" +else + fail "GREYWALL_VERSION env var respected" "output: $output" +fi + +# ============================================================ +echo "" +echo "=== URL Construction ===" +echo "" + +# Download URL must point to Gitea, not GitHub +output=$(sh "$INSTALL_SCRIPT" v1.2.3 2>&1) || true +if echo "$output" | grep -q "gitea.app.monadical.io"; then + pass "download URL uses Gitea host" +else + fail "download URL uses Gitea host" "output: $output" +fi + +if echo "$output" | grep -q "github.com"; then + fail "download URL does not use GitHub" "found github.com in output: $output" +else + pass "download URL does not use GitHub" +fi + +# URL contains the version, binary name, OS, and arch +OS_TITLE="Linux" +if [[ "$(uname -s)" == "Darwin" ]]; then OS_TITLE="Darwin"; fi +ARCH="x86_64" +if [[ "$(uname -m)" == "aarch64" || "$(uname -m)" == "arm64" ]]; then ARCH="arm64"; fi + +if echo "$output" | grep -q "greywall_1.2.3_${OS_TITLE}_${ARCH}.tar.gz"; then + pass "download URL has correct filename format" +else + fail "download URL has correct filename format" "expected greywall_1.2.3_${OS_TITLE}_${ARCH}.tar.gz in: $output" +fi + +# ============================================================ +echo "" +echo "=== Error Handling ===" +echo "" + +# Non-existent version → curl 404 → clean error, no crash +output=$(sh "$INSTALL_SCRIPT" v0.0.0-nonexistent 2>&1) || true +if echo "$output" | grep -q "Error: Failed to download release"; then + pass "non-existent version → clean download error" +else + fail "non-existent version → clean download error" "output: $output" +fi + +# ============================================================ +echo "" +echo "=== Live Install (optional) ===" +echo "" + +if [[ "${GREYWALL_TEST_INSTALL_LIVE:-}" == "1" ]]; then + # Check a release actually exists before attempting live install + LATEST_TAG=$(curl -s "https://gitea.app.monadical.io/api/v1/repos/monadical/greywall/releases/latest" \ + 2>/dev/null | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' || echo "") + case "$LATEST_TAG" in + v[0-9]*) + TMP_BIN=$(mktemp -d) + trap 'rm -rf "$TMP_BIN"' EXIT + install_out=$(HOME="$TMP_BIN" sh "$INSTALL_SCRIPT" 2>&1) || true + if echo "$install_out" | grep -q "installed successfully"; then + if [[ -x "$TMP_BIN/.local/bin/greywall" ]]; then + pass "live install: binary downloaded and executable" + version_out=$("$TMP_BIN/.local/bin/greywall" --version 2>&1) + if echo "$version_out" | grep -qE '^greywall v?[0-9]'; then + pass "live install: binary runs and reports version" + else + fail "live install: binary runs and reports version" "output: $version_out" + fi + else + fail "live install: binary downloaded and executable" "binary not found at $TMP_BIN/.local/bin/greywall" + fi + else + fail "live install: install succeeded" "output: $install_out" + fi + ;; + *) + skip "live install (download + run binary)" "no releases published on Gitea yet" + ;; + esac +else + skip "live install (download + run binary)" "set GREYWALL_TEST_INSTALL_LIVE=1 to enable" +fi + +# ============================================================ +echo "" +echo "==============================================" +echo "" +echo -e "Results: ${GREEN}$PASSED passed${NC}, ${RED}$FAILED failed${NC}, ${YELLOW}$SKIPPED skipped${NC}" +echo "" + +[[ $FAILED -eq 0 ]] \ No newline at end of file -- 2.49.1 From b1ad4b9803baa919f598cb00240d2a8f6af74659 Mon Sep 17 00:00:00 2001 From: juanarias8 Date: Tue, 10 Mar 2026 20:35:56 -0500 Subject: [PATCH 3/3] chore(ci): update golangci-lint and fix script paths - bump golangci-lint-action to v7 and version to v2.1.6 - correct directory paths in `smoke_test.sh` - update `test` and `test-ci` targets in Makefile --- .gitea/workflows/main.yml | 13 ++++++++----- Makefile | 4 ++-- scripts/smoke_test.sh | 8 ++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.gitea/workflows/main.yml b/.gitea/workflows/main.yml index 2743798..9b8b90e 100644 --- a/.gitea/workflows/main.yml +++ b/.gitea/workflows/main.yml @@ -42,11 +42,14 @@ jobs: - name: Download dependencies run: go mod download + - name: Download tun2socks binaries + run: make download-tun2socks + + - name: Install golangci-lint + run: GOTOOLCHAIN=local go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 + - name: Lint - uses: golangci/golangci-lint-action@v6 - with: - install-mode: goinstall - version: v1.64.8 + run: golangci-lint run --allow-parallel-runners test-linux: name: Test (Linux) @@ -112,4 +115,4 @@ jobs: run: make build-ci - name: Run smoke tests - run: GREYWALL_TEST_NETWORK=1 ./scripts/smoke_test.sh ./greywall + run: ./scripts/smoke_test.sh ./greywall diff --git a/Makefile b/Makefile index 0b9b09b..a253e65 100644 --- a/Makefile +++ b/Makefile @@ -38,11 +38,11 @@ build-ci: download-tun2socks $(eval GIT_COMMIT := $(shell git rev-parse HEAD 2>/dev/null || echo "unknown")) $(GOBUILD) -ldflags "-s -w -X main.version=$(VERSION) -X main.buildTime=$(BUILD_TIME) -X main.gitCommit=$(GIT_COMMIT)" -o $(BINARY_NAME) -v ./cmd/greywall -test: +test: download-tun2socks @echo "Running tests..." $(GOTEST) -v ./... -test-ci: +test-ci: download-tun2socks @echo "CI: Running tests with coverage..." $(GOTEST) -v -race -coverprofile=coverage.out ./... diff --git a/scripts/smoke_test.sh b/scripts/smoke_test.sh index 811fa07..fcbac6c 100755 --- a/scripts/smoke_test.sh +++ b/scripts/smoke_test.sh @@ -25,11 +25,11 @@ GREYWALL_BIN="${1:-}" if [[ -z "$GREYWALL_BIN" ]]; then if [[ -x "./greywall" ]]; then GREYWALL_BIN="./greywall" - elif [[ -x "./dis./greywall" ]]; then - GREYWALL_BIN="./dis./greywall" + elif [[ -x "./dist/greywall" ]]; then + GREYWALL_BIN="./dist/greywall" else echo "Building greywall..." - go build -o ./greywall ./cm./greywall + go build -o ./greywall ./cmd/greywall GREYWALL_BIN="./greywall" fi fi @@ -121,7 +121,7 @@ run_test "read file in workspace" "pass" "$GREYWALL_BIN" -c "cat $WORKSPACE/test # Test: Write outside workspace blocked # Create a settings file that only allows write to current workspace -SETTINGS_FILE="$WORKSPAC./greywall.json" +SETTINGS_FILE="$WORKSPACE/greywall.json" cat > "$SETTINGS_FILE" << EOF { "filesystem": { -- 2.49.1