diff --git a/.github/workflows/ci-macos-linux-windows-pixi.yml b/.github/workflows/ci-macos-linux-windows-pixi.yml index 3dc4b7965e7..3e6efe6dc68 100644 --- a/.github/workflows/ci-macos-linux-windows-pixi.yml +++ b/.github/workflows/ci-macos-linux-windows-pixi.yml @@ -1,44 +1,221 @@ name: CI - MacOS/Linux/Windows via Pixi on: - push: - pull_request: - workflow_dispatch: + workflow_call: + inputs: + sofa-branch-name: + type: string + required: true + sofa-commit-sha: + type: string + required: true + pr-owner-url: + type: string + required: false + pr-branch-name: + type: string + required: false + pr-commit-sha: + type: string + required: false + preset: + type: string + required: true + python-version: + type: string + required: true + ci-depends-on: + type: string + required: false + with-all-tests: + type: boolean + required: false + default: false + force-full-build: + type: boolean + required: false + default: false + generate-binaries: + type: boolean + required: false + default: false + external-plugins: + type: string + required: false + additionnal-cmake-flags: + type: string + required: false + builder-os: + type: string + required: true + default: '["ubuntu-latest", "macos-latest", "macos-15-intel", "windows-latest"]' + dash-info: + type: string + required: false + default: 'NONE' + description: 'Json scructure with three parameters {"COMMIT_HASH":"fullhsashofthecommit", }' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: - sofa-pixi: - name: ${{ matrix.os }} - Env ${{ matrix.environment }} ${{ matrix.build_type }} ${{ matrix.compiler }} - runs-on: ${{ matrix.os }} + display-inputs: + runs-on: ubuntu-latest + steps: + - name: Display + shell: bash + run: | + echo "Build and test launched with following parameters:" + echo "sofa-branch-name : ${{ inputs.sofa-branch-name }}" + echo "sofa-commit-sha : ${{ inputs.sofa-commit-sha }}" + echo "pr-owner-url : ${{ inputs.pr-owner-url }}" + echo "pr-branch-name : ${{ inputs.pr-branch-name }}" + echo "pr-commit-sha : ${{ inputs.pr-commit-sha }}" + echo "preset : ${{ inputs.preset }}" + echo "python-version : ${{ inputs.python-version }}" + echo "ci-depends-on : ${{ inputs.ci-depends-on }}" + echo "with-all-tests : ${{ inputs.with-all-tests }}" + echo "force-full-build : ${{ inputs.force-full-build }}" + echo "generate-binaries : ${{ inputs.generate-binaries }}" + echo "external-plugins : ${{ inputs.external-plugins }}" + echo "additionnal-cmake-flags : ${{ inputs.additionnal-cmake-flags }}" + echo "builder-os : ${{ inputs.builder-os }}" + sofa-pixi: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, macos-15-intel, windows-latest] - environment: [supported-plugins] + os: ${{ fromJson(inputs.builder-os) }} build_type: [Release] + runs-on: ${{ matrix.os }} + name: ${{ matrix.os }} - Env ${{ inputs.preset }} ${{ matrix.build_type }} ${{ matrix.compiler }} + steps: - uses: actions/checkout@v4 + with: + ref: ${{ inputs.sofa-branch-name }} + path: sofa + + - run: git config --global user.email "<>" + - run: git config --global user.name "SOFA Bot" - uses: prefix-dev/setup-pixi@v0.8.10 with: cache: false - environments: ${{ matrix.environment }} + manifest-path: sofa/pixi.toml + environments: ${{ inputs.preset }} + + - name: Setup SOFA and clone CI + shell: bash -el {0} + run: | + export WORKSPACE=$GITHUB_WORKSPACE + echo "WORKSPACE=$WORKSPACE" >> $GITHUB_ENV + + export SRC_DIR=$GITHUB_WORKSPACE/sofa + echo "SRC_DIR=$SRC_DIR" >> $GITHUB_ENV + + cd $SRC_DIR + if [ ! -z "${{ inputs.pr-owner-url }}" ]; then + echo "This is a PR, merging branch ${{ inputs.pr-branch-name }} from remote ${{ inputs.pr-owner-url }} into origin branch ${{ inputs.sofa-branch-name }}" + git remote add pr ${{ inputs.pr-owner-url }} + git fetch pr + + if [ "${{ inputs.pr-commit-sha }}" == "HEAD" ]; then + git merge ${{ inputs.pr-branch-name }} + else + git merge ${{ inputs.pr-commit-sha }} + fi + else + echo "This is not a PR: checking out sha ${{ inputs.sofa-commit-sha }} from branch ${{ inputs.sofa-branch-name }}" + git checkout ${{ inputs.sofa-commit-sha }} + fi + + cd $WORKSPACE + + ## Clone CI and use ci-depends-on structure + ci_branch=${{ inputs.sofa-branch-name }} + ci_repo_url="https://www.github.com/sofa-framework/ci" + + + # check if ci has a ci-depends-on + ci_ci_depends_on=$(echo "${{ inputs.ci-depends-on }}" | jq .ci) + if [ -n "${{ inputs.ci-depends-on }}" ] && [ "$ci_ci_depends_on" != "null" ]; then + echo "ci-depends-on for ci repository detected." + ci_repo_url=$(echo "${{ inputs.ci-depends-on }}" | jq .ci.repo_url) + ci_branch=$(echo "${{ inputs.ci-depends-on }}" | jq .ci.branch_name) + fi + echo "CI_BRANCH=$ci_branch" >> $GITHUB_ENV + + + echo "Cloning CI from remote ${ci_repo_url}, selecting branch ${ci_branch}" + + CI_DIR=$WORKSPACE/ci + echo "CI_DIR=$CI_DIR" >> $GITHUB_ENV + + git clone -b ${ci_branch//\"} --single-branch ${ci_repo_url//\"} + + cd $WORKSPACE + + ## Setup build folder + mkdir $WORKSPACE/build + + SOFA_BUILD_DIR=$WORKSPACE/build + echo "SOFA_BUILD_DIR=$SOFA_BUILD_DIR" >> $GITHUB_ENV + + if [ -n "${{ inputs.external-plugins }}" ]; then + echo "Setting up external plugins." + for plugin in ${{ inputs.external-plugins }}; do + plugin_base=${plugin%@*} + plugin_branch=${plugin##*@} + plugin_repo=$(basename "$plugin_base") + + echo "Adding line 'sofa_add_external(plugin $plugin_repo GIT_REF $plugin_branch GIT_REPOSITORY $plugin_base ON)' to file ${SRC_DIR}/applications/CMakeLists.txt" + echo "sofa_add_external(plugin $plugin_repo GIT_REF $plugin_branch GIT_REPOSITORY $plugin_base ON)" >> "${SRC_DIR}/applications/CMakeLists.txt" + done + fi + + - name: Build SOFA [MacOS/Linux/Windows] shell: bash -el {0} env: SOFA_BUILD_TYPE: ${{ matrix.build_type }} run: | - pixi run -e ${{ matrix.environment }} build + cd ${SRC_DIR} + + + ## Deal with ci-depends-on + # Loop over each key-value pair in the JSON avoiding ci repository if inside + CMAKE_OPTIONS="${{inputs.additionnal-cmake-flags}}" + for key in $(echo "${{ inputs.ci-depends-on }}" | jq -r 'keys[]' | grep -v '^ci$'); do + + repo_url=$(echo "${{ inputs.ci-depends-on }}" | jq -r ".\"$key\".repo_url") + branch_name=$(echo "${{ inputs.ci-depends-on }}" | jq -r ".\"$key\".branch_name") + + # Format the CMake flags for this key and append to the result + fixed_name=$(echo "$key" | awk '{gsub(/\./, "_"); print toupper($0)}') + flag_repository="-D${fixed_name}_GIT_REPOSITORY=\"$repo_url\"" + flag_tag="-D${fixed_name}_GIT_TAG=\"$branch_name\"" + + # Append both flags to the result string with a space + CMAKE_OPTIONS="$CMAKE_OPTIONS $flag_repository $flag_tag " + done + + if [[ ! -n "$CMAKE_OPTIONS" ]]; then + echo "No ci-depends-on detected." + else + echo "Adding the following cmake variable : $CMAKE_OPTIONS" + fi + + ## Run build step + pixi run -e ${{ inputs.preset }} configure $CMAKE_OPTIONS + pixi run -e ${{ inputs.preset }} build - name: Testing - Run SOFA in batch mode [MacOS/Linux/Windows] shell: bash -el {0} env: SOFA_BUILD_TYPE: ${{ matrix.build_type }} run: | - pixi run -e ${{ matrix.environment }} runSofa -g batch + pixi run -e ${{ inputs.preset }} runSofa -g batch diff --git a/.github/workflows/trigger-build-and-tests.yml b/.github/workflows/trigger-build-and-tests.yml index d25724995eb..b21c6ff65c6 100644 --- a/.github/workflows/trigger-build-and-tests.yml +++ b/.github/workflows/trigger-build-and-tests.yml @@ -40,10 +40,14 @@ on: type: choice description: On which OS run the binaries generation options: - - '["sh-ubuntu_gcc_release"]' - - '["sh-macos_clang_release"]' - - '["sh-ubuntu_gcc_release","sh-macos_clang_release"]' - default: '["sh-ubuntu_gcc_release","sh-macos_clang_release"]' + - '["ubuntu"]' + - '["macos"]' + - '["windows"]' + - '["ubuntu","macos"]' + - '["ubuntu","windows"]' + - '["macos","windows"]' + - '["ubuntu","macos","windows"]' + default: '["ubuntu","macos","windows"]' # PR-related build (open, labels, push) pull_request: @@ -63,7 +67,7 @@ jobs: # Filter build handling : push in master, commits in PR, comments in PR and dispatch filter_build: runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'sofa-framework' }} + if: ${{ github.repository_owner == 'bakpaul' }} outputs: SOFA_BRANCH_NAME: ${{ steps.export-vars.outputs.SOFA_BRANCH_NAME }} SOFA_COMMIT_SHA: ${{ steps.export-vars.outputs.SOFA_COMMIT_SHA }} @@ -78,7 +82,8 @@ jobs: PR_OWNER_URL: ${{ steps.export-vars.outputs.PR_OWNER_URL }} PR_BRANCH_NAME: ${{ steps.export-vars.outputs.PR_BRANCH_NAME }} PR_COMMIT_SHA: ${{ steps.export-vars.outputs.PR_COMMIT_SHA }} - BUILDER_OS: ${{ steps.export-vars.outputs.BUILDER_OS }} + SH_BUILDER_OS: ${{ steps.export-vars.outputs.SH_BUILDER_OS }} + PIXI_BUILDER_OS: ${{ steps.export-vars.outputs.PIXI_BUILDER_OS }} steps: - name: Default values of environment variables @@ -96,7 +101,8 @@ jobs: echo "PR_OWNER_URL=" >> $GITHUB_ENV # PR_OWNER_URL: "" echo "PR_BRANCH_NAME=" >> $GITHUB_ENV # PR_BRANCH_NAME: "" echo "PR_COMMIT_SHA=HEAD" >> $GITHUB_ENV # PR_COMMIT_SHA: "HEAD" - echo 'BUILDER_OS=["sh-ubuntu_gcc_release"]' >> $GITHUB_ENV # BUILDER_OS: ["sh-ubuntu_gcc_release"] + echo 'SH_BUILDER_OS=["sh-ubuntu_gcc_release","sh-macos_clang_release"]' >> $GITHUB_ENV # BUILDER_OS: ubuntu and maco + echo 'PIXI_BUILDER_OS=["windows-latest"]' >> $GITHUB_ENV # BUILDER_OS: windows - name: Run on dispatch if: ${{ github.event_name == 'workflow_dispatch' }} @@ -129,11 +135,26 @@ jobs: echo "PRESET=${{ github.event.inputs.preset }}" >> $GITHUB_ENV echo "PYTHON_VERSION=${{ github.event.inputs.python_version }}" >> $GITHUB_ENV echo "GENERATE_BINARIES=true" >> $GITHUB_ENV - echo 'BUILDER_OS=${{ github.event.inputs.builder-os }}' >> $GITHUB_ENV echo "FORCE_FULL_BUILD=true" >> $GITHUB_ENV echo "EXTERNAL_PLUGINS=${{ inputs.external-plugins }}" >> $GITHUB_ENV echo "ADDITIONNAL_CMAKE_FLAGS=${{ inputs.additionnal-cmake-flags }}" >> $GITHUB_ENV + if [[ "${{ inputs.builder-os}}" == *"windows"* ]]; then + echo 'PIXI_BUILDER_OS=["windows-latest"]' >> $GITHUB_ENV + else + echo 'PIXI_BUILDER_OS=[]' >> $GITHUB_ENV + fi + + if [[ "${{ inputs.builder-os}}" == *"ubuntu"* && "${{ inputs.builder-os}}" == *"macos"*]]; then + echo 'SH_BUILDER_OS=["sh-ubuntu_gcc_release","sh-macos_clang_release"]' >> $GITHUB_ENV + elif [[ "${{ inputs.builder-os}}" == *"ubuntu"* ]]; then + echo 'SH_BUILDER_OS=["sh-ubuntu_gcc_release"]' >> $GITHUB_ENV + elif [[ "${{ inputs.builder-os}}" == *"macos"* ]]; then + echo 'SH_BUILDER_OS=["sh-macos_clang_release"]' >> $GITHUB_ENV + else + echo 'SH_BUILDER_OS=[]' >> $GITHUB_ENV + fi + - name: Set up python uses: actions/setup-python@v5 @@ -159,7 +180,9 @@ jobs: echo "SOFA_COMMIT_SHA=${{ github.sha }}">> $GITHUB_ENV echo "WITH_ALL_TESTS=true" >> $GITHUB_ENV echo "FORCE_FULL_BUILD=true" >> $GITHUB_ENV - echo 'BUILDER_OS=["sh-ubuntu_gcc_release","sh-ubuntu_clang_release","sh-ubuntu_clang_debug","sh-fedora_clang_release","sh-macos_clang_release"]' >> $GITHUB_ENV + echo 'SH_BUILDER_OS=["sh-ubuntu_gcc_release","sh-ubuntu_clang_release","sh-ubuntu_clang_debug","sh-fedora_clang_release","sh-macos_clang_release"]' >> $GITHUB_ENV + echo 'PIXI_BUILDER_OS=["ubuntu-latest", "macos-latest", "macos-15-intel", "windows-latest"]' >> $GITHUB_ENV + - name: Run when PR is opened or a commit is pushed in a PR if: ${{ github.event_name == 'pull_request' }} @@ -179,7 +202,7 @@ jobs: id: export-vars run: | # Validate branch format (e.g., v25.06) - if [ [ ! "$SOFA_BRANCH_NAME" =~ ^v[0-9]{2}\.[0-9]{2}$ ] && [ "$SOFA_BRANCH_NAME" != "master" ] ]; then + if [[ ! "$SOFA_BRANCH_NAME" =~ ^v[0-9]{2}\.[0-9]{2}$ && "$SOFA_BRANCH_NAME" != "master" ]]; then echo "Error: Invalid branch name format: $SOFA_BRANCH_NAME." echo "Branch name should be either master or any release branch (e.g., v25.06)" exit 1 @@ -198,7 +221,8 @@ jobs: echo "PR_OWNER_URL=${PR_OWNER_URL}" >> $GITHUB_OUTPUT echo "PR_BRANCH_NAME=${PR_BRANCH_NAME}" >> $GITHUB_OUTPUT echo "PR_COMMIT_SHA=${PR_COMMIT_SHA}" >> $GITHUB_OUTPUT - echo "BUILDER_OS=${BUILDER_OS}" >> $GITHUB_OUTPUT + echo "SH_BUILDER_OS=${SH_BUILDER_OS}" >> $GITHUB_OUTPUT + echo "PIXI_BUILDER_OS=${PIXI_BUILDER_OS}" >> $GITHUB_OUTPUT # =============================================================== @@ -207,8 +231,8 @@ jobs: # Trigger the build and sharing all parameters from filter_build > outputs build-on: needs: filter_build - if: ${{ github.repository_owner == 'sofa-framework' }} - uses: sofa-framework/sofa/.github/workflows/build-and-test.yml@master + if: ${{ github.repository_owner == 'sofa-framework' && needs.filter_build.outputs.SH_BUILDER_OS != '[]' }} + uses: bakpaul/sofa/.github/workflows/build-and-test.yml@master with: sofa-branch-name: ${{ needs.filter_build.outputs.SOFA_BRANCH_NAME }} sofa-commit-sha: ${{ needs.filter_build.outputs.SOFA_COMMIT_SHA }} @@ -223,4 +247,26 @@ jobs: pr-owner-url: ${{ needs.filter_build.outputs.PR_OWNER_URL }} pr-branch-name: ${{ needs.filter_build.outputs.PR_BRANCH_NAME }} pr-commit-sha: ${{ needs.filter_build.outputs.PR_COMMIT_SHA }} - builder-os: ${{ needs.filter_build.outputs.BUILDER_OS }} + builder-os: ${{ needs.filter_build.outputs.SH_BUILDER_OS }} + + # Trigger the build and sharing all parameters from filter_build > outputs + pixi-ci: + needs: filter_build + if: ${{ github.repository_owner == 'bakpaul' && needs.filter_build.outputs.PIXI_BUILDER_OS != '[]' }} + uses: bakpaul/sofa/.github/workflows/ci-macos-linux-windows-pixi.yml@master + with: + sofa-branch-name: ${{ needs.filter_build.outputs.SOFA_BRANCH_NAME }} + sofa-commit-sha: ${{ needs.filter_build.outputs.SOFA_COMMIT_SHA }} + preset: ${{ needs.filter_build.outputs.PRESET }} + python-version: ${{ needs.filter_build.outputs.PYTHON_VERSION }} + ci-depends-on: ${{ needs.filter_build.outputs.CI_DEPENDS_ON }} + with-all-tests: ${{ needs.filter_build.outputs.WITH_ALL_TESTS == 'true'}} + force-full-build: ${{ needs.filter_build.outputs.FORCE_FULL_BUILD == 'true'}} + external-plugins: ${{ needs.filter_build.outputs.EXTERNAL_PLUGINS }} + additionnal-cmake-flags: ${{ needs.filter_build.outputs.ADDITIONNAL_CMAKE_FLAGS }} + generate-binaries: ${{ needs.filter_build.outputs.GENERATE_BINARIES == 'true'}} + pr-owner-url: ${{ needs.filter_build.outputs.PR_OWNER_URL }} + pr-branch-name: ${{ needs.filter_build.outputs.PR_BRANCH_NAME }} + pr-commit-sha: ${{ needs.filter_build.outputs.PR_COMMIT_SHA }} + builder-os: ${{ needs.filter_build.outputs.PIXI_BUILDER_OS }} +