github actions
1. 自动编译放到release name: Go Build and Release on: push: branches: [ "main" ] pull_request:
github actions
发布时间:2025-06-22 (2025-06-22)

1. 自动编译放到release

name: Go Build and Release

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write  # 允许推送标签和代码
    steps:
    - uses: actions/checkout@v4

    - name: Set up Go
      uses: actions/setup-go@v4
      with:
        go-version: '1.24'

    - name: Build
      run: go build -v -o main ./...

    - name: Test
      run: go test -v ./...

    - name: Tag Version
      if: github.ref == 'refs/heads/main'
      run: |
        git config --local user.email "action@github.com"
        git config --local user.name "GitHub Action"
        TAG="v$(date +'%Y%m%d%H%M%S')"  # 示例:自动生成时间戳标签
        echo "TAG=${TAG}" >> $GITHUB_ENV  # 将变量导出到后续步骤
        git tag $TAG
        git push origin $TAG
    
    - name: Create Release
      if: github.ref == 'refs/heads/main'
      uses: softprops/action-gh-release@v1
      with:
        files: main
        tag_name: ${{ env.TAG }}  # 引用上面创建的标签
        generate_release_notes: true
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

这个理论上来说你们应该可以一下子走通

然后基于这个修改一下

2. 推送v开头的tag才进行此操作

name: Go Build and Release

on:
  push:
    tags:
      - "v*"  # 只有推送 v 开头的 tag 时才触发整个工作流

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write  # 允许发布 Release
    steps:
      # 检出代码(必须包含 fetch-depth: 0 才能读取 tag)
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      # 设置 Go 环境
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24'

      # 编译
      - name: Build
        run: go build -v -o main ./.

      # 发布到 GitHub Release(自动使用触发的 tag)
      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: main          # 上传编译好的二进制文件
          tag_name: ${{ github.ref_name }}  # 使用触发的 tag
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

3. 构建release的时候,把项目文件也带上

name: Go Build and Release

on:
  push:
    tags:
      - "v*"  # 只有推送 v 开头的 tag 时才触发整个工作流

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write  # 允许发布 Release
    steps:
      # 检出代码(必须包含 fetch-depth: 0 才能读取 tag)
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      # 设置 Go 环境
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24'

      # 编译
      - name: Build
        run: go build -v -o main ./.

      # 发布到 GitHub Release(自动使用触发的 tag)
      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: |
            main
            settings.yaml
          tag_name: ${{ github.ref_name }}  # 使用触发的 tag
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4. 交叉编译,跨平台打包

name: Go Build and Release

on:
  push:
    tags:
      - "v*"  # 仅 v 开头的 tag 触发

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    strategy:
      matrix:
        platform:
          - { os: linux, goos: linux, goarch: amd64, suffix: "" }
          - { os: linux, goos: linux, goarch: arm64, suffix: "-arm64" }
          - { os: windows, goos: windows, goarch: amd64, suffix: ".exe" }
          - { os: macos, goos: darwin, goarch: amd64, suffix: "-darwin" }
          - { os: macos, goos: darwin, goarch: arm64, suffix: "-darwin-arm64" }
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24'

      - name: Build
        env:
          GOOS: ${{ matrix.platform.goos }}
          GOARCH: ${{ matrix.platform.goarch }}
          CGO_ENABLED: 0  # 静态编译
        run: |
          output_name="main-${{ matrix.platform.goos }}-${{ matrix.platform.goarch }}${{ matrix.platform.suffix }}"
          go build -v -o $output_name .
          echo "BINARY_NAME=$output_name" >> $GITHUB_ENV

      - name: Upload Artifact
        uses: actions/upload-artifact@v4  
        with:
          name: ${{ env.BINARY_NAME }}
          path: ${{ env.BINARY_NAME }}

  release:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Download Artifacts
        uses: actions/download-artifact@v4  # 同步升级到 v4
        with:
          path: artifacts
          merge-multiple: true  # 关键修复:合并文件

      - name: Verify Files
        run: ls -R artifacts  # 调试用

      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: |
            artifacts/main-darwin-amd64-darwin
            artifacts/main-darwin-arm64-darwin-arm64
            artifacts/main-linux-amd64
            artifacts/main-linux-arm64-arm64
            artifacts/main-windows-amd64.exe
          tag_name: ${{ github.ref_name }}
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

5. 增加打docker镜像包

name: Go Build, Dockerize and Release

on:
  push:
    tags:
      - "v*"  # 仅 v 开头的 tag 触发

env:
  DOCKER_IMAGE_NAME: myapp  # Docker镜像名称

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    strategy:
      matrix:
        platform:
          - { os: linux, goos: linux, goarch: amd64, suffix: "" }
          - { os: linux, goos: linux, goarch: arm64, suffix: "-arm64" }
          - { os: windows, goos: windows, goarch: amd64, suffix: ".exe" }
          - { os: macos, goos: darwin, goarch: amd64, suffix: "-darwin" }
          - { os: macos, goos: darwin, goarch: arm64, suffix: "-darwin-arm64" }
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24'

      - name: Build
        env:
          GOOS: ${{ matrix.platform.goos }}
          GOARCH: ${{ matrix.platform.goarch }}
          CGO_ENABLED: 0  # 静态编译
        run: |
          output_name="main-${{ matrix.platform.goos }}-${{ matrix.platform.goarch }}${{ matrix.platform.suffix }}"
          go build -v -o $output_name .
          echo "BINARY_NAME=$output_name" >> $GITHUB_ENV

      - name: Upload Artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.BINARY_NAME }}
          path: ${{ env.BINARY_NAME }}

  docker:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4

      - name: Download Linux Binary
        uses: actions/download-artifact@v4
        with:
          name: main-linux-amd64
          path: docker-build/

      - name: Set up Docker
        uses: docker/setup-buildx-action@v2

      - name: Build Docker Image
        run: |
          cp Dockerfile docker-build/
          cd docker-build
          docker build -t ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }} .
          docker save ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }} > ${{ env.DOCKER_IMAGE_NAME }}.tar
          gzip ${{ env.DOCKER_IMAGE_NAME }}.tar
          echo "DOCKER_TAR=${{ env.DOCKER_IMAGE_NAME }}.tar.gz" >> $GITHUB_ENV

      - name: Upload Docker Image
        uses: actions/upload-artifact@v4
        with:
          name: docker-image
          path: docker-build/${{ env.DOCKER_TAR }}

  release:
    needs: [build, docker]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Download Binaries
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Download Docker Image
        uses: actions/download-artifact@v4
        with:
          name: docker-image
          path: artifacts

      - name: Verify Files
        run: ls -R artifacts

      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: |
            artifacts/main-darwin-amd64-darwin
            artifacts/main-darwin-arm64-darwin-arm64
            artifacts/main-linux-amd64
            artifacts/main-linux-arm64-arm64
            artifacts/main-windows-amd64.exe
            artifacts/${{ env.DOCKER_IMAGE_NAME }}.tar.gz
          tag_name: ${{ github.ref_name }}
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Dockerfile

FROM alpine
COPY main-linux-amd64 /app
RUN chmod +x /app
ENTRYPOINT ["/app"]

6. 将docker镜像发送到服务器,并执行命令

必须得要个云服务器才行

name: Go Build, Dockerize and Release

on:
  push:
    tags:
      - "v*"  # 仅 v 开头的 tag 触发

env:
  DOCKER_IMAGE_NAME: myapp  # Docker镜像名称
  SSH_HOST:  ${{ secrets.SSH_HOST }} # 云服务器地址
  SSH_PORT: 22  # SSH端口
  SSH_USER: root
  DEPLOY_DIR: /opt/myapp  # 云服务器部署目录

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    strategy:
      matrix:
        platform:
          - { os: linux, goos: linux, goarch: amd64, suffix: "" }
          - { os: linux, goos: linux, goarch: arm64, suffix: "-arm64" }
          - { os: windows, goos: windows, goarch: amd64, suffix: ".exe" }
          - { os: macos, goos: darwin, goarch: amd64, suffix: "-darwin" }
          - { os: macos, goos: darwin, goarch: arm64, suffix: "-darwin-arm64" }
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24'

      - name: Build
        env:
          GOOS: ${{ matrix.platform.goos }}
          GOARCH: ${{ matrix.platform.goarch }}
          CGO_ENABLED: 0  # 静态编译
        run: |
          output_name="main-${{ matrix.platform.goos }}-${{ matrix.platform.goarch }}${{ matrix.platform.suffix }}"
          go build -v -o $output_name .
          echo "BINARY_NAME=$output_name" >> $GITHUB_ENV

      - name: Upload Artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.BINARY_NAME }}
          path: ${{ env.BINARY_NAME }}

  docker:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4

      - name: Download Linux Binary
        uses: actions/download-artifact@v4
        with:
          name: main-linux-amd64
          path: docker-build/

      - name: Set up Docker
        uses: docker/setup-buildx-action@v2

      - name: Build Docker Image
        run: |
          cp Dockerfile docker-build/
          cd docker-build
          docker build -t ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }} .
          docker save ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }} > ${{ env.DOCKER_IMAGE_NAME }}.tar
          gzip ${{ env.DOCKER_IMAGE_NAME }}.tar
          echo "DOCKER_TAR=${{ env.DOCKER_IMAGE_NAME }}.tar.gz" >> $GITHUB_ENV

      - name: Upload Docker Image
        uses: actions/upload-artifact@v4
        with:
          name: docker-image
          path: docker-build/${{ env.DOCKER_TAR }}

  release:
    needs: [build, docker]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Download Binaries
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Download Docker Image
        uses: actions/download-artifact@v4
        with:
          name: docker-image
          path: artifacts

      - name: Verify Files
        run: ls -R artifacts

      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: |
            artifacts/main-darwin-amd64-darwin
            artifacts/main-darwin-arm64-darwin-arm64
            artifacts/main-linux-amd64
            artifacts/main-linux-arm64-arm64
            artifacts/main-windows-amd64.exe
            artifacts/${{ env.DOCKER_IMAGE_NAME }}.tar.gz
          tag_name: ${{ github.ref_name }}
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  deploy:
    needs: docker
    runs-on: ubuntu-latest
    steps:
      - name: Download Docker Image
        uses: actions/download-artifact@v4
        with:
          name: docker-image
          path: artifacts

      - name: Install sshpass
        run: sudo apt-get install -y sshpass

      - name: Deploy via Password
        env:
          SSH_PASSWORD: ${{ secrets.SSH_PASSWORD }}  # 密码存储在GitHub Secrets
        run: |
          sshpass -p "$SSH_PASSWORD" ssh -o StrictHostKeyChecking=no \
            ${{ env.SSH_USER }}@${{ secrets.SSH_HOST }} \
            "echo 'Deployment commands here'"

      - name: Deploy to Cloud Server
        env:
          SSH_EXTRA_OPTS: -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
        run: |
          # 1. 上传Docker镜像到服务器
          sshpass -p ${{ secrets.SSH_PASSWORD }}  scp -P ${{ env.SSH_PORT }} ${{ env.SSH_EXTRA_OPTS }} \
            artifacts/${{ env.DOCKER_IMAGE_NAME }}.tar.gz \
            ${{ env.SSH_USER }}@${{ env.SSH_HOST }}:${{ env.DEPLOY_DIR }}
          
          echo "镜像上传成功"
          
          # 2. 执行远程部署命令
          sshpass -p ${{ secrets.SSH_PASSWORD }}  ssh -p ${{ env.SSH_PORT }} ${{ env.SSH_EXTRA_OPTS }} \
            ${{ env.SSH_USER }}@${{ env.SSH_HOST }} \
            "set -e && \
            cd ${{ env.DEPLOY_DIR }} && \
            docker load -i ${{ env.DOCKER_IMAGE_NAME }}.tar.gz && \
            docker stop \$(docker ps -q --filter name=${{ env.DOCKER_IMAGE_NAME }}) || true && \
            docker rm \$(docker ps -aq --filter name=${{ env.DOCKER_IMAGE_NAME }}) || true && \
            docker run -d \
              --name ${{ env.DOCKER_IMAGE_NAME }} \
              -p 8000:8000 \
              --restart unless-stopped \
              ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }}"

7. 把版本信息打进go文件

通过动态注入的方式

name: Go Build, Dockerize and Release

on:
  push:
    tags:
      - "v*"  # 仅 v 开头的 tag 触发

env:
  DOCKER_IMAGE_NAME: myapp  # Docker镜像名称
  SSH_HOST:  ${{ secrets.SSH_HOST }} # 云服务器地址
  SSH_PORT: 22  # SSH端口
  SSH_USER: root
  DEPLOY_DIR: /opt/myapp  # 云服务器部署目录

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    strategy:
      matrix:
        platform:
          - { os: linux, goos: linux, goarch: amd64, suffix: "" }
          - { os: linux, goos: linux, goarch: arm64, suffix: "-arm64" }
          - { os: windows, goos: windows, goarch: amd64, suffix: ".exe" }
          - { os: macos, goos: darwin, goarch: amd64, suffix: "-darwin" }
          - { os: macos, goos: darwin, goarch: arm64, suffix: "-darwin-arm64" }
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24'

      - name: Build
        env:
          GOOS: ${{ matrix.platform.goos }}
          GOARCH: ${{ matrix.platform.goarch }}
          CGO_ENABLED: 0  # 静态编译
        run: |
          output_name="main-${{ matrix.platform.goos }}-${{ matrix.platform.goarch }}${{ matrix.platform.suffix }}"
          go build -v -ldflags "-X 'main.version=${{ github.ref_name }}' -X 'main.buildTime=$(date -u +"%Y-%m-%dT%H:%M:%SZ")' -X 'main.gitCommit=${{ github.sha }}'"  -o $output_name .
          echo "BINARY_NAME=$output_name" >> $GITHUB_ENV

      - name: Upload Artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.BINARY_NAME }}
          path: ${{ env.BINARY_NAME }}

  docker:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4

      - name: Download Linux Binary
        uses: actions/download-artifact@v4
        with:
          name: main-linux-amd64
          path: docker-build/

      - name: Set up Docker
        uses: docker/setup-buildx-action@v2

      - name: Build Docker Image
        run: |
          cp Dockerfile docker-build/
          cd docker-build
          docker build -t ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }} .
          docker save ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }} > ${{ env.DOCKER_IMAGE_NAME }}.tar
          gzip ${{ env.DOCKER_IMAGE_NAME }}.tar
          echo "DOCKER_TAR=${{ env.DOCKER_IMAGE_NAME }}.tar.gz" >> $GITHUB_ENV

      - name: Upload Docker Image
        uses: actions/upload-artifact@v4
        with:
          name: docker-image
          path: docker-build/${{ env.DOCKER_TAR }}

  release:
    needs: [build, docker]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Download Binaries
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Download Docker Image
        uses: actions/download-artifact@v4
        with:
          name: docker-image
          path: artifacts

      - name: Verify Files
        run: ls -R artifacts

      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: |
            artifacts/main-darwin-amd64-darwin
            artifacts/main-darwin-arm64-darwin-arm64
            artifacts/main-linux-amd64
            artifacts/main-linux-arm64-arm64
            artifacts/main-windows-amd64.exe
            artifacts/${{ env.DOCKER_IMAGE_NAME }}.tar.gz
          tag_name: ${{ github.ref_name }}
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  deploy:
    needs: docker
    runs-on: ubuntu-latest
    steps:
      - name: Download Docker Image
        uses: actions/download-artifact@v4
        with:
          name: docker-image
          path: artifacts

      - name: Install sshpass
        run: sudo apt-get install -y sshpass

      - name: Deploy via Password
        env:
          SSH_PASSWORD: ${{ secrets.SSH_PASSWORD }}  # 密码存储在GitHub Secrets
        run: |
          sshpass -p "$SSH_PASSWORD" ssh -o StrictHostKeyChecking=no \
            ${{ env.SSH_USER }}@${{ secrets.SSH_HOST }} \
            "echo 'Deployment commands here'"

      - name: Deploy to Cloud Server
        env:
          SSH_EXTRA_OPTS: -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
        run: |
          # 1. 上传Docker镜像到服务器
          sshpass -p ${{ secrets.SSH_PASSWORD }}  scp -P ${{ env.SSH_PORT }} ${{ env.SSH_EXTRA_OPTS }} \
            artifacts/${{ env.DOCKER_IMAGE_NAME }}.tar.gz \
            ${{ env.SSH_USER }}@${{ env.SSH_HOST }}:${{ env.DEPLOY_DIR }}
          
          echo "镜像上传成功"
          
          # 2. 执行远程部署命令
          sshpass -p ${{ secrets.SSH_PASSWORD }}  ssh -p ${{ env.SSH_PORT }} ${{ env.SSH_EXTRA_OPTS }} \
            ${{ env.SSH_USER }}@${{ env.SSH_HOST }} \
            "set -e && \
            cd ${{ env.DEPLOY_DIR }} && \
            docker load -i ${{ env.DOCKER_IMAGE_NAME }}.tar.gz && \
            docker stop \$(docker ps -q --filter name=${{ env.DOCKER_IMAGE_NAME }}) || true && \
            docker rm \$(docker ps -aq --filter name=${{ env.DOCKER_IMAGE_NAME }}) || true && \
            docker run -d \
              --name ${{ env.DOCKER_IMAGE_NAME }} \
              -p 8000:8000 \
              --restart unless-stopped \
              ${{ env.DOCKER_IMAGE_NAME }}:${{ github.ref_name }}"