feat(node): Surge 导出透传 hysteria2 端口跳跃(port-hopping) #166
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Checks | |
| on: | |
| pull_request: | |
| types: | |
| - opened | |
| - reopened | |
| - ready_for_review | |
| paths-ignore: | |
| # 文档文件(不包括 skill-sublinkpro,它会被嵌入到二进制文件中) | |
| - '*.md' | |
| - 'docs/**' | |
| # AI 代理配置和私有文档 | |
| - '.agents/**' | |
| - '.claude/**' | |
| - '.codex/**' | |
| - 'AGENTS.md' | |
| - 'CLAUDE.md' | |
| - 'GEMINI.md' | |
| - 'CONTRIBUTING.md' | |
| # 编辑器/IDE 配置 | |
| - '.vscode/**' | |
| - '.idea/**' | |
| - '.editorconfig' | |
| # Git 配置 | |
| - '.gitignore' | |
| - '.gitattributes' | |
| # 许可证文件 | |
| - 'LICENSE' | |
| - 'COPYING' | |
| issue_comment: | |
| types: | |
| - created | |
| permissions: | |
| contents: read | |
| issues: write | |
| pull-requests: read | |
| jobs: | |
| prepare-pr-check: | |
| name: Prepare PR Check | |
| if: github.event_name == 'pull_request' || (github.event_name == 'issue_comment' && github.event.issue.pull_request) | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_run: ${{ steps.prepare.outputs.should_run }} | |
| authorized: ${{ steps.prepare.outputs.authorized }} | |
| checkout_repository: ${{ steps.prepare.outputs.checkout_repository }} | |
| checkout_ref: ${{ steps.prepare.outputs.checkout_ref }} | |
| pr_number: ${{ steps.prepare.outputs.pr_number }} | |
| steps: | |
| - name: Resolve PR context | |
| id: prepare | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| REPOSITORY: ${{ github.repository }} | |
| ACTOR: ${{ github.actor }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| COMMENT_ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| COMMENT_IS_PR: ${{ github.event.issue.pull_request && 'true' || 'false' }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | |
| PR_HEAD_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }} | |
| PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| echo "should_run=false" >> "$GITHUB_OUTPUT" | |
| echo "authorized=false" >> "$GITHUB_OUTPUT" | |
| if [ "$EVENT_NAME" = "pull_request" ]; then | |
| echo "should_run=true" >> "$GITHUB_OUTPUT" | |
| echo "authorized=true" >> "$GITHUB_OUTPUT" | |
| echo "checkout_repository=$PR_HEAD_REPOSITORY" >> "$GITHUB_OUTPUT" | |
| echo "checkout_ref=$PR_HEAD_SHA" >> "$GITHUB_OUTPUT" | |
| echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [ "$EVENT_NAME" != "issue_comment" ] || [ "$COMMENT_IS_PR" != "true" ]; then | |
| exit 0 | |
| fi | |
| command="$(printf '%s' "$COMMENT_BODY" | tr -d '\r' | head -n 1)" | |
| if [ "$command" != "/recheck" ]; then | |
| exit 0 | |
| fi | |
| pr_author="$(gh api "repos/$REPOSITORY/pulls/$COMMENT_ISSUE_NUMBER" --jq '.user.login')" | |
| checkout_repository="$(gh api "repos/$REPOSITORY/pulls/$COMMENT_ISSUE_NUMBER" --jq '.head.repo.full_name')" | |
| checkout_ref="$(gh api "repos/$REPOSITORY/pulls/$COMMENT_ISSUE_NUMBER" --jq '.head.sha')" | |
| actor_permission="$(gh api "repos/$REPOSITORY/collaborators/$ACTOR/permission" --jq '.permission' 2>/dev/null || echo "none")" | |
| authorized=false | |
| if [ "$ACTOR" = "$pr_author" ]; then | |
| authorized=true | |
| fi | |
| if [ "$actor_permission" = "admin" ]; then | |
| authorized=true | |
| fi | |
| echo "should_run=true" >> "$GITHUB_OUTPUT" | |
| echo "authorized=$authorized" >> "$GITHUB_OUTPUT" | |
| echo "checkout_repository=$checkout_repository" >> "$GITHUB_OUTPUT" | |
| echo "checkout_ref=$checkout_ref" >> "$GITHUB_OUTPUT" | |
| echo "pr_number=$COMMENT_ISSUE_NUMBER" >> "$GITHUB_OUTPUT" | |
| - name: Trigger summary | |
| if: always() | |
| run: | | |
| echo "## PR Check Trigger" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Event: ${{ github.event_name }}" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- PR: #${{ steps.prepare.outputs.pr_number || github.event.issue.number || github.event.pull_request.number }}" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Should run: ${{ steps.prepare.outputs.should_run }}" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Authorized: ${{ steps.prepare.outputs.authorized }}" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "Comment-triggered reruns require the PR author or a repository admin to comment \`/recheck\`." >> "$GITHUB_STEP_SUMMARY" | |
| backend-checks: | |
| name: Backend Checks | |
| needs: prepare-pr-check | |
| if: needs.prepare-pr-check.outputs.should_run == 'true' && needs.prepare-pr-check.outputs.authorized == 'true' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| golangci: ${{ steps.backend-summary.outputs.golangci }} | |
| gotest: ${{ steps.backend-summary.outputs.gotest }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| with: | |
| repository: ${{ needs.prepare-pr-check.outputs.checkout_repository }} | |
| ref: ${{ needs.prepare-pr-check.outputs.checkout_ref }} | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Set up Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.26.4' | |
| cache: true | |
| cache-dependency-path: go.sum | |
| - name: Download Go modules | |
| run: go mod download | |
| - name: Run golangci-lint | |
| id: golangci | |
| continue-on-error: true | |
| uses: golangci/golangci-lint-action@v9 | |
| with: | |
| version: v2.12.2 | |
| - name: Run Go tests | |
| id: gotest | |
| continue-on-error: true | |
| run: go test ./... | |
| - name: Backend check summary | |
| id: backend-summary | |
| if: always() | |
| run: | | |
| golangci_status="${{ steps.golangci.outcome }}" | |
| gotest_status="${{ steps.gotest.outcome }}" | |
| echo "golangci=$golangci_status" >> "$GITHUB_OUTPUT" | |
| echo "gotest=$gotest_status" >> "$GITHUB_OUTPUT" | |
| echo "## Backend Checks" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Check | Result |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| --- | --- |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| golangci-lint | $golangci_status |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| go test ./... | $gotest_status |" >> "$GITHUB_STEP_SUMMARY" | |
| if [ "$golangci_status" != "success" ] || [ "$gotest_status" != "success" ]; then | |
| exit 1 | |
| fi | |
| frontend-checks: | |
| name: Frontend Checks | |
| needs: prepare-pr-check | |
| if: needs.prepare-pr-check.outputs.should_run == 'true' && needs.prepare-pr-check.outputs.authorized == 'true' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| lint: ${{ steps.frontend-summary.outputs.lint }} | |
| build: ${{ steps.frontend-summary.outputs.build }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| with: | |
| repository: ${{ needs.prepare-pr-check.outputs.checkout_repository }} | |
| ref: ${{ needs.prepare-pr-check.outputs.checkout_ref }} | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24' | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Get yarn cache directory path | |
| id: yarn-cache-dir-path | |
| run: | | |
| cd webs | |
| echo "dir=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT" | |
| - name: Cache dependencies | |
| uses: actions/cache@v6 | |
| with: | |
| path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | |
| key: ${{ runner.os }}-yarn-${{ hashFiles('webs/yarn.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-yarn- | |
| - name: Install frontend dependencies | |
| run: | | |
| cd webs | |
| yarn install --immutable | |
| - name: Run frontend lint | |
| id: frontend-lint | |
| continue-on-error: true | |
| run: | | |
| cd webs | |
| yarn run lint | |
| - name: Build frontend | |
| id: frontend-build | |
| continue-on-error: true | |
| run: | | |
| cd webs | |
| yarn run build | |
| - name: Frontend check summary | |
| id: frontend-summary | |
| if: always() | |
| run: | | |
| lint_status="${{ steps.frontend-lint.outcome }}" | |
| build_status="${{ steps.frontend-build.outcome }}" | |
| echo "lint=$lint_status" >> "$GITHUB_OUTPUT" | |
| echo "build=$build_status" >> "$GITHUB_OUTPUT" | |
| echo "## Frontend Checks" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Check | Result |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| --- | --- |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| yarn run lint | $lint_status |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| yarn run build | $build_status |" >> "$GITHUB_STEP_SUMMARY" | |
| if [ "$lint_status" != "success" ] || [ "$build_status" != "success" ]; then | |
| exit 1 | |
| fi |