You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

该OCaml项目的GitHub Action发布工作流是否存在冗余步骤?

问题:发布阶段的重复构建步骤是否必要?

我编写GitHub Workflow时经常靠复制粘贴或修改模板,手上有个两年没维护的OCaml项目,Workflow文件99%来自初始化工具,细节不太敢改。这个Workflow分两个Job:第一个Job在各平台构建并上传产物;第二个Job本应只负责发布到GitHub Release,但却包含了和第一个Job几乎一样的耗时构建步骤,而且发布阶段已经会下载第一个Job生成的产物。想问这些重复构建步骤有没有存在的必要?

以下是原Workflow文件:

name: Release

on: 
  workflow_dispatch:
  release:
    types: [ published ]

jobs:
  build:
    name: Build and test
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
    steps:
      - uses: actions/checkout@v2

      - name: Fetch git tags
        run: git fetch --tags --force

      - name: Use Node.js 12.x
        uses: actions/setup-node@v1
        with:
          node-version: 12.x
          registry-url: "https://registry.npmjs.org"

      - name: Set macOS deployment target
        if: matrix.os == 'macos-latest'
        run: |
          echo "::set-env name=MACOSX_DEPLOYMENT_TARGET=10.9"

      - name: Cache esy dependencies
        uses: actions/cache@v1
        id: cache
        with:
          path: _export
          key: ${{ runner.OS }}-build-${{ hashFiles('esy.lock/index.json') }}
          restore-keys: |
            ${{ runner.OS }}-build-${{ env.cache-name }}-
            ${{ runner.OS }}-build-
            ${{ runner.OS }}-

      - name: Install esy
        run: npm install -g esy@latest

      - name: Import dependencies
        if: steps.cache.outputs.cache-hit == 'true'
        run: esy import-build _export/*

      - name: Install dependencies
        run: esy install

      - name: Build
        run: esy build --release

      - name: Substitute watermarks
        run: esy dune subst

      - name: Build subst changes
        run: esy dune build

      - name: Export dependencies
        run: esy export-dependencies

      - name: Get binary path
        id: get_binary_path
        shell: bash
        run: |
          # from https://stackoverflow.com/a/24848739/617787
          s=$(pwd); d=$(dirname $(esy x which reason-ls));
          while [ "${d#$s/}" == "${d}" ]
          do s=$(dirname $s);b="../${b}"; done; 
          BINARY_PATH=${b}${d#$s/}/reason-ls
          echo "BINARY_PATH: $BINARY_PATH"
          echo "##[set-output name=path;]$BINARY_PATH"

      - name: Upload artifacts for ${{ matrix.os }}
        uses: actions/upload-artifact@master
        with:
          name: ${{ matrix.os }}
          path: ${{ steps.get_binary_path.outputs.path }}


  publish:
    needs: build
    name: Publish
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Fetch git tags
        run: git fetch --tags --force

      - name: Use Node.js 12.x
        uses: actions/setup-node@v1
        with:
          node-version: 12.x

      - name: Cache esy dependencies
        uses: actions/cache@v1
        id: cache
        with:
          path: _export
          key: ${{ runner.OS }}-build-${{ hashFiles('esy.lock/index.json') }}
          restore-keys: |
            ${{ runner.OS }}-build-${{ env.cache-name }}-
            ${{ runner.OS }}-build-
            ${{ runner.OS }}-

      - name: Install esy
        run: npm install -g esy@latest

      - name: Import dependencies
        if: steps.cache.outputs.cache-hit == 'true'
        run: esy import-build _export/*

      - name: Install dependencies
        run: esy install

      - name: Build
        run: esy build --release

      - name: Substitute watermarks
        run: esy dune subst

      - name: Make NPM release skeleton
        run: node script/release-make-skeleton.js

      - name: Download linux artifacts
        uses: actions/download-artifact@master
        with:
          name: ubuntu-latest
          path: _release/platform-linux-x64

      - name: Download macOS artifacts
        uses: actions/download-artifact@master
        with:
          name: macos-latest
          path: _release/platform-darwin-x64


      - name: Create archives for Github release
        run: |
          cd _release/platform-darwin-x64
          zip -r ../../reason-ls-darwin-x64.zip .
          cd ../..

          cd _release/platform-linux-x64
          zip -r ../../reason-ls-linux-x64.zip .
          cd ../..


      - name: Upload reason-ls-darwin-x64.zip to Github release 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: reason-ls-darwin-x64.zip
          asset_name: reason-ls-darwin-x64.zip
          asset_content_type: application/gzip

      - name: Upload reason-ls-linux-x64.zip to Github release 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: reason-ls-linux-x64.zip
          asset_name: reason-ls-linux-x64.zip
          asset_content_type: application/gzip

      - name: Publish NPM package
        run: |
          npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
          npm config set scope "@{{ npm_username }}"
          npm config list
          npm publish --access public
        working-directory: ./_release
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

回答

这些重复构建步骤完全没有必要,可以安全删除,能大幅减少发布阶段的运行时间。具体分析如下:

  1. 冗余性明确
    build job已经在Ubuntu和macOS平台完成了完整的依赖安装、项目构建、产物上传流程,publish job通过actions/download-artifact已经拿到了最终的二进制产物,后续打包、发布只需要这些产物,不需要再次执行构建流程。publish job里的esy install、esy build --release、esy dune subst等步骤都是完全重复的操作,纯粹浪费资源。

  2. 需要保留的核心步骤
    只需要保留支撑node script/release-make-skeleton.js和后续发布流程的基础步骤:

    • actions/checkout@v2:需要获取项目中的script/release-make-skeleton.js脚本文件
    • Use Node.js 12.x:运行Node脚本需要对应的Node环境
    • Fetch git tags:如果release-make-skeleton.js需要读取git标签信息来生成版本号,这个步骤需要保留;如果不需要也可以删除
      其余所有esy相关的缓存、安装、构建步骤都可以直接删除。
  3. 优化后的publish job示例
    简化后的publish job步骤如下:

publish:
  needs: build
  name: Publish
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v2

    - name: Fetch git tags
      run: git fetch --tags --force

    - name: Use Node.js 12.x
      uses: actions/setup-node@v1
      with:
        node-version: 12.x

    - name: Make NPM release skeleton
      run: node script/release-make-skeleton.js

    - name: Download linux artifacts
      uses: actions/download-artifact@master
      with:
        name: ubuntu-latest
        path: _release/platform-linux-x64

    - name: Download macOS artifacts
      uses: actions/download-artifact@master
      with:
        name: macos-latest
        path: _release/platform-darwin-x64

    - name: Create archives for Github release
      run: |
        cd _release/platform-darwin-x64
        zip -r ../../reason-ls-darwin-x64.zip .
        cd ../..

        cd _release/platform-linux-x64
        zip -r ../../reason-ls-linux-x64.zip .
        cd ../..

    - name: Upload reason-ls-darwin-x64.zip to Github release 
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.create_release.outputs.upload_url }}
        asset_path: reason-ls-darwin-x64.zip
        asset_name: reason-ls-darwin-x64.zip
        asset_content_type: application/gzip

    - name: Upload reason-ls-linux-x64.zip to Github release 
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.create_release.outputs.upload_url }}
        asset_path: reason-ls-linux-x64.zip
        asset_name: reason-ls-linux-x64.zip
        asset_content_type: application/gzip

    - name: Publish NPM package
      run: |
        npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
        npm config set scope "@{{ npm_username }}"
        npm config list
        npm publish --access public
      working-directory: ./_release
      env:
        NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

内容的提问来源于stack exchange,提问作者Danielo515

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:25:56