You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2023/10/13 02:55:14 UTC
[incubator-opendal] branch main updated: refactor: Introduce OpenDAL Workflow Planner (#3258)
This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 147753d80 refactor: Introduce OpenDAL Workflow Planner (#3258)
147753d80 is described below
commit 147753d80a15661711fc796c25928a31be1a427b
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Fri Oct 13 10:55:07 2023 +0800
refactor: Introduce OpenDAL Workflow Planner (#3258)
* Try workflow call
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Add s3 as ignore example
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Remove concurrency
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Use output file
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Let's go
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* wrap
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix typo
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* test
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Polish naming
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* polish naming
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Can we use / ?
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Try
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix build
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* polish matrix
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix not found
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix path
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* FIx path
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* try
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix typo
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* toJson
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix typo
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* polish naming
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* FIx build
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Auto detect task
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* better
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Polish fs
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Add s3
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Make json pretty
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Make sure secrets
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Try passing
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Use from json
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Fix
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Remove migrated tests
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* remove unused functions
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Work under push event
Signed-off-by: Xuanwo <gi...@xuanwo.io>
---------
Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
.github/actions/setup/action.yaml | 20 +++---
.github/actions/test-core/action.yaml | 51 ++++++++++++++
.github/services/fs/local-fs/action.yml | 28 ++++++++
.github/services/s3/aws-s3/action.yml | 39 +++++++++++
.github/workflows/core_test.yml | 93 +++++++++++++++++++++++++
.github/workflows/service_test_fs.yml | 57 ---------------
.github/workflows/service_test_s3.yml | 22 ------
.github/workflows/test_planner.yml | 94 +++++++++++++++++++++++++
scripts/workflow_planner.py | 120 ++++++++++++++++++++++++++++++++
9 files changed, 436 insertions(+), 88 deletions(-)
diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml
index 5c5dc5dc8..2adc5d67a 100644
--- a/.github/actions/setup/action.yaml
+++ b/.github/actions/setup/action.yaml
@@ -49,24 +49,26 @@ runs:
shell: bash
run: sudo apt-get install libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev
- - name: Setup protoc on linux
- if: inputs.need-protoc == 'true' && runner.os == 'Linux'
- shell: bash
- run: sudo apt install -y protobuf-compiler
+ - name: Setup Protoc
+ if: inputs.need-protoc == 'true'
+ uses: arduino/setup-protoc@v2
+ with:
+ version: "23.4"
- name: Cache nextest on linux
id: cache-nextest
uses: actions/cache@v3
- if: inputs.need-nextest == 'true' && runner.os == 'Linux'
+ if: inputs.need-nextest == 'true'
with:
- path: ~/.cargo/bin/cargo-nextest
- # TODO: remove the runner.os while bumping version
- key: r0-${{runner.os}}-nextest-0.9.53
+ path: |
+ ~/.cargo/bin/cargo-nextest
+ ~/.cargo/bin/cargo-nextest.exe
+ key: r0-${{runner.os}}-nextest-0.9.59
- name: Build nextest if not cached
if: steps.cache-nextest.outputs.cache-hit != 'true' && inputs.need-nextest == 'true'
shell: bash
- run: cargo install cargo-nextest@0.9.53 --locked
+ run: cargo install cargo-nextest@0.9.59 --locked
- name: Setup rust on linux
if: runner.os == 'Linux' && inputs.need-rocksdb == 'true'
diff --git a/.github/actions/test-core/action.yaml b/.github/actions/test-core/action.yaml
new file mode 100644
index 000000000..da5759fe1
--- /dev/null
+++ b/.github/actions/test-core/action.yaml
@@ -0,0 +1,51 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Test Core
+description: 'Test Core with given setup and service'
+inputs:
+ setup:
+ description: "The setup action for test"
+ service:
+ description: "The service to test"
+ secrets:
+ description: "The secrets for test"
+ default: "{}"
+
+runs:
+ using: "composite"
+ steps:
+ - name: Setup
+ shell: bash
+ run: |
+ mkdir -p ./dynamic_test_core &&
+ cat <<EOF >./dynamic_test_core/action.yml
+ runs:
+ using: composite
+ steps:
+ - name: Setup Test Core
+ uses: ./.github/services/${{ inputs.service }}/${{ inputs.setup }}
+ with:
+ secrets: ${{ toJson(inputs.secrets) }}
+ - name: Run Test Core
+ shell: bash
+ working-directory: core
+ run: cargo nextest run services_${{ inputs.service }} --archive-file=./core-test.tar.zst
+ EOF
+ - name: Run
+ id: run
+ uses: ./dynamic_test_core
diff --git a/.github/services/fs/local-fs/action.yml b/.github/services/fs/local-fs/action.yml
new file mode 100644
index 000000000..4175de1eb
--- /dev/null
+++ b/.github/services/fs/local-fs/action.yml
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: local_fs
+description: "Setup local fs"
+
+runs:
+ using: "composite"
+ steps:
+ - name: Setup
+ shell: bash
+ run: |
+ echo "OPENDAL_FS_TEST=on" >> $GITHUB_ENV
+ echo "OPENDAL_FS_ROOT=${{ runner.temp }}/" >> $GITHUB_ENV
diff --git a/.github/services/s3/aws-s3/action.yml b/.github/services/s3/aws-s3/action.yml
new file mode 100644
index 000000000..7591937d5
--- /dev/null
+++ b/.github/services/s3/aws-s3/action.yml
@@ -0,0 +1,39 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: aws_s3
+description: "Setup AWS S3"
+
+inputs:
+ secrets:
+ description: "The secrets for test"
+ default: "{}"
+
+# TODO: we should migrate to 1password instead.
+runs:
+ using: "composite"
+ steps:
+ - name: Setup
+ shell: bash
+ run: |
+ echo "OPENDAL_S3_TEST=${{ fromJson(inputs.secrets).OPENDAL_S3_TEST }}" >> $GITHUB_ENV
+ echo "OPENDAL_S3_ROOT=${{ fromJson(inputs.secrets).OPENDAL_S3_ROOT }}" >> $GITHUB_ENV
+ echo "OPENDAL_S3_BUCKET=${{ fromJson(inputs.secrets).OPENDAL_S3_BUCKET }}" >> $GITHUB_ENV
+ echo "OPENDAL_S3_ENDPOINT=${{ fromJson(inputs.secrets).OPENDAL_S3_ENDPOINT }}" >> $GITHUB_ENV
+ echo "OPENDAL_S3_ACCESS_KEY_ID=${{ fromJson(inputs.secrets).OPENDAL_S3_ACCESS_KEY_ID }}" >> $GITHUB_ENV
+ echo "OPENDAL_S3_SECRET_ACCESS_KEY=${{ fromJson(inputs.secrets).OPENDAL_S3_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
+ echo "OPENDAL_S3_REGION=ap-northeast-1" >> $GITHUB_ENV
diff --git a/.github/workflows/core_test.yml b/.github/workflows/core_test.yml
new file mode 100644
index 000000000..a92cadd9a
--- /dev/null
+++ b/.github/workflows/core_test.yml
@@ -0,0 +1,93 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Core
+
+on:
+ workflow_call:
+ inputs:
+ os:
+ required: true
+ type: string
+ cases:
+ required: true
+ type: string
+ features:
+ required: true
+ type: string
+
+jobs:
+ build:
+ name: build
+ runs-on: ${{ inputs.os }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Rust toolchain
+ uses: ./.github/actions/setup
+ with:
+ need-nextest: true
+ need-protoc: true
+ need-rocksdb: true
+
+ # Required by hdfs
+ - name: Setup java env
+ uses: actions/setup-java@v3
+ with:
+ distribution: temurin
+ java-version: "11"
+
+ - name: Build
+ shell: bash
+ working-directory: core
+ run: |
+ cargo nextest archive --features ${{ inputs.features }} --archive-file ./core-test.tar.zst
+
+ - name: Upload
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ inputs.os }}-core-test
+ path: ./core/core-test.tar.zst
+
+ test:
+ name: ${{ matrix.cases.service }} / ${{ matrix.cases.setup }}
+ needs: [build]
+ runs-on: ${{ inputs.os }}
+ strategy:
+ matrix:
+ cases: ${{ fromJson(inputs.cases) }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup Rust toolchain
+ uses: ./.github/actions/setup
+ with:
+ need-nextest: true
+ need-protoc: true
+ need-rocksdb: true
+
+ - name: Download
+ uses: actions/download-artifact@v3
+ with:
+ name: ${{ inputs.os }}-core-test
+ path: ./core
+
+ - name: Test Core
+ uses: ./.github/actions/test-core
+ with:
+ setup: ${{ matrix.cases.setup }}
+ service: ${{ matrix.cases.service }}
+ secrets: ${{ toJson(secrets) }}
diff --git a/.github/workflows/service_test_fs.yml b/.github/workflows/service_test_fs.yml
deleted file mode 100644
index c06b9e81d..000000000
--- a/.github/workflows/service_test_fs.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: Service Test Fs
-
-on:
- push:
- branches:
- - main
- pull_request:
- branches:
- - main
- paths:
- - "core/src/**"
- - "core/tests/**"
- - "!core/src/docs/**"
- - "!core/src/services/**"
- - "core/src/services/fs/**"
- - ".github/workflows/service_test_fs.yml"
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
- cancel-in-progress: true
-
-jobs:
- local_fs:
- runs-on: ${{ matrix.os }}
- strategy:
- matrix:
- os:
- - ubuntu-latest
- - windows-latest
- steps:
- - uses: actions/checkout@v4
- - name: Setup Rust toolchain
- uses: ./.github/actions/setup
- - name: Test
- shell: bash
- working-directory: core
- run: cargo test services_fs
- env:
- OPENDAL_FS_TEST: on
- OPENDAL_FS_ROOT: ${{ runner.temp }}/
diff --git a/.github/workflows/service_test_s3.yml b/.github/workflows/service_test_s3.yml
index 9efd04f60..95f703ab7 100644
--- a/.github/workflows/service_test_s3.yml
+++ b/.github/workflows/service_test_s3.yml
@@ -39,28 +39,6 @@ concurrency:
cancel-in-progress: true
jobs:
- aws_s3:
- runs-on: ubuntu-latest
- if: github.event_name == 'push' || !github.event.pull_request.head.repo.fork
- steps:
- - uses: actions/checkout@v4
- - name: Setup Rust toolchain
- uses: ./.github/actions/setup
- with:
- need-nextest: true
- - name: Test
- shell: bash
- working-directory: core
- run: cargo nextest run s3
- env:
- OPENDAL_S3_TEST: ${{ secrets.OPENDAL_S3_TEST }}
- OPENDAL_S3_ROOT: ${{ secrets.OPENDAL_S3_ROOT }}
- OPENDAL_S3_BUCKET: ${{ secrets.OPENDAL_S3_BUCKET }}
- OPENDAL_S3_ENDPOINT: ${{ secrets.OPENDAL_S3_ENDPOINT }}
- OPENDAL_S3_ACCESS_KEY_ID: ${{ secrets.OPENDAL_S3_ACCESS_KEY_ID }}
- OPENDAL_S3_SECRET_ACCESS_KEY: ${{ secrets.OPENDAL_S3_SECRET_ACCESS_KEY }}
- OPENDAL_S3_REGION: ap-northeast-1
-
aws_s3_with_virtual_host:
runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.head.repo.fork
diff --git a/.github/workflows/test_planner.yml b/.github/workflows/test_planner.yml
new file mode 100644
index 000000000..535170d86
--- /dev/null
+++ b/.github/workflows/test_planner.yml
@@ -0,0 +1,94 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Test
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
+ cancel-in-progress: true
+
+jobs:
+ plan:
+ runs-on: ubuntu-latest
+ outputs:
+ plan: ${{ steps.plan.outputs.plan }}
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ # fetch depth set to 0 to make sure we have correct diff result.
+ fetch-depth: 0
+
+ - name: Plan
+ id: plan
+ run: |
+ git fetch origin main:main
+
+ event_name="${{ github.event_name }}"
+ repository="${{ github.repository }}"
+ files_changed=""
+ has_secrets="False"
+ is_push="False"
+
+ # Handle event-specific logic
+ if [ "$event_name" == "push" ]; then
+ if [ "$repository" == "apache/incubator-opendal" ]; then
+ is_push="True"
+ has_secrets="True"
+ fi
+ elif [ "$event_name" == "pull_request" ]; then
+ pr_head_repo_fork="${{ github.event.pull_request.head.repo.fork }}"
+ if [ "$pr_head_repo_fork" != "true" ]; then
+ has_secrets="True"
+ fi
+
+ files_changed=$(git diff --name-only main ${{ github.event.pull_request.head.sha }})
+ echo "Files changed:"
+ echo "$FILES_CHANGED"
+ fi
+
+ # Export variables
+ export GITHUB_HAS_SECRETS=$has_secrets
+ export GITHUB_IS_PUSH=$is_push
+
+ # Run the workflow planner script
+ PLAN=$(./scripts/workflow_planner.py $files_changed)
+ echo "Plan:"
+ echo "$PLAN" | jq .
+ echo "plan=$PLAN" >> $GITHUB_OUTPUT
+
+ core_test:
+ name: core / ${{ matrix.os }}
+ needs: [plan]
+ if: fromJson(needs.plan.outputs.plan).components.core
+ secrets: inherit
+ strategy:
+ matrix:
+ include: ${{ fromJson(needs.plan.outputs.plan).core }}
+ uses: ./.github/workflows/core_test.yml
+ with:
+ os: ${{ matrix.os }}
+ cases: ${{ toJson(matrix.cases) }}
+ features: ${{ matrix.features }}
diff --git a/scripts/workflow_planner.py b/scripts/workflow_planner.py
new file mode 100755
index 000000000..7c8d8f9d7
--- /dev/null
+++ b/scripts/workflow_planner.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import sys
+import json
+import os
+from pathlib import Path
+
+
+def get_provided_cases():
+ root_dir = ".github/services"
+
+ cases = [
+ {
+ "service": service,
+ "setup": setup,
+ "content": Path(
+ os.path.join(root_dir, service, setup, "action.yml")
+ ).read_text(),
+ }
+ for service in os.listdir(root_dir)
+ for setup in os.listdir(os.path.join(root_dir, service))
+ ]
+
+ # Check if this workflow needs to read secrets.
+ #
+ # We will check if pattern `secrets.XXX` exist in content.
+ if not bool(os.getenv("GITHUB_HAS_SECRETS")):
+ cases[:] = [v for v in cases if "secrets." not in v["content"]]
+
+ return cases
+
+
+def calculate_core_cases(cases, changed_files):
+ # If any of the core workflow changed, we will run all cases.
+ for p in [
+ ".github/workflows/core_test.yml",
+ ".github/workflows/test_planner.yml",
+ ".github/actions/test-core",
+ ]:
+ if p in changed_files:
+ return cases
+
+ # Always run all tests if it is a push event.
+ if bool(os.getenv("GITHUB_IS_PUSH")):
+ return cases
+
+ # If any of the core files changed, we will run all cases.
+ if any(
+ p.startswith("core/src/") and not p.startswith("core/src/services")
+ for p in changed_files
+ ):
+ return cases
+ if any(p.startswith("core/tests/") for p in changed_files):
+ return cases
+
+ # Filter all cases that not shown un in changed files
+ cases = [v for v in cases if any(v["service"] in p for p in changed_files)]
+ return cases
+
+
+# Context is the github context: https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
+def plan(changed_files):
+ # TODO: add bindings/java, bindings/python in the future.
+ components = ["core"]
+ cases = get_provided_cases()
+
+ core_cases = calculate_core_cases(cases, changed_files)
+
+ jobs = {}
+
+ if len(core_cases) > 0:
+ jobs["components"] = {"core": True}
+ jobs["core"] = [
+ {
+ "os": "ubuntu-latest",
+ "features": ",".join(
+ set([f"services-{v['service']}" for v in core_cases])
+ ),
+ "cases": [
+ {"setup": v["setup"], "service": v["service"]} for v in core_cases
+ ],
+ },
+ ]
+
+ # fs is the only services need to run upon windows, let's hard code it here.
+ if "fs" in [v["service"] for v in core_cases]:
+ jobs["core"].append(
+ {
+ "os": "windows-latest",
+ "features": "services-fs",
+ "cases": [{"setup": "local-fs", "service": "fs"}],
+ }
+ )
+
+ return json.dumps(jobs)
+
+
+# For quick test:
+#
+# ./scripts/workflow_planner.py PATH
+if __name__ == "__main__":
+ changed_files = sys.argv[1:]
+ result = plan(changed_files)
+ print(result)