github.com/metacubex/mihomo@v1.18.5/.github/workflows/build.yml (about)

     1  name: Build
     2  on:
     3    workflow_dispatch:
     4      inputs:
     5        version:
     6          description: "Tag version to release"
     7          required: true
     8    push:
     9      paths-ignore:
    10        - "docs/**"
    11        - "README.md"
    12        - ".github/ISSUE_TEMPLATE/**"
    13      branches:
    14        - Alpha
    15      tags:
    16        - "v*"
    17    pull_request_target:
    18      branches:
    19        - Alpha
    20  concurrency:
    21    group: ${{ github.workflow }}-${{ github.ref }}
    22    cancel-in-progress: true
    23    
    24  env:
    25    REGISTRY: docker.io
    26  jobs:
    27    build:
    28      runs-on: ubuntu-latest
    29      strategy:
    30        matrix:
    31          jobs:
    32            - { goos: darwin, goarch: arm64, output: arm64 }
    33            - { goos: darwin, goarch: amd64, goamd64: v1, output: amd64-compatible }
    34            - { goos: darwin, goarch: amd64, goamd64: v3, output: amd64 }
    35  
    36            - { goos: linux, goarch: '386', output: '386' }
    37            - { goos: linux, goarch: amd64, goamd64: v1, output: amd64-compatible, test: test }
    38            - { goos: linux, goarch: amd64, goamd64: v3, output: amd64 }
    39            - { goos: linux, goarch: arm64, output: arm64 }
    40            - { goos: linux, goarch: arm, goarm: '5', output: armv5 }
    41            - { goos: linux, goarch: arm, goarm: '6', output: armv6 }
    42            - { goos: linux, goarch: arm, goarm: '7', output: armv7 }
    43            - { goos: linux, goarch: mips, mips: hardfloat, output: mips-hardfloat }
    44            - { goos: linux, goarch: mips, mips: softfloat, output: mips-softfloat }
    45            - { goos: linux, goarch: mipsle, mips: hardfloat, output: mipsle-hardfloat }
    46            - { goos: linux, goarch: mipsle, mips: softfloat, output: mipsle-softfloat }
    47            - { goos: linux, goarch: mips64, output: mips64 }
    48            - { goos: linux, goarch: mips64le, output: mips64le }
    49            - { goos: linux, goarch: loong64, output: loong64-abi1, abi: '1' }
    50            - { goos: linux, goarch: loong64, output: loong64-abi2, abi: '2' }
    51            - { goos: linux, goarch: riscv64, output: riscv64 }
    52            - { goos: linux, goarch: s390x, output: s390x }
    53  
    54            - { goos: windows, goarch: '386', output: '386' }
    55            - { goos: windows, goarch: amd64, goamd64: v1, output: amd64-compatible }
    56            - { goos: windows, goarch: amd64, goamd64: v3, output: amd64 }
    57            - { goos: windows, goarch: arm, goarm: '7', output: armv7 }
    58            - { goos: windows, goarch: arm64, output: arm64 }
    59  
    60            - { goos: freebsd, goarch: '386', output: '386' }
    61            - { goos: freebsd, goarch: amd64, goamd64: v1, output: amd64-compatible }
    62            - { goos: freebsd, goarch: amd64, goamd64: v3, output: amd64 }
    63            - { goos: freebsd, goarch: arm64, output: arm64 }
    64  
    65            - { goos: android, goarch: '386', ndk: i686-linux-android34, output: '386' }
    66            - { goos: android, goarch: amd64, ndk: x86_64-linux-android34, output: amd64 }
    67            - { goos: android, goarch: arm, ndk: armv7a-linux-androideabi34, output: armv7 }
    68            - { goos: android, goarch: arm64, ndk: aarch64-linux-android34, output: arm64-v8 }
    69  
    70            # Go 1.21 can revert commit `9e4385` to work on Windows 7
    71            # https://github.com/golang/go/issues/64622#issuecomment-1847475161
    72            # (OR we can just use golang1.21.4 which unneeded any patch)
    73            - { goos: windows, goarch: '386', output: '386-go121', goversion: '1.21' }
    74            - { goos: windows, goarch: amd64, goamd64: v1, output: amd64-compatible-go121, goversion: '1.21' }
    75            - { goos: windows, goarch: amd64, goamd64: v3, output: amd64-go121, goversion: '1.21' }
    76  
    77            # Go 1.20 is the last release that will run on any release of Windows 7, 8, Server 2008 and Server 2012. Go 1.21 will require at least Windows 10 or Server 2016.
    78            - { goos: windows, goarch: '386', output: '386-go120', goversion: '1.20' }
    79            - { goos: windows, goarch: amd64, goamd64: v1, output: amd64-compatible-go120, goversion: '1.20' }
    80            - { goos: windows, goarch: amd64, goamd64: v3, output: amd64-go120, goversion: '1.20' }
    81  
    82            # Go 1.20 is the last release that will run on macOS 10.13 High Sierra or 10.14 Mojave. Go 1.21 will require macOS 10.15 Catalina or later.
    83            - { goos: darwin, goarch: arm64, output: arm64-go120, goversion: '1.20' }
    84            - { goos: darwin, goarch: amd64, goamd64: v1, output: amd64-compatible-go120, goversion: '1.20' }
    85            - { goos: darwin, goarch: amd64, goamd64: v3, output: amd64-go120, goversion: '1.20' }
    86  
    87            # only for test
    88            - { goos: linux, goarch: '386', output: '386-go120', goversion: '1.20' }
    89            - { goos: linux, goarch: amd64, goamd64: v1, output: amd64-compatible-go120, goversion: '1.20', test: test }
    90            - { goos: linux, goarch: amd64, goamd64: v3, output: amd64-go120, goversion: '1.20' }
    91  
    92      steps:
    93      - uses: actions/checkout@v4
    94  
    95      - name: Set up Go
    96        if: ${{ matrix.jobs.goversion == '' && matrix.jobs.goarch != 'loong64' }}
    97        uses: actions/setup-go@v5
    98        with:
    99          go-version: '1.22'
   100  
   101      - name: Set up Go
   102        if: ${{ matrix.jobs.goversion != '' && matrix.jobs.goarch != 'loong64' }}
   103        uses: actions/setup-go@v5
   104        with:
   105          go-version: ${{ matrix.jobs.goversion }}
   106  
   107      - name: Set up Go1.22 loongarch abi1
   108        if: ${{ matrix.jobs.goarch == 'loong64' && matrix.jobs.abi == '1' }}
   109        run: |
   110          wget -q https://github.com/xishang0128/loongarch64-golang/releases/download/1.22.0/go1.22.0.linux-amd64-abi1.tar.gz
   111          sudo tar zxf go1.22.0.linux-amd64-abi1.tar.gz -C /usr/local
   112          echo "/usr/local/go/bin" >> $GITHUB_PATH
   113  
   114      - name: Set up Go1.22 loongarch abi2
   115        if: ${{ matrix.jobs.goarch == 'loong64' && matrix.jobs.abi == '2' }}
   116        run: |
   117          wget -q https://github.com/xishang0128/loongarch64-golang/releases/download/1.22.0/go1.22.0.linux-amd64-abi2.tar.gz
   118          sudo tar zxf go1.22.0.linux-amd64-abi2.tar.gz -C /usr/local
   119          echo "/usr/local/go/bin" >> $GITHUB_PATH
   120  
   121        # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557
   122        # this patch file only works on golang1.22.x
   123        # that means after golang1.23 release it must be changed
   124        # revert:
   125        # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng"
   126        # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7"
   127        # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround"
   128      - name: Revert Golang1.22 commit for Windows7/8
   129        if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '' }}
   130        run: |
   131          cd $(go env GOROOT)
   132          patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff
   133          patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff
   134          patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff
   135  
   136        # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557
   137      - name: Revert Golang1.21 commit for Windows7/8
   138        if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.21' }}
   139        run: |
   140          cd $(go env GOROOT)
   141          curl https://github.com/golang/go/commit/9e43850a3298a9b8b1162ba0033d4c53f8637571.diff | patch --verbose -R -p 1
   142  
   143      - name: Set variables
   144        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }}
   145        run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
   146        shell: bash
   147  
   148      - name: Set variables
   149        if: ${{ github.event_name != 'workflow_dispatch' && github.ref_name == 'Alpha' }}
   150        run: echo "VERSION=alpha-$(git rev-parse --short HEAD)" >> $GITHUB_ENV
   151        shell: bash
   152  
   153      - name: Set Time Variable
   154        run: |
   155          echo "BUILDTIME=$(date)" >> $GITHUB_ENV
   156          echo "CGO_ENABLED=0" >> $GITHUB_ENV
   157          echo "BUILDTAG=-extldflags --static" >> $GITHUB_ENV
   158  
   159      - name: Setup NDK
   160        if: ${{ matrix.jobs.goos == 'android' }}
   161        uses: nttld/setup-ndk@v1
   162        id: setup-ndk
   163        with:
   164          ndk-version: r26c
   165  
   166      - name: Set NDK path
   167        if: ${{ matrix.jobs.goos == 'android' }}
   168        run: |
   169          echo "CC=${{steps.setup-ndk.outputs.ndk-path}}/toolchains/llvm/prebuilt/linux-x86_64/bin/${{matrix.jobs.ndk}}-clang" >> $GITHUB_ENV
   170          echo "CGO_ENABLED=1" >> $GITHUB_ENV
   171          echo "BUILDTAG=" >> $GITHUB_ENV
   172  
   173      - name: Test
   174        if: ${{ matrix.jobs.test == 'test' }}
   175        run: |
   176          go test ./...
   177  
   178      - name: Update CA
   179        run: |
   180          sudo apt-get install ca-certificates
   181          sudo update-ca-certificates
   182          cp -f /etc/ssl/certs/ca-certificates.crt component/ca/ca-certificates.crt
   183  
   184      - name: Build core
   185        env:
   186          GOOS: ${{matrix.jobs.goos}}
   187          GOARCH: ${{matrix.jobs.goarch}}
   188          GOAMD64: ${{matrix.jobs.goamd64}}
   189          GOARM: ${{matrix.jobs.arm}}
   190          GOMIPS: ${{matrix.jobs.mips}}
   191        run: |
   192          echo $CGO_ENABLED
   193          go build -v -tags "with_gvisor" -trimpath -ldflags "${BUILDTAG} -X 'github.com/metacubex/mihomo/constant.Version=${VERSION}' -X 'github.com/metacubex/mihomo/constant.BuildTime=${BUILDTIME}' -w -s -buildid="
   194          if [ "${{matrix.jobs.goos}}" = "windows" ]; then
   195            cp mihomo.exe mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}.exe
   196            zip -r mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}.zip mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}.exe
   197          else
   198            cp mihomo mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}
   199            gzip -c mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}} > mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}.gz
   200            rm mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}
   201          fi
   202  
   203      - name: Create DEB package
   204        if: ${{ matrix.jobs.goos == 'linux' && !contains(matrix.jobs.goarch, 'mips') }}
   205        run: |
   206          sudo apt-get install dpkg
   207          if [ "${{matrix.jobs.abi}}" = "1" ]; then
   208            ARCH=loongarch64
   209          else
   210            ARCH=${{matrix.jobs.goarch}}
   211          fi
   212          PackageVersion=$(curl -s "https://api.github.com/repos/MetaCubeX/mihomo/releases/latest" | grep -o '"tag_name": "[^"]*' | grep -o '[^"]*$' | sed 's/v//g' )
   213          if [ $(git branch | awk -F ' ' '{print $2}') = "Alpha" ]; then
   214            PackageVersion="$(echo "${PackageVersion}" | awk -F '.' '{$NF = $NF + 1; print}' OFS='.')-${VERSION}"
   215          fi
   216  
   217          mkdir -p mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/DEBIAN
   218          mkdir -p mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/usr/bin
   219          mkdir -p mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/etc/mihomo
   220          mkdir -p mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/etc/systemd/system/
   221          mkdir -p mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/usr/share/licenses/mihomo
   222  
   223          cp mihomo mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/usr/bin/mihomo
   224          cp LICENSE mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/usr/share/licenses/mihomo/
   225          cp .github/mihomo.service mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/etc/systemd/system/
   226  
   227          cat > mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/etc/mihomo/config.yaml <<EOF
   228          mixed-port: 7890
   229          external-controller: 127.0.0.1:9090
   230          EOF
   231  
   232          cat > mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}/DEBIAN/control <<EOF
   233          Package: mihomo
   234          Version: ${PackageVersion}
   235          Section:
   236          Priority: extra
   237          Architecture: ${ARCH}
   238          Maintainer: MetaCubeX <none@example.com>
   239          Homepage: https://wiki.metacubex.one/
   240          Description: The universal proxy platform.
   241          EOF
   242  
   243          dpkg-deb -Z gzip --build mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}
   244  
   245      - name: Convert DEB to RPM
   246        if: ${{ matrix.jobs.goos == 'linux' && !contains(matrix.jobs.goarch, 'mips') }}
   247        run: |
   248          sudo apt-get install -y alien
   249          alien --to-rpm --scripts mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}.deb
   250          mv mihomo*.rpm mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}.rpm
   251  
   252      # - name: Convert DEB to PKG
   253      #   if: ${{ matrix.jobs.goos == 'linux' && !contains(matrix.jobs.goarch, 'mips') && !contains(matrix.jobs.goarch, 'loong64') }}
   254      #   run: |
   255      #     docker pull archlinux
   256      #     docker run --rm -v ./:/mnt archlinux bash -c "
   257      #       pacman -Syu pkgfile base-devel --noconfirm
   258      #       curl -L https://github.com/helixarch/debtap/raw/master/debtap > /usr/bin/debtap
   259      #       chmod 755 /usr/bin/debtap
   260      #       debtap -u 
   261      #       debtap -Q /mnt/mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}.deb
   262      #     "
   263      #     mv mihomo*.pkg.tar.zst mihomo-${{matrix.jobs.goos}}-${{matrix.jobs.output}}-${VERSION}.pkg.tar.zst
   264  
   265      - name: Save version
   266        run: |
   267          echo ${VERSION} > version.txt
   268        shell: bash
   269  
   270      - name: Archive production artifacts
   271        uses: actions/upload-artifact@v4
   272        with:
   273          name: ${{ matrix.jobs.goos }}-${{ matrix.jobs.output }}
   274          path: |
   275            mihomo*.gz
   276            mihomo*.deb
   277            mihomo*.rpm
   278            mihomo*.zip
   279            version.txt
   280  
   281    Upload-Prerelease:
   282      permissions: write-all
   283      if: ${{ github.event_name != 'workflow_dispatch' && github.ref_type == 'branch' && !startsWith(github.event_name, 'pull_request') }}
   284      needs: [build]
   285      runs-on: ubuntu-latest
   286      steps:
   287      - name: Download all workflow run artifacts
   288        uses: actions/download-artifact@v4
   289        with:
   290          path: bin/
   291          merge-multiple: true
   292  
   293      - name: Delete current release assets
   294        uses: 8Mi-Tech/delete-release-assets-action@main
   295        with:
   296          github_token: ${{ secrets.GITHUB_TOKEN }}
   297          tag: Prerelease-${{ github.ref_name }}
   298          deleteOnlyFromDrafts: false
   299      - name: Set Env
   300        run: |
   301          echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV
   302        shell: bash
   303  
   304      - name: Tag Repo
   305        uses: richardsimko/update-tag@v1
   306        with:
   307          tag_name: Prerelease-${{ github.ref_name }}
   308        env:
   309          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
   310        
   311      - run: |
   312          cat > release.txt << 'EOF'
   313          Release created at  ${{ env.BUILDTIME }}
   314          Synchronize ${{ github.ref_name }} branch code updates, keeping only the latest version
   315          <br>
   316          [我应该下载哪个文件? / Which file should I download?](https://github.com/MetaCubeX/mihomo/wiki/FAQ)
   317          [二进制文件筛选 / Binary file selector](https://metacubex.github.io/Meta-Docs/startup/#_1)
   318          [查看文档 / Docs](https://metacubex.github.io/Meta-Docs/)
   319          EOF
   320  
   321      - name: Upload Prerelease
   322        uses: softprops/action-gh-release@v1
   323        if: ${{  success() }}
   324        with:
   325          tag_name: Prerelease-${{ github.ref_name }}
   326          files: |
   327            bin/*
   328          prerelease: true
   329          generate_release_notes: true
   330          body_path: release.txt
   331  
   332    Upload-Release:
   333      permissions: write-all
   334      if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }}
   335      needs: [build]
   336      runs-on: ubuntu-latest
   337      steps:
   338        - name: Checkout
   339          uses: actions/checkout@v4
   340          with:
   341            ref: Meta
   342            fetch-depth: '0'
   343            fetch-tags: 'true'
   344  
   345        - name: Get tags
   346          run: |
   347            echo "CURRENTVERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
   348            git fetch --tags
   349            echo "PREVERSION=$(git describe --tags --abbrev=0 HEAD)" >> $GITHUB_ENV
   350  
   351        - name: Merge Alpha branch into Meta
   352          run: |
   353            git config --global user.email "github-actions[bot]@users.noreply.github.com"
   354            git config --global user.name "github-actions[bot]"
   355            git fetch origin Alpha:Alpha
   356            git merge Alpha
   357            git push origin Meta
   358          env:
   359            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
   360  
   361        - name: Tag the commit
   362          run: |
   363            git tag ${{ github.event.inputs.version }}
   364            git push origin ${{ github.event.inputs.version }}
   365          env:
   366            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
   367  
   368        - name: Generate release notes
   369          run: |
   370              cp ./.github/genReleaseNote.sh ./
   371              bash ./genReleaseNote.sh -v ${PREVERSION}...${CURRENTVERSION}
   372              rm ./genReleaseNote.sh
   373    
   374        - uses: actions/download-artifact@v4
   375          with:
   376            path: bin/
   377            merge-multiple: true
   378    
   379        - name: Display structure of downloaded files
   380          run: ls -R
   381          working-directory: bin
   382    
   383        - name: Upload Release
   384          uses: softprops/action-gh-release@v2
   385          if: ${{ success() }}
   386          with:
   387            tag_name: ${{ github.event.inputs.version }}
   388            files: bin/*
   389            body_path: release.md
   390  
   391    Docker:
   392      if: ${{ !startsWith(github.event_name, 'pull_request') }}
   393      permissions: write-all
   394      needs: [build]
   395      runs-on: ubuntu-latest
   396      steps:
   397        - name: Checkout repository
   398          uses: actions/checkout@v4
   399          with:
   400            fetch-depth: 0
   401  
   402        - uses: actions/download-artifact@v4
   403          with:
   404            path: bin/
   405            merge-multiple: true
   406  
   407        - name: Display structure of downloaded files
   408          run: ls -R
   409          working-directory: bin
   410  
   411        - name: Set up QEMU
   412          uses: docker/setup-qemu-action@v3
   413  
   414        - name: Setup Docker buildx
   415          uses: docker/setup-buildx-action@v3
   416          with:
   417            version: latest
   418  
   419        # Extract metadata (tags, labels) for Docker
   420        # https://github.com/docker/metadata-action
   421        - name: Extract Docker metadata
   422          id: meta
   423          uses: docker/metadata-action@v5
   424          with:
   425            images: ${{ env.REGISTRY }}/${{ github.repository }}
   426  
   427        - name: Show files
   428          run: |
   429            ls .
   430            ls bin/
   431  
   432        - name: login to docker REGISTRY
   433          uses: docker/login-action@v3
   434          with:
   435            registry: ${{ env.REGISTRY }}
   436            username: ${{ secrets.DOCKER_HUB_USER }}
   437            password: ${{ secrets.DOCKER_HUB_TOKEN }}
   438  
   439        # Build and push Docker image with Buildx (don't push on PR)
   440        # https://github.com/docker/build-push-action
   441        - name: Build and push Docker image
   442          id: build-and-push
   443          uses: docker/build-push-action@v5
   444          with:
   445            context: .
   446            file: ./Dockerfile
   447            push: ${{ github.event_name != 'pull_request' }}
   448            platforms: |
   449              linux/386
   450              linux/amd64
   451              linux/arm64
   452              linux/arm/v7
   453            tags: ${{ steps.meta.outputs.tags }}
   454            labels: ${{ steps.meta.outputs.labels }}