linux.yml 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. name: Build Linux Packages
  2. on:
  3. workflow_dispatch:
  4. inputs:
  5. version:
  6. description: "Version name"
  7. required: true
  8. type: string
  9. release:
  10. types:
  11. - published
  12. jobs:
  13. calculate_version:
  14. name: Calculate version
  15. runs-on: ubuntu-latest
  16. outputs:
  17. version: ${{ steps.outputs.outputs.version }}
  18. steps:
  19. - name: Checkout
  20. uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
  21. with:
  22. fetch-depth: 0
  23. - name: Setup Go
  24. uses: actions/setup-go@v5
  25. with:
  26. go-version: ~1.25.8
  27. - name: Check input version
  28. if: github.event_name == 'workflow_dispatch'
  29. run: |-
  30. echo "version=${{ inputs.version }}"
  31. echo "version=${{ inputs.version }}" >> "$GITHUB_ENV"
  32. - name: Calculate version
  33. if: github.event_name != 'workflow_dispatch'
  34. run: |-
  35. go run -v ./cmd/internal/read_tag --ci --nightly
  36. - name: Set outputs
  37. id: outputs
  38. run: |-
  39. echo "version=$version" >> "$GITHUB_OUTPUT"
  40. build:
  41. name: Build binary
  42. runs-on: ubuntu-latest
  43. needs:
  44. - calculate_version
  45. strategy:
  46. matrix:
  47. include:
  48. - { os: linux, arch: amd64, debian: amd64, rpm: x86_64, pacman: x86_64 }
  49. - { os: linux, arch: "386", debian: i386, rpm: i386 }
  50. - { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl }
  51. - { os: linux, arch: arm, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl }
  52. - { os: linux, arch: arm64, debian: arm64, rpm: aarch64, pacman: aarch64 }
  53. - { os: linux, arch: mips64le, debian: mips64el, rpm: mips64el }
  54. - { os: linux, arch: mipsle, debian: mipsel, rpm: mipsel }
  55. - { os: linux, arch: s390x, debian: s390x, rpm: s390x }
  56. - { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
  57. - { os: linux, arch: riscv64, debian: riscv64, rpm: riscv64 }
  58. - { os: linux, arch: loong64, debian: loongarch64, rpm: loongarch64 }
  59. steps:
  60. - name: Checkout
  61. uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
  62. with:
  63. fetch-depth: 0
  64. - name: Setup Go
  65. uses: actions/setup-go@v5
  66. with:
  67. go-version: ~1.25.8
  68. - name: Setup Android NDK
  69. if: matrix.os == 'android'
  70. uses: nttld/setup-ndk@v1
  71. with:
  72. ndk-version: r28
  73. local-cache: true
  74. - name: Set tag
  75. run: |-
  76. git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
  77. git tag v${{ needs.calculate_version.outputs.version }} -f
  78. - name: Set build tags
  79. run: |
  80. set -xeuo pipefail
  81. TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale'
  82. echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
  83. - name: Build
  84. run: |
  85. set -xeuo pipefail
  86. mkdir -p dist
  87. go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
  88. -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' \
  89. ./cmd/sing-box
  90. env:
  91. CGO_ENABLED: "0"
  92. GOOS: ${{ matrix.os }}
  93. GOARCH: ${{ matrix.arch }}
  94. GOARM: ${{ matrix.goarm }}
  95. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  96. - name: Set mtime
  97. run: |-
  98. TZ=UTC touch -t '197001010000' dist/sing-box
  99. - name: Detect track
  100. run: bash .github/detect_track.sh
  101. - name: Set version
  102. run: |-
  103. PKG_VERSION="${{ needs.calculate_version.outputs.version }}"
  104. PKG_VERSION="${PKG_VERSION//-/\~}"
  105. echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}"
  106. - name: Package DEB
  107. if: matrix.debian != ''
  108. run: |
  109. set -xeuo pipefail
  110. sudo gem install fpm
  111. sudo apt-get install -y debsigs
  112. cp .fpm_systemd .fpm
  113. fpm -t deb \
  114. --name "${NAME}" \
  115. -v "$PKG_VERSION" \
  116. -p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.debian }}.deb" \
  117. --architecture ${{ matrix.debian }} \
  118. dist/sing-box=/usr/bin/sing-box
  119. curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff'
  120. sudo patch /usr/bin/debsigs < '/tmp/debsigs.diff'
  121. rm -rf $HOME/.gnupg
  122. gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
  123. ${{ secrets.GPG_KEY }}
  124. EOF
  125. debsigs --sign=origin -k ${{ secrets.GPG_KEY_ID }} --gpgopts '--pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}"' dist/*.deb
  126. - name: Package RPM
  127. if: matrix.rpm != ''
  128. run: |-
  129. set -xeuo pipefail
  130. sudo gem install fpm
  131. cp .fpm_systemd .fpm
  132. fpm -t rpm \
  133. --name "${NAME}" \
  134. -v "$PKG_VERSION" \
  135. -p "dist/${NAME}_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.rpm }}.rpm" \
  136. --architecture ${{ matrix.rpm }} \
  137. dist/sing-box=/usr/bin/sing-box
  138. cat > $HOME/.rpmmacros <<EOF
  139. %_gpg_name ${{ secrets.GPG_KEY_ID }}
  140. %_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase ${{ secrets.GPG_PASSPHRASE }}
  141. EOF
  142. gpg --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --import <<EOF
  143. ${{ secrets.GPG_KEY }}
  144. EOF
  145. rpmsign --addsign dist/*.rpm
  146. - name: Cleanup
  147. run: rm dist/sing-box
  148. - name: Upload artifact
  149. uses: actions/upload-artifact@v4
  150. with:
  151. name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.legacy_go && '-legacy' || '' }}
  152. path: "dist"
  153. upload:
  154. name: Upload builds
  155. runs-on: ubuntu-latest
  156. needs:
  157. - calculate_version
  158. - build
  159. steps:
  160. - name: Checkout
  161. uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
  162. with:
  163. fetch-depth: 0
  164. - name: Set tag
  165. run: |-
  166. git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
  167. git tag v${{ needs.calculate_version.outputs.version }} -f
  168. echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
  169. - name: Download builds
  170. uses: actions/download-artifact@v5
  171. with:
  172. path: dist
  173. merge-multiple: true
  174. - name: Publish packages
  175. run: |-
  176. ls dist | xargs -I {} curl -F "package=@dist/{}" https://${{ secrets.FURY_TOKEN }}@push.fury.io/sagernet/