diff --git a/.github/workflows/lint.yml b/.github/workflows/_lint.yml similarity index 100% rename from .github/workflows/lint.yml rename to .github/workflows/_lint.yml diff --git a/.github/workflows/test.yml b/.github/workflows/_test.yml similarity index 100% rename from .github/workflows/test.yml rename to .github/workflows/_test.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..b292e19d3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +--- + name: CI + + on: + push: + branches: [master] + pull_request: + + # If another push to the same PR or branch happens while this workflow is still running, + # cancel the earlier run in favor of the next run. + # + # There's no point in testing an outdated version of the code. GitHub only allows + # a limited number of job runners to be active at the same time, so it's better to cancel + # pointless jobs early so that more useful jobs can run sooner. + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + env: + POETRY_VERSION: "1.7.1" + + jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + + lint: + name: cd ${{ matrix.working-directory }} + needs: [ build ] + strategy: + matrix: + working-directory: [ + "libs/langgraph/", + "libs/sdk-py", + "libs/cli" + ] + uses: ./.github/workflows/_lint.yml + with: + working-directory: ${{ matrix.working-directory }} + secrets: inherit + + test: + name: cd ${{ matrix.working-directory }} + needs: [ build ] + strategy: + matrix: + working-directory: [ + "libs/langgraph/", + "libs/cli" + ] + uses: ./.github/workflows/_test.yml + with: + working-directory: ${{ matrix.working-directory }} + secrets: inherit + + ci_success: + name: "CI Success" + needs: [build, lint, test] + if: | + always() + runs-on: ubuntu-latest + env: + JOBS_JSON: ${{ toJSON(needs) }} + RESULTS_JSON: ${{ toJSON(needs.*.result) }} + EXIT_CODE: ${{!contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && '0' || '1'}} + steps: + - name: "CI Success" + run: | + echo $JOBS_JSON + echo $RESULTS_JSON + echo "Exiting with $EXIT_CODE" + exit $EXIT_CODE + \ No newline at end of file diff --git a/libs/cli/Makefile b/libs/cli/Makefile index 0bb0d74da..680c8f53c 100644 --- a/libs/cli/Makefile +++ b/libs/cli/Makefile @@ -1,13 +1,31 @@ -.PHONY: lint format +.PHONY: test lint format -lint: - poetry run ruff . - poetry run ruff format . --diff - poetry run mypy . - -format: - poetry run ruff format . - poetry run ruff --select I --fix . +###################### +# TESTING AND COVERAGE +###################### test: - poetry run pytest tests \ No newline at end of file + poetry run pytest tests + +###################### +# LINTING AND FORMATTING +###################### + +# Define a variable for Python and notebook files. +PYTHON_FILES=. +MYPY_CACHE=.mypy_cache +lint format: PYTHON_FILES=. +lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --relative --diff-filter=d main . | grep -E '\.py$$|\.ipynb$$') +lint_package: PYTHON_FILES=langgraph_cli +lint_tests: PYTHON_FILES=tests +lint_tests: MYPY_CACHE=.mypy_cache_test + +lint lint_diff lint_package lint_tests: + poetry run ruff . + [ "$(PYTHON_FILES)" = "" ] || poetry run ruff format $(PYTHON_FILES) --diff + [ "$(PYTHON_FILES)" = "" ] || poetry run ruff --select I $(PYTHON_FILES) + [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) || poetry run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) + +format format_diff: + poetry run ruff format $(PYTHON_FILES) + poetry run ruff --select I --fix $(PYTHON_FILES) \ No newline at end of file diff --git a/libs/langgraph/Makefile b/libs/langgraph/Makefile index dad4407d2..8403fbf33 100644 --- a/libs/langgraph/Makefile +++ b/libs/langgraph/Makefile @@ -28,7 +28,7 @@ test_watch: PYTHON_FILES=. MYPY_CACHE=.mypy_cache lint format: PYTHON_FILES=. -lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --diff-filter=d master | grep -E '\.py$$|\.ipynb$$') +lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --relative --diff-filter=d main . | grep -E '\.py$$|\.ipynb$$') lint_package: PYTHON_FILES=langgraph lint_tests: PYTHON_FILES=tests lint_tests: MYPY_CACHE=.mypy_cache_test diff --git a/libs/sdk-py/Makefile b/libs/sdk-py/Makefile index d3707c2f8..f7c1fc828 100644 --- a/libs/sdk-py/Makefile +++ b/libs/sdk-py/Makefile @@ -1,10 +1,21 @@ .PHONY: lint format -lint: - poetry run ruff check . - poetry run ruff format . --diff - poetry run mypy . +###################### +# LINTING AND FORMATTING +###################### -format: - poetry run ruff format . - poetry run ruff check --select I --fix . +# Define a variable for Python and notebook files. +PYTHON_FILES=. +MYPY_CACHE=.mypy_cache +lint format: PYTHON_FILES=. +lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --relative --diff-filter=d main . | grep -E '\.py$$|\.ipynb$$') + +lint lint_diff: + poetry run ruff . + [ "$(PYTHON_FILES)" = "" ] || poetry run ruff format $(PYTHON_FILES) --diff + [ "$(PYTHON_FILES)" = "" ] || poetry run ruff --select I $(PYTHON_FILES) + [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) || poetry run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) + +format format_diff: + poetry run ruff format $(PYTHON_FILES) + poetry run ruff --select I --fix $(PYTHON_FILES) \ No newline at end of file