Skip to content

完整 Workflow 示例

基础版本

适用于单平台构建的项目:

yaml
name: Build and Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: write
      attestations: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Attest Build Provenance
        uses: actions/attest-build-provenance@v2
        with:
          subject-path: 'dist/*'

      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          files: dist/*
          generate_release_notes: true

多平台构建版本

适用于需要在多个操作系统上构建的项目:

yaml
name: Multi-Platform Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            artifact_name: app-linux
          - os: windows-latest
            artifact_name: app-windows.exe
          - os: macos-latest
            artifact_name: app-macos

    runs-on: ${{ matrix.os }}
    permissions:
      id-token: write
      contents: write
      attestations: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Attest Build Provenance
        uses: actions/attest-build-provenance@v2
        with:
          subject-path: 'dist/${{ matrix.artifact_name }}'

      - name: Upload Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.artifact_name }}
          path: dist/${{ matrix.artifact_name }}

  release:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Download All Artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts

      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          files: artifacts/**/*
          generate_release_notes: true

Go 项目示例

yaml
name: Release Go Application

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    strategy:
      matrix:
        include:
          - goos: linux
            goarch: amd64
          - goos: windows
            goarch: amd64
          - goos: darwin
            goarch: amd64
          - goos: darwin
            goarch: arm64

    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: write
      attestations: write

    steps:
      - uses: actions/checkout@v4

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.22'

      - name: Build
        env:
          GOOS: ${{ matrix.goos }}
          GOARCH: ${{ matrix.goarch }}
        run: |
          output="myapp-${{ matrix.goos }}-${{ matrix.goarch }}"
          if [ "${{ matrix.goos }}" = "windows" ]; then
            output="${output}.exe"
          fi
          go build -o "dist/${output}" .

      - name: Attest
        uses: actions/attest-build-provenance@v2
        with:
          subject-path: 'dist/*'

      - name: Upload
        uses: actions/upload-artifact@v4
        with:
          name: myapp-${{ matrix.goos }}-${{ matrix.goarch }}
          path: dist/*

  release:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true

      - uses: softprops/action-gh-release@v2
        with:
          files: dist/*

Python 项目示例

yaml
name: Release Python Package

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: write
      attestations: write

    steps:
      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install Build Tools
        run: pip install build

      - name: Build Package
        run: python -m build

      - name: Attest
        uses: actions/attest-build-provenance@v2
        with:
          subject-path: 'dist/*'

      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          files: dist/*

PyInstaller 多平台可执行文件

使用 PyInstaller 构建跨平台桌面应用时,需要注意各平台的打包差异:

macOS 注意事项

  • macOS GUI 应用必须使用 --onedir 生成 .app
  • 使用 --onefile 只会生成裸二进制文件,下载后可能无法直接运行
  • 建议将产物打包为 .zip 以保留文件权限和目录结构
yaml
name: Build and Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            artifact_name: myapp-linux.zip
          - os: windows-latest
            artifact_name: myapp-windows.exe
          - os: macos-latest
            artifact_name: myapp-macos.zip

    runs-on: ${{ matrix.os }}
    permissions:
      id-token: write
      contents: write
      attestations: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install Dependencies
        run: pip install pyinstaller

      # Linux: 单文件可执行,打包为 zip 保留权限
      - name: Build Executable (Linux)
        if: runner.os == 'Linux'
        run: |
          pyinstaller --onefile --name "myapp-linux" app.py
          mkdir -p dist_final
          chmod +x dist/myapp-linux
          cd dist && zip ../dist_final/myapp-linux.zip myapp-linux

      # macOS: 必须用 --onedir 生成 .app 包,再打包为 zip
      - name: Build Executable (macOS)
        if: runner.os == 'macOS'
        run: |
          pyinstaller --onedir --windowed --name "myapp" app.py
          mkdir -p dist_final
          cd dist && zip -r ../dist_final/myapp-macos.zip myapp.app

      # Windows: 直接生成 .exe
      - name: Build Executable (Windows)
        if: runner.os == 'Windows'
        run: |
          pyinstaller --onefile --windowed --name "myapp-windows" app.py
          mkdir dist_final
          copy dist\myapp-windows.exe dist_final\

      - name: Attest Build Provenance
        uses: actions/attest-build-provenance@v2
        with:
          subject-path: 'dist_final/*'

      - name: Upload Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.artifact_name }}
          path: dist_final/*

  release:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Download All Artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          files: artifacts/*
          generate_release_notes: true

用户使用说明

平台下载文件使用方式
macOSmyapp-macos.zip解压后双击 myapp.app
Linuxmyapp-linux.zip解压后运行 ./myapp-linux
Windowsmyapp-windows.exe直接双击运行

Electron 应用示例

yaml
name: Release Electron App

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]

    runs-on: ${{ matrix.os }}
    permissions:
      id-token: write
      contents: write
      attestations: write

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Dependencies
        run: npm ci

      - name: Build Electron App
        run: npm run electron:build

      - name: Attest
        uses: actions/attest-build-provenance@v2
        with:
          subject-path: |
            dist/*.exe
            dist/*.dmg
            dist/*.AppImage

      - name: Upload Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: electron-${{ matrix.os }}
          path: |
            dist/*.exe
            dist/*.dmg
            dist/*.AppImage

  release:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true

      - uses: softprops/action-gh-release@v2
        with:
          files: dist/*

使用说明

  1. 选择适合你项目的模板
  2. 复制到 .github/workflows/release.yml
  3. 根据项目需要修改构建步骤
  4. 推送代码并创建 tag 触发构建

软件安全标准文档