diff --git a/.github/workflows/ci_v2_shadow.yml b/.github/workflows/ci_v2_shadow.yml index 25f02a11..ef44af65 100644 --- a/.github/workflows/ci_v2_shadow.yml +++ b/.github/workflows/ci_v2_shadow.yml @@ -27,11 +27,50 @@ on: branches: ["master", "ci/ci-online"] jobs: + plugin-matrix: + runs-on: ubuntu-latest + outputs: + platform: ${{ steps.select.outputs.platform }} + requires_full_matrix: ${{ steps.select.outputs.requires_full_matrix }} + matrix_json: ${{ steps.select.outputs.matrix_json }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Collect changed paths + if: github.event_name == 'pull_request' + run: | + git diff --name-only \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.sha }}" > changed_paths.txt + + - name: Select active platforms + id: select + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.platform }}" != "active" ]]; then + if [[ "${{ inputs.platform }}" == "all" ]]; then + echo "platform=nvidia,iluvatar,metax,moore,cambricon,ascend" >> "$GITHUB_OUTPUT" + else + echo "platform=${{ inputs.platform }}" >> "$GITHUB_OUTPUT" + fi + echo "requires_full_matrix=false" >> "$GITHUB_OUTPUT" + echo 'matrix_json={}' >> "$GITHUB_OUTPUT" + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + python scripts/infini_ops_plugin_test_matrix.py --github-output < changed_paths.txt >> "$GITHUB_OUTPUT" + else + echo "platform=nvidia,iluvatar,metax,moore,cambricon,ascend" >> "$GITHUB_OUTPUT" + echo "requires_full_matrix=true" >> "$GITHUB_OUTPUT" + echo 'matrix_json={}' >> "$GITHUB_OUTPUT" + fi + ci-v2-shadow: + needs: plugin-matrix + if: needs.plugin-matrix.outputs.platform != '' uses: InfiniTensor/ci/.github/workflows/infiniops-ci-v2-shadow.yml@b45d360c8cc529747ee31c5451d7eac96ac9f309 with: config_path: .github/ci_config.yml ci_ref: b45d360c8cc529747ee31c5451d7eac96ac9f309 max_parallel: 10 - platform: ${{ github.event_name == 'workflow_dispatch' && (inputs.platform == 'all' && 'nvidia,iluvatar,metax,moore,cambricon,ascend' || inputs.platform == 'active' && 'nvidia,iluvatar,metax,moore,cambricon,ascend' || inputs.platform) || 'nvidia,iluvatar,metax,moore,cambricon,ascend' }} + platform: ${{ needs.plugin-matrix.outputs.platform }} secrets: inherit diff --git a/scripts/infini_ops_plugin_test_matrix.py b/scripts/infini_ops_plugin_test_matrix.py index 86d4120f..5b0a4984 100644 --- a/scripts/infini_ops_plugin_test_matrix.py +++ b/scripts/infini_ops_plugin_test_matrix.py @@ -138,6 +138,16 @@ def _read_paths(args): return [line.strip() for line in sys.stdin if line.strip()] +def _print_github_output(matrix): + platform = ",".join(matrix["ci_platforms"]) + requires_full_matrix = str(matrix["requires_full_matrix"]).lower() + compact_json = json.dumps(matrix, sort_keys=True, separators=(",", ":")) + + print(f"platform={platform}") + print(f"requires_full_matrix={requires_full_matrix}") + print(f"matrix_json={compact_json}") + + def main(argv=None): parser = argparse.ArgumentParser( description="Map changed paths to `infini::ops` plugin test devices." @@ -151,11 +161,19 @@ def main(argv=None): "to include external plugin roots." ), ) + parser.add_argument( + "--github-output", + action="store_true", + help="Print `$GITHUB_OUTPUT` compatible key/value lines.", + ) parser.add_argument("paths", nargs="*", help="Changed paths to classify.") args = parser.parse_args(argv) matrix = build_test_matrix(args.plugin_root or ["plugins"], _read_paths(args)) - print(json.dumps(matrix, indent=2, sort_keys=True)) + if args.github_output: + _print_github_output(matrix) + else: + print(json.dumps(matrix, indent=2, sort_keys=True)) if __name__ == "__main__": diff --git a/tests/test_plugin_test_matrix.py b/tests/test_plugin_test_matrix.py index 461ec296..d2231a2f 100644 --- a/tests/test_plugin_test_matrix.py +++ b/tests/test_plugin_test_matrix.py @@ -132,6 +132,41 @@ def test_matrix_accepts_multiple_plugin_roots(tmp_path): assert matrix["ci_platforms"] == [] +def test_cli_outputs_github_output_format(): + repo = pathlib.Path(__file__).resolve().parents[1] + script = repo / "scripts" / "infini_ops_plugin_test_matrix.py" + + result = subprocess.run( + [ + sys.executable, + str(script), + "--plugin-root", + str(_plugin_root()), + "--github-output", + "src/native/cuda/nvidia/ops/add/add.cu", + ], + check=True, + stdout=subprocess.PIPE, + text=True, + ) + + assert "platform=nvidia" in result.stdout.splitlines() + assert "requires_full_matrix=false" in result.stdout.splitlines() + + +def test_shadow_ci_uses_path_aware_platform_output(): + workflow = ( + pathlib.Path(__file__).resolve().parents[1] + / ".github" + / "workflows" + / "ci_v2_shadow.yml" + ).read_text(encoding="utf-8") + + assert "plugin-matrix:" in workflow + assert "scripts/infini_ops_plugin_test_matrix.py --github-output" in workflow + assert "needs.plugin-matrix.outputs.platform" in workflow + + def test_cli_outputs_json_matrix(tmp_path): repo = pathlib.Path(__file__).resolve().parents[1] script = repo / "scripts" / "infini_ops_plugin_test_matrix.py"