UniLabOS Conda Build #889
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: UniLabOS Conda Build | |
| on: | |
| # 在 Multi-Platform Conda Build 成功上传 msgs 后自动触发 | |
| workflow_run: | |
| workflows: ["Multi-Platform Conda Build"] | |
| types: [completed] | |
| # 手动触发 | |
| workflow_dispatch: | |
| inputs: | |
| platforms: | |
| description: '选择构建平台 (逗号分隔): linux-64, osx-64, osx-arm64, win-64' | |
| required: false | |
| default: 'linux-64' | |
| build_full: | |
| description: '是否构建 unilabos-full 完整包 (默认只构建 unilabos 基础包)' | |
| required: false | |
| default: false | |
| type: boolean | |
| upload_to_anaconda: | |
| description: '是否上传到Anaconda.org' | |
| required: false | |
| default: false | |
| type: boolean | |
| skip_ci_check: | |
| description: '跳过等待 CI Check (手动触发时可选)' | |
| required: false | |
| default: false | |
| type: boolean | |
| jobs: | |
| # 等待上游 msgs 构建完成的 job (仅用于 workflow_run 触发) | |
| wait-for-upstream: | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_run' | |
| outputs: | |
| should_continue: ${{ steps.check.outputs.should_continue }} | |
| steps: | |
| - name: Check upstream workflow status | |
| id: check | |
| run: | | |
| if [[ "${{ github.event.workflow_run.conclusion }}" == "success" && ( "${{ github.event.workflow_run.event }}" == "release" || "${{ github.event.workflow_run.event }}" == "push" ) ]]; then | |
| echo "should_continue=true" >> $GITHUB_OUTPUT | |
| echo "Multi-Platform Conda Build passed for release/tag, proceeding with UniLabOS build" | |
| else | |
| echo "should_continue=false" >> $GITHUB_OUTPUT | |
| echo "Upstream workflow is not a successful release/tag build (status: ${{ github.event.workflow_run.conclusion }}, event: ${{ github.event.workflow_run.event }}), skipping build" | |
| fi | |
| build: | |
| needs: [wait-for-upstream] | |
| # 运行条件:workflow_run 触发且上游成功,或者手动触发 | |
| if: | | |
| always() && | |
| (needs.wait-for-upstream.result == 'skipped' || needs.wait-for-upstream.outputs.should_continue == 'true') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| platform: linux-64 | |
| - os: macos-15-intel # Intel x86_64 | |
| platform: osx-64 | |
| - os: macos-latest # ARM64 | |
| platform: osx-arm64 | |
| - os: windows-latest | |
| platform: win-64 | |
| runs-on: ${{ matrix.os }} | |
| defaults: | |
| run: | |
| shell: bash -l {0} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| # 如果是 workflow_run 触发,使用上游 conda 包构建的 commit | |
| ref: ${{ github.event.workflow_run.head_sha || github.ref }} | |
| fetch-depth: 0 | |
| - name: Check if platform should be built | |
| id: should_build | |
| run: | | |
| if [[ "${{ github.event_name }}" != "workflow_dispatch" ]]; then | |
| echo "should_build=true" >> $GITHUB_OUTPUT | |
| elif [[ -z "${{ github.event.inputs.platforms }}" ]]; then | |
| echo "should_build=true" >> $GITHUB_OUTPUT | |
| elif [[ "${{ github.event.inputs.platforms }}" == *"${{ matrix.platform }}"* ]]; then | |
| echo "should_build=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "should_build=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Setup Miniforge | |
| if: steps.should_build.outputs.should_build == 'true' | |
| uses: conda-incubator/setup-miniconda@v4 | |
| with: | |
| miniforge-version: latest | |
| use-mamba: true | |
| python-version: '3.11.14' | |
| channels: conda-forge,robostack-staging,uni-lab | |
| channel-priority: strict | |
| activate-environment: build-env | |
| auto-update-conda: false | |
| show-channel-urls: true | |
| - name: Install rattler-build and anaconda-client | |
| if: steps.should_build.outputs.should_build == 'true' | |
| run: | | |
| if [[ "$RUNNER_OS" == "Windows" ]]; then | |
| cmd //D //S //C '%CONDA%\condabin\mamba.bat install -n build-env --override-channels -c conda-forge rattler-build anaconda-client -y' | |
| else | |
| mamba install -n build-env --override-channels -c conda-forge rattler-build anaconda-client -y | |
| fi | |
| echo "CONDA_NO_PLUGINS=true" >> "$GITHUB_ENV" | |
| echo "PYTHONUTF8=1" >> "$GITHUB_ENV" | |
| echo "PYTHONIOENCODING=utf-8" >> "$GITHUB_ENV" | |
| - name: Show environment info | |
| if: steps.should_build.outputs.should_build == 'true' | |
| run: | | |
| conda info | |
| conda list -n build-env | grep -E "(rattler-build|anaconda-client)" | |
| conda run -n build-env rattler-build --version | |
| conda run -n build-env anaconda --version | |
| echo "Platform: ${{ matrix.platform }}" | |
| echo "OS: ${{ matrix.os }}" | |
| echo "Build full package: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.build_full == 'true' }}" | |
| echo "Building packages:" | |
| echo " - unilabos-env (environment dependencies)" | |
| echo " - unilabos (with pip package)" | |
| if [[ "${{ github.event_name == 'workflow_dispatch' && github.event.inputs.build_full == 'true' }}" == "true" ]]; then | |
| echo " - unilabos-full (complete package)" | |
| fi | |
| - name: Build unilabos-env (conda environment only, noarch) | |
| if: steps.should_build.outputs.should_build == 'true' | |
| run: | | |
| echo "Building unilabos-env (conda environment dependencies)..." | |
| conda run -n build-env rattler-build build -r .conda/environment/recipe.yaml --target-platform ${{ matrix.platform }} -c uni-lab -c robostack-staging -c conda-forge | |
| - name: Upload unilabos-env to Anaconda.org (if enabled) | |
| if: | | |
| steps.should_build.outputs.should_build == 'true' && | |
| ( | |
| github.event_name == 'workflow_run' || | |
| github.event.inputs.upload_to_anaconda == 'true' | |
| ) | |
| run: | | |
| echo "Uploading unilabos-env to uni-lab organization..." | |
| for package in $(find ./output -name "unilabos-env*.conda"); do | |
| conda run -n build-env anaconda -t ${{ secrets.ANACONDA_API_TOKEN }} upload --user uni-lab --force "$package" | |
| done | |
| - name: Build unilabos (with pip package) | |
| if: steps.should_build.outputs.should_build == 'true' | |
| run: | | |
| echo "Building unilabos package..." | |
| # 如果已上传到 Anaconda,从 uni-lab channel 获取 unilabos-env;否则从本地 output 获取 | |
| conda run -n build-env rattler-build build -r .conda/base/recipe.yaml --target-platform ${{ matrix.platform }} -c uni-lab -c robostack-staging -c conda-forge --channel ./output | |
| - name: Upload unilabos to Anaconda.org (if enabled) | |
| if: | | |
| steps.should_build.outputs.should_build == 'true' && | |
| ( | |
| github.event_name == 'workflow_run' || | |
| github.event.inputs.upload_to_anaconda == 'true' | |
| ) | |
| run: | | |
| echo "Uploading unilabos to uni-lab organization..." | |
| for package in $(find ./output -name "unilabos-0*.conda" -o -name "unilabos-[0-9]*.conda"); do | |
| conda run -n build-env anaconda -t ${{ secrets.ANACONDA_API_TOKEN }} upload --user uni-lab --force "$package" | |
| done | |
| - name: Build unilabos-full - Only when explicitly requested | |
| if: | | |
| steps.should_build.outputs.should_build == 'true' && | |
| github.event_name == 'workflow_dispatch' && | |
| github.event.inputs.build_full == 'true' | |
| run: | | |
| echo "Building unilabos-full package on ${{ matrix.platform }}..." | |
| conda run -n build-env rattler-build build -r .conda/full/recipe.yaml --target-platform ${{ matrix.platform }} -c uni-lab -c robostack-staging -c conda-forge --channel ./output | |
| - name: Upload unilabos-full to Anaconda.org (if enabled) | |
| if: | | |
| steps.should_build.outputs.should_build == 'true' && | |
| github.event_name == 'workflow_dispatch' && | |
| github.event.inputs.build_full == 'true' && | |
| github.event.inputs.upload_to_anaconda == 'true' | |
| run: | | |
| echo "Uploading unilabos-full to uni-lab organization..." | |
| for package in $(find ./output -name "unilabos-full*.conda"); do | |
| conda run -n build-env anaconda -t ${{ secrets.ANACONDA_API_TOKEN }} upload --user uni-lab --force "$package" | |
| done | |
| - name: List built packages | |
| if: steps.should_build.outputs.should_build == 'true' | |
| run: | | |
| echo "Built packages in output directory:" | |
| find ./output -name "*.conda" | head -10 | |
| ls -la ./output/${{ matrix.platform }}/ || echo "${{ matrix.platform }} directory not found" | |
| ls -la ./output/noarch/ || echo "noarch directory not found" | |
| echo "Output directory structure:" | |
| find ./output -type f -name "*.conda" | |
| - name: Prepare artifacts for upload | |
| if: steps.should_build.outputs.should_build == 'true' | |
| run: | | |
| mkdir -p conda-packages-temp | |
| find ./output -name "*.conda" -exec cp {} conda-packages-temp/ \; | |
| echo "Copied files to temp directory:" | |
| ls -la conda-packages-temp/ | |
| - name: Upload conda package artifacts | |
| if: steps.should_build.outputs.should_build == 'true' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: conda-package-unilabos-${{ matrix.platform }} | |
| path: conda-packages-temp | |
| if-no-files-found: warn | |
| retention-days: 30 |