name: Build Sing-Box Core for ShellCrash

on:
  workflow_dispatch:
    inputs:
      tag1:
        description: 'project name of sing-box, such as SagerNet/sing-box'
        required: true
        type: string
      tag2:
        description: 'version of sing-box, such as v1.7.8'
        required: true
        type: string
      tag3:
        description: 'a new prerelease name (such as singbox_core_178) or only upload-artifact'
        required: false
        type: string
      tag4:
        description: 'git push as crashcore (such as singbox or singboxp) or only upload-artifact'
        required: false
        type: string
      tag5:
        description: 'build tags'
        required: false
        type: string
  workflow_call:
    inputs:
      tag1:
        required: true
        type: string
      tag2:
        required: true
        type: string
      tag3:
        required: false
        type: string
      tag4:
        required: false
        type: string
      tag5:
        required: false
        type: string

jobs:
  go:
    runs-on: ubuntu-latest
    outputs:
      version: ${{steps.go.outputs.version}}
    steps:
      - name: get latest go version
        id: go
        run: |
          echo version=$(curl -s https://raw.githubusercontent.com/actions/go-versions/update-versions-manifest-file/versions-manifest.json | grep -oE '"version": "[0-9]{1}.[0-9]{1,}(.[0-9]{1,})?"' | head -1 | cut -d':' -f2 | sed 's/ //g; s/"//g') >> $GITHUB_OUTPUT
  
  sing-box:
    runs-on: ubuntu-latest
    needs: go
    env:
      REPO: ${{ inputs.tag1 }}
      TAGS: ${{ inputs.tag5 }}
    outputs:
      version: ${{steps.sing-box.outputs.version}}
      tags: ${{steps.sing-box.outputs.tags}}
    steps:
      - uses: actions/checkout@v4.1.1
        with:
          repository: ${{ inputs.tag1 }}
          ref: ${{ inputs.tag2 }}
          fetch-depth: 0

      - name: setup go
        uses: actions/setup-go@v5.0.0
        with:
          go-version: ${{needs.go.outputs.version}}

      - name: get sing-box version
        id: sing-box
        run: |
          git remote add sekai https://github.com/SagerNet/sing-box.git
          git fetch --tags sekai
          version=$(CGO_ENABLED=0 go run ./cmd/internal/read_tag)
          [ -z "$version" ] &&  version=${{ inputs.tag2 }}
          echo version=$version >> $GITHUB_OUTPUT
          if [ -z "$TAGS" ];then
            if [ "$REPO" = 'PuerNya/sing-box' ];then
                echo tags=with_quic,with_shadowsocksr,with_ech,with_utls,with_reality_server,with_clash_api >> $GITHUB_OUTPUT
            else
                echo tags=with_quic,with_ech,with_utls,with_reality_server,with_clash_api >> $GITHUB_OUTPUT
            fi
          else
            echo tags=$TAGS >> $GITHUB_OUTPUT
          fi
  cross:
    strategy:
      matrix:
        include:
          # linux
          - name: linux-amd64
            goos: linux
            goarch: amd64
            goamd64: v1
          - name: linux-386
            goos: linux
            goarch: 386
          - name: linux-arm64
            goos: linux
            goarch: arm64
          - name: linux-armv5
            goos: linux
            goarch: arm
            goarm: 5
          - name: linux-armv7
            goos: linux
            goarch: arm
            goarm: 7
          - name: linux-mips-softfloat
            goos: linux
            goarch: mips
            gomips: softfloat
          - name: linux-mipsel-softfloat
            goos: linux
            goarch: mipsle
            gomips: softfloat
          - name: linux-mipsel-hardfloat
            goos: linux
            goarch: mipsle
            gomips: hardfloat   

      fail-fast: false
    runs-on: ubuntu-latest
    needs: 
      - go
      - sing-box
    env:
      GOOS: ${{ matrix.goos }}
      GOARCH: ${{ matrix.goarch }}
      GOAMD64: ${{ matrix.goamd64 }}
      GOARM: ${{ matrix.goarm }}
      GOMIPS: ${{ matrix.gomips }}
      CGO_ENABLED: 0
      REPO: ${{ inputs.tag1 }}
      TAGS: ${{needs.sing-box.outputs.tags}}
      VERSION: ${{needs.sing-box.outputs.version}}
    steps:
      - name: Checkout sing-box
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
        with:
          repository: ${{ inputs.tag1 }}
          ref: ${{ inputs.tag2 }}
          fetch-depth: 1
          
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{needs.go.outputs.version}}
          
      - name: checkout sing repository
        if: ${{ env.REPO == 'PuerNya/sing-box' }}
        uses: actions/checkout@v4.1.1
        with:
          ref: building
          path: sing
          repository: PuerNya/sing
          
      - name: build core
        id: build
        run: go build -v -trimpath -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${VERSION}' -s -w -buildid=" -tags "${TAGS}" ./cmd/sing-box
        
      - name: Upload file to workspace
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.name }}
          path: sing-box
          
  push_to_git:
    needs: 
      - cross
      - sing-box
    runs-on: ubuntu-latest
    env: 
      RELEASE: ${{ inputs.tag3 }}
      PUSHDIR: ${{ inputs.tag4 }}
      VERSION: ${{needs.sing-box.outputs.version}}
    steps:
      - name: Checkout ShellCrash
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
        with:
          repository: juewuy/ShellCrash
          fetch-depth: 1
          
      - name: Download file from workspace
        uses: actions/download-artifact@v4
        with:
          path: ./tmp
          
      - name: Zip core by tar
        run: |      
          for arch in amd64 armv5 armv7 arm64 mips-softfloat mipsel-hardfloat mipsel-softfloat;do
            mv -f ./tmp/linux-${arch}/sing-box ./tmp/CrashCore
            chmod +x ./tmp/CrashCore
            tar --no-same-owner -zcvf ./tmp/singbox-linux-${arch}.tar.gz -C ./tmp CrashCore
          done
          mv -f ./tmp/singbox-linux-mipsel-hardfloat.tar.gz ./tmp/singbox-linux-mipsle-hardfloat.tar.gz
          mv -f ./tmp/singbox-linux-mipsel-softfloat.tar.gz ./tmp/singbox-linux-mipsle-softfloat.tar.gz
          echo ${VERSION} > ./tmp/version

      - name: Commit and push
        if: ${{ env.PUSHDIR != '' }}
        run: |
          [ "${{ inputs.tag1 }}" = SagerNet/sing-box ] && crashcore='singbox'
          [ "${{ inputs.tag1 }}" = PuerNya/sing-box ] && crashcore='singboxp'
          mkdir -p ./bin/${crashcore}
          rm -fr ./bin/${crashcore}/*
          mv -f ./tmp/singbox-linux-*.tar.gz ./bin/${crashcore}/
          rm -fr ./tmp
          sed -i "s/${crashcore}_v=.*/${crashcore}_v=${VERSION}/" ./bin/version
          git config --global user.email "github-actions[bot]@users.noreply.github.com" && git config --global user.name "github-actions[bot]"
          git add . && git commit -m "更新${crashcore}内核至${VERSION}" || exit 0
          git push
          
      - name: Create Release and Upload Release Asset
        if: ${{ env.RELEASE != '' && env.PUSHDIR == '' }}
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ inputs.tag3 }}
          name: ${{ inputs.tag3 }}
          body: "The ${{env.VERSION}} version of ${{ inputs.tag1 }} \n这是${{ inputs.tag1 }}的${{env.VERSION}}版本内核文件\nhttps://github.com/${{ inputs.tag1 }}/releases \nOnly support for ShellCrash\n仅适配ShellCrash项目"
          draft: false
          prerelease: true
          files: |
            ./tmp/singbox*.tar.gz
            ./tmp/version
            
      - name: Cleanup Workflow
        uses: Mattraks/delete-workflow-runs@main
        with:
          retain_days: 1
          keep_minimum_runs: 2    
