From 1129f9f915a2b71becbdc6aa6d17918e4d7a51b6 Mon Sep 17 00:00:00 2001 From: hanruo <552455797@qq.com> Date: Sat, 23 May 2026 21:55:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20"=E5=B7=A5=E4=BD=9C=E6=B5=81"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/release.yml | 58 +++++++++++++++++++++ .gitignore | 1 + package.json | 3 +- scripts/install.sh | 98 ++++++++++++++++++++++++++++++++++++ scripts/release.sh | 25 +++++++++ 5 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/release.yml create mode 100755 scripts/install.sh create mode 100755 scripts/release.sh diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..f845b94 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,58 @@ +name: release + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + tag: + description: "Tag to release (e.g. v0.2.0)" + required: true + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install dependencies + run: npm ci || npm install + + - name: Test + run: npm test + + - name: Build bundle + run: npm run build + + - name: Stage release artifacts + run: | + mkdir -p release + cp dist/app.mjs release/app.mjs + cp scripts/install.sh release/install.sh + ls -lh release/ + + - name: Resolve tag + id: tag + run: | + if [ -n "${{ inputs.tag }}" ]; then + echo "name=${{ inputs.tag }}" >> "$GITHUB_OUTPUT" + else + echo "name=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT" + fi + + - name: Publish Gitea Release + uses: https://gitea.com/actions/release-action@main + with: + api_key: ${{ secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN }} + tag: ${{ steps.tag.outputs.name }} + title: ${{ steps.tag.outputs.name }} + files: |- + release/app.mjs + release/install.sh diff --git a/.gitignore b/.gitignore index fbb8ac8..ba900fc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ npm-debug.log* .DS_Store dist/ +release/ diff --git a/package.json b/package.json index f97ebfa..b4fc4ad 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "build": "esbuild src/app.jsx --bundle --platform=node --target=node18 --format=esm --jsx=automatic --outfile=dist/app.mjs --alias:react-devtools-core=./src/stubs/react-devtools-core.js --banner:js=\"import { createRequire as __cR } from 'node:module'; const require = __cR(import.meta.url);\"", "build:watch": "npm run build -- --watch", "check": "node --check bin/server-config.js && node --check src/lib/frp-config.js && node --check src/lib/runner.js && node --check src/lib/tasks.js && node --check test/frp-config.test.js", - "test": "node --test test/*.test.js" + "test": "node --test test/*.test.js", + "release:prepare": "bash scripts/release.sh" }, "engines": { "node": ">=18" diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..94fbd5b --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# server-config-cli installer +# +# Usage: +# curl -fsSL /releases/latest/download/install.sh | bash +# +# Environment overrides: +# VERSION release tag to install (default: latest) +# NODE_VERSION portable Node version (default: v20.18.1) +# NODE_MIRROR Node download base URL +# REPO_BASE Gitea repo URL +# SERVER_CONFIG_HOME install root (default: $HOME/.server-config) +# SERVER_CONFIG_BIN launcher dir (default: $HOME/.local/bin) + +set -euo pipefail + +REPO_BASE="${REPO_BASE:-https://gitea1.deeppolicy.cn:3002/hanruo/server-config-cli}" +VERSION="${VERSION:-latest}" +NODE_VERSION="${NODE_VERSION:-v20.18.1}" +NODE_MIRROR="${NODE_MIRROR:-https://registry.npmmirror.com/-/binary/node}" +INSTALL_DIR="${SERVER_CONFIG_HOME:-$HOME/.server-config}" +BIN_DIR="${SERVER_CONFIG_BIN:-$HOME/.local/bin}" + +log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m!!\033[0m %s\n' "$*" >&2; } +die() { printf '\033[1;31mxx\033[0m %s\n' "$*" >&2; exit 1; } + +command -v curl >/dev/null 2>&1 || die "curl is required" +command -v tar >/dev/null 2>&1 || die "tar is required" + +OS=$(uname -s | tr '[:upper:]' '[:lower:]') +case "$OS" in + linux) NODE_OS=linux ;; + darwin) NODE_OS=darwin ;; + *) die "unsupported OS: $OS" ;; +esac + +ARCH=$(uname -m) +case "$ARCH" in + x86_64|amd64) NODE_ARCH=x64 ;; + aarch64|arm64) NODE_ARCH=arm64 ;; + *) die "unsupported arch: $ARCH" ;; +esac + +NODE_PKG="node-${NODE_VERSION}-${NODE_OS}-${NODE_ARCH}.tar.gz" +NODE_URL="${NODE_MIRROR}/${NODE_VERSION}/${NODE_PKG}" +NODE_DIR="${INSTALL_DIR}/node-${NODE_VERSION}-${NODE_OS}-${NODE_ARCH}" + +if [ "$VERSION" = "latest" ]; then + BUNDLE_URL="${REPO_BASE}/releases/latest/download/app.mjs" +else + BUNDLE_URL="${REPO_BASE}/releases/download/${VERSION}/app.mjs" +fi + +mkdir -p "$INSTALL_DIR" "$BIN_DIR" + +if [ ! -x "${NODE_DIR}/bin/node" ]; then + log "Downloading Node ${NODE_VERSION} (${NODE_OS}-${NODE_ARCH})" + TMP=$(mktemp -d) + trap 'rm -rf "$TMP"' EXIT + curl -fL --progress-bar "$NODE_URL" -o "${TMP}/node.tar.gz" \ + || die "failed to download $NODE_URL" + tar -xzf "${TMP}/node.tar.gz" -C "$INSTALL_DIR" + [ -x "${NODE_DIR}/bin/node" ] || die "Node extraction did not produce ${NODE_DIR}/bin/node" +else + log "Reusing existing Node at ${NODE_DIR}" +fi + +log "Downloading server-config bundle (${VERSION})" +mkdir -p "${INSTALL_DIR}/app" +curl -fL --progress-bar "$BUNDLE_URL" -o "${INSTALL_DIR}/app/app.mjs" \ + || die "failed to download $BUNDLE_URL" + +log "Writing launcher to ${BIN_DIR}/server-config" +cat > "${BIN_DIR}/server-config" < server-config" + +case ":$PATH:" in + *":${BIN_DIR}:"*) ;; + *) + echo + warn "${BIN_DIR} is not in your PATH." + echo " Add this to ~/.zshrc or ~/.bashrc:" + echo " export PATH=\"${BIN_DIR}:\$PATH\"" + ;; +esac + +echo +echo "Run: server-config" diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..430a325 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Stage release artifacts into ./release/ for upload to Gitea Releases. +# +# Produces: +# release/app.mjs — built bundle +# release/install.sh — installer script +# +# Upload both files as assets on the matching tag in Gitea. + +set -euo pipefail + +cd "$(dirname "$0")/.." + +echo "==> npm run build" +npm run build + +mkdir -p release +cp dist/app.mjs release/app.mjs +cp scripts/install.sh release/install.sh + +echo +echo "Staged:" +ls -lh release/ +echo +echo "Next: upload release/app.mjs and release/install.sh as assets on the Gitea release tag."