diff --git a/.github/release-notes.md b/.github/release-notes.md new file mode 100644 index 0000000..9531b9c --- /dev/null +++ b/.github/release-notes.md @@ -0,0 +1,33 @@ + +## 下载 · Downloads + +### 客户端 · Client + +装在能访问内网服务的电脑上,用来创建通道、邀请同事。 +Install it on a machine that can reach your internal services. + +| 平台 Platform | 文件 File | +| --- | --- | +| macOS(Apple Silicon / Intel) | [PortRelay-{{VERSION}}.dmg]({{DOWNLOAD}}/PortRelay-{{VERSION}}.dmg) | +| Linux x86_64 | [portrelay-agent-{{VERSION}}-linux-amd64.tar.gz]({{DOWNLOAD}}/portrelay-agent-{{VERSION}}-linux-amd64.tar.gz) | +| Linux ARM64 | [portrelay-agent-{{VERSION}}-linux-arm64.tar.gz]({{DOWNLOAD}}/portrelay-agent-{{VERSION}}-linux-arm64.tar.gz) | +| Windows x86_64 | [portrelay-agent-{{VERSION}}-windows-amd64.zip]({{DOWNLOAD}}/portrelay-agent-{{VERSION}}-windows-amd64.zip) | + +macOS 是菜单栏 App:打开 dmg,把 PortRelay 拖进「应用程序」。App 未经 Apple 公证,首次打开请在 Finder 里右键选择「打开」。Linux / Windows 是命令行 Agent,运行后在浏览器里打开管理面板。 +On macOS, open the dmg and drag PortRelay to Applications. The app is not notarized, so right-click it and choose Open the first time. On Linux and Windows, run the agent and use the web panel it opens. + +### 服务端 · Server (edge gateway) + +部署在同事和客户端都能连到的 Linux 机器上。 +Deploy it on a Linux host that both teammates and the client can reach. + +| 方式 Method | 文件 File | +| --- | --- | +| 二进制 + systemd · x86_64 | [portrelay-server-{{VERSION}}-linux-amd64.tar.gz]({{DOWNLOAD}}/portrelay-server-{{VERSION}}-linux-amd64.tar.gz) | +| 二进制 + systemd · ARM64 | [portrelay-server-{{VERSION}}-linux-arm64.tar.gz]({{DOWNLOAD}}/portrelay-server-{{VERSION}}-linux-arm64.tar.gz) | +| Docker | `{{IMAGE}}:{{VERSION}}` | + +解压后运行 `sudo ./deploy/install-server.sh ./portrelay-server`,再次运行即可升级。 +Unpack and run `sudo ./deploy/install-server.sh ./portrelay-server`; run it again to upgrade. + +校验文件 Checksums:`SHA256SUMS` diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 535d4b2..a8e5bb9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ permissions: jobs: binaries: - name: Server & agent binaries + name: Server & agent archives runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -31,24 +31,22 @@ jobs: dist/*.zip macos-app: - name: macOS app + name: macOS app (dmg) runs-on: macos-15 steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version-file: go.mod - - name: Build universal app + - name: Build universal dmg run: | VERSION=${GITHUB_REF_NAME#v} case "$VERSION" in [0-9]*) ;; *) VERSION=0.0.0-${GITHUB_SHA::7} ;; esac - UNIVERSAL=1 VERSION=$VERSION ./build-app.sh - mkdir -p dist - ditto -c -k --sequesterRsrc --keepParent PortRelay.app "dist/PortRelay-$VERSION-macos-universal.zip" + UNIVERSAL=1 make dmg VERSION=$VERSION - uses: actions/upload-artifact@v4 with: name: macos-app - path: dist/*.zip + path: dist/*.dmg docker: name: Docker image @@ -88,13 +86,27 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: + - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: path: dist merge-multiple: true - name: Checksums run: cd dist && sha256sum * > SHA256SUMS + # 说明 = 标签注释正文(本次更新)+ 下载说明(区分客户端与服务端)+ 自动生成的变更列表 + - name: Release notes + run: | + git fetch --force origin "refs/tags/$GITHUB_REF_NAME:refs/tags/$GITHUB_REF_NAME" + body=$(git tag -l --format='%(contents:body)' "$GITHUB_REF_NAME") + { + if [ -n "$body" ]; then printf "## 本次更新 · What's new\n\n%s\n\n" "$body"; fi + sed -e "s|{{VERSION}}|${GITHUB_REF_NAME#v}|g" \ + -e "s|{{DOWNLOAD}}|https://github.com/$GITHUB_REPOSITORY/releases/download/$GITHUB_REF_NAME|g" \ + -e "s|{{IMAGE}}|ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/portrelay-server|g" \ + .github/release-notes.md + } > "$RUNNER_TEMP/notes.md" + cat "$RUNNER_TEMP/notes.md" - name: Create release env: GH_TOKEN: ${{ github.token }} - run: gh release create "$GITHUB_REF_NAME" dist/* --repo "$GITHUB_REPOSITORY" --title "$GITHUB_REF_NAME" --generate-notes + run: gh release create "$GITHUB_REF_NAME" dist/* --repo "$GITHUB_REPOSITORY" --title "$GITHUB_REF_NAME" --notes-file "$RUNNER_TEMP/notes.md" --generate-notes diff --git a/Makefile b/Makefile index 2ca4f3d..16c1f06 100644 --- a/Makefile +++ b/Makefile @@ -4,16 +4,19 @@ # make agent 编译当前平台的 Agent 到 bin/ # make app 构建 macOS 应用 PortRelay.app(需要 Xcode 命令行工具) # make install-app 构建并替换 /Applications/PortRelay.app(正在运行的会先退出,装好后重新打开) -# make release 打包所有平台的服务端 / Agent 到 dist/ +# make dmg 打包 macOS 安装镜像 dist/PortRelay-<版本>.dmg(UNIVERSAL=1 构建通用版本) +# make release 打包服务端(Linux)与命令行 Agent(Linux / Windows)到 dist/ # make snapshots 离屏渲染 App 界面截图(tools/ui-snapshots/out) VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null | sed 's/^v//' || echo dev) LDFLAGS := -s -w -X main.version=$(VERSION) GOBUILD := CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -PLATFORMS := linux/amd64 linux/arm64 darwin/arm64 darwin/amd64 windows/amd64 +# 服务端只发布 Linux 版本;macOS 用户用 App,其余平台用命令行 Agent +SERVER_PLATFORMS := linux/amd64 linux/arm64 +AGENT_PLATFORMS := linux/amd64 linux/arm64 windows/amd64 -.PHONY: all test fmt server agent app install-app release snapshots clean +.PHONY: all test fmt server agent app install-app dmg release snapshots clean all: test agent @@ -47,20 +50,31 @@ install-app: app echo "✓ 已安装 /Applications/PortRelay.app ($(VERSION))"; \ if [ -n "$$running" ]; then open /Applications/PortRelay.app; fi +# 安装镜像:PortRelay.app 和「应用程序」的快捷方式,打开后拖进去即可 +dmg: app + @rm -rf build/dmg && mkdir -p build/dmg dist + ditto PortRelay.app build/dmg/PortRelay.app && rm -rf PortRelay.app + ln -s /Applications build/dmg/Applications + hdiutil create -volname PortRelay -srcfolder build/dmg -fs HFS+ -format UDZO -ov dist/PortRelay-$(VERSION).dmg + @rm -rf build/dmg + +# 服务端:portrelay-server-<版本>-linux-<架构>.tar.gz(含 deploy/ 安装脚本) +# 客户端:portrelay-agent-<版本>-<系统>-<架构>.tar.gz / .zip release: - @rm -rf dist && mkdir -p dist - @for p in $(PLATFORMS); do \ - os=$${p%/*}; arch=$${p#*/}; ext=; [ $$os = windows ] && ext=.exe; \ - name=portrelay-$(VERSION)-$$os-$$arch; mkdir -p dist/$$name; \ + @rm -rf dist/portrelay-* dist/SHA256SUMS && mkdir -p dist + @pack() { \ + cmd=$$1; os=$$2; arch=$$3; ext=; [ $$os = windows ] && ext=.exe; \ + name=$$cmd-$(VERSION)-$$os-$$arch; mkdir -p dist/$$name; \ echo "==> $$name"; \ - GOOS=$$os GOARCH=$$arch $(GOBUILD) -o dist/$$name/portrelay-server$$ext ./cmd/portrelay-server || exit 1; \ - GOOS=$$os GOARCH=$$arch $(GOBUILD) -o dist/$$name/portrelay-agent$$ext ./cmd/portrelay-agent || exit 1; \ + GOOS=$$os GOARCH=$$arch $(GOBUILD) -o dist/$$name/$$cmd$$ext ./cmd/$$cmd || return 1; \ cp LICENSE README.md README_EN.md dist/$$name/; \ - if [ $$os = linux ]; then cp -R deploy dist/$$name/; fi; \ + if [ $$cmd = portrelay-server ]; then cp -R deploy dist/$$name/; fi; \ if [ $$os = windows ]; then (cd dist && zip -qr $$name.zip $$name); \ else tar -C dist -czf dist/$$name.tar.gz $$name; fi; \ rm -rf dist/$$name; \ - done + }; \ + for p in $(SERVER_PLATFORMS); do pack portrelay-server $${p%/*} $${p#*/} || exit 1; done; \ + for p in $(AGENT_PLATFORMS); do pack portrelay-agent $${p%/*} $${p#*/} || exit 1; done @cd dist && shasum -a 256 * > SHA256SUMS && cat SHA256SUMS snapshots: diff --git a/README.md b/README.md index a344f79..9a4394f 100644 --- a/README.md +++ b/README.md @@ -153,9 +153,9 @@ PortRelay 把这件事变成三步: **方式 A:二进制 + systemd(推荐)** ```bash -VERSION=1.0.0 # 见 Releases 页面 -curl -LO https://github.com/DeepFal/PortRelay/releases/download/v$VERSION/portrelay-$VERSION-linux-amd64.tar.gz -tar xzf portrelay-$VERSION-linux-amd64.tar.gz && cd portrelay-$VERSION-linux-amd64 +VERSION=1.1.0 # 见 Releases 页面;ARM64 机器把 amd64 换成 arm64 +curl -LO https://github.com/DeepFal/PortRelay/releases/download/v$VERSION/portrelay-server-$VERSION-linux-amd64.tar.gz +tar xzf portrelay-server-$VERSION-linux-amd64.tar.gz && cd portrelay-server-$VERSION-linux-amd64 sudo ./deploy/install-server.sh ./portrelay-server # 安装脚本会生成随机 token,记下来填到 Agent 里 @@ -185,7 +185,7 @@ make server # 产物:dist/portrelay-server-linux-{amd64,arm64} ### 2. 运行 Agent -**macOS App**:从 [Releases](https://github.com/DeepFal/PortRelay/releases) 下载 `PortRelay-*-macos-universal.zip`,解压后拖进“应用程序”。 +**macOS App**:从 [Releases](https://github.com/DeepFal/PortRelay/releases) 下载 `PortRelay-*.dmg`(Apple Silicon 与 Intel 通用),打开后把 PortRelay 拖进“应用程序”。 > [!NOTE] > App 未经 Apple 公证。首次打开时,在 Finder 中右键选择“打开”,或者执行 `xattr -dr com.apple.quarantine /Applications/PortRelay.app`。也可以 `make app` 自行构建。 @@ -200,7 +200,7 @@ make server # 产物:dist/portrelay-server-linux-{amd64,arm64} > 举例:Agent 通过 Tailscale 地址 `100.64.0.10` 连网关,同事在办公室局域网里用 `192.168.1.10` 访问。这时“服务器控制地址”填 `100.64.0.10:33000`,“对外访问地址”填 `192.168.1.10`,邀请链接和分享文案都会使用后者。 -**Linux / Windows**:下载对应平台的压缩包,直接运行 Agent,在浏览器打开的面板里完成同样的设置。 +**Linux / Windows**:下载对应平台的 `portrelay-agent-*` 压缩包,直接运行 Agent,在浏览器打开的面板里完成同样的设置。 ```bash ./portrelay-agent # 面板:http://127.0.0.1:33080 diff --git a/README_EN.md b/README_EN.md index f87584a..1a278bf 100644 --- a/README_EN.md +++ b/README_EN.md @@ -158,9 +158,9 @@ The gateway must be reachable by **visitors** and by **the agent**. Open TCP `33 **Option A: binary + systemd (recommended)** ```bash -VERSION=1.0.0 # see the Releases page -curl -LO https://github.com/DeepFal/PortRelay/releases/download/v$VERSION/portrelay-$VERSION-linux-amd64.tar.gz -tar xzf portrelay-$VERSION-linux-amd64.tar.gz && cd portrelay-$VERSION-linux-amd64 +VERSION=1.1.0 # see the Releases page; use arm64 instead of amd64 on ARM hosts +curl -LO https://github.com/DeepFal/PortRelay/releases/download/v$VERSION/portrelay-server-$VERSION-linux-amd64.tar.gz +tar xzf portrelay-server-$VERSION-linux-amd64.tar.gz && cd portrelay-server-$VERSION-linux-amd64 sudo ./deploy/install-server.sh ./portrelay-server # The installer generates a random token; you will enter it in the agent @@ -194,7 +194,7 @@ make server # dist/portrelay-server-linux-{amd64,arm64} ### 2. Run the agent -**macOS app.** Download `PortRelay-*-macos-universal.zip` from [Releases](https://github.com/DeepFal/PortRelay/releases), unzip it and move it to Applications. +**macOS app.** Download `PortRelay-*.dmg` (universal: Apple Silicon and Intel) from [Releases](https://github.com/DeepFal/PortRelay/releases), open it and drag PortRelay to Applications. > [!NOTE] > The app is not notarized. On first launch, right-click it in Finder and choose Open, or run `xattr -dr com.apple.quarantine /Applications/PortRelay.app`. You can also build it yourself with `make app`. @@ -209,7 +209,7 @@ Open ⚙️ Settings and fill in: > Example: the agent reaches the gateway over Tailscale at `100.64.0.10`, while teammates in the office use the LAN address `192.168.1.10`. Set the control address to `100.64.0.10:33000` and the public access address to `192.168.1.10`. Invite links and share messages will use the LAN address. -**Linux / Windows.** Download the archive for your platform, run the agent, and use the web panel that opens in your browser. +**Linux / Windows.** Download the `portrelay-agent-*` archive for your platform, run the agent, and use the web panel that opens in your browser. ```bash ./portrelay-agent # panel at http://127.0.0.1:33080