Skip to content

fix(keycardai-langchain): raise the langchain and langgraph floors to versions that install #442

fix(keycardai-langchain): raise the langchain and langgraph floors to versions that install

fix(keycardai-langchain): raise the langchain and langgraph floors to versions that install #442

Workflow file for this run

name: Pull Request Validation
on:
pull_request:
branches:
- main
- release/mcp-v1
permissions:
contents: read
pull-requests: write
jobs:
validate-commits:
runs-on: ubuntu-latest
if: github.event.pull_request.user.type != 'Bot'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install just
run: |
mkdir -p "$HOME/.local/bin"
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh \
| bash -s -- --tag 1.50.0 --to "$HOME/.local/bin"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Validate commit messages
run: just validate-commits
lint-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install just
run: |
mkdir -p "$HOME/.local/bin"
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh \
| bash -s -- --tag 1.50.0 --to "$HOME/.local/bin"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Install dependencies
run: uv sync --all-extras
- name: Run linting and formatting checks
run: just check
- name: Run tests with coverage
run: just test-coverage
- name: Test release tooling
run: just test-release-tooling
# Version matrix for packages/langchain only (ECO-287). lint-and-test already
# covers latest resolutions on Python 3.12, so these legs only add the cases
# that job cannot see: the declared floors, one real customer pin set, and the
# mcp 1.x/2.x resolution clash from the ECO-213 audit.
langchain-version-matrix:
runs-on: ubuntu-latest
name: langchain (${{ matrix.leg }})
strategy:
fail-fast: false
matrix:
include:
- leg: floors
python-version: "3.12"
- leg: customer-pins
python-version: "3.13"
- leg: mcp-resolution-clash
python-version: "3.12"
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
# Tags drive uv-dynamic-versioning, so the built packages carry their
# real versions in the resolution printout.
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v4
# --no-sources keeps keycardai-oauth coming from the index at its declared
# floor instead of the workspace checkout: the floor is what users install.
- name: Floors resolution
if: matrix.leg == 'floors'
run: |
uv venv .venv-leg --python "${{ matrix.python-version }}"
source .venv-leg/bin/activate
uv pip install --no-sources --resolution lowest-direct "./packages/langchain[test]"
uv pip list
cd packages/langchain && pytest tests/ -v
- name: Customer pins (langchain 1.3.13, langgraph 1.2.11)
if: matrix.leg == 'customer-pins'
run: |
uv venv .venv-leg --python "${{ matrix.python-version }}"
source .venv-leg/bin/activate
uv pip install "./packages/langchain[test]" "langchain==1.3.13" "langgraph==1.2.11"
uv pip list
cd packages/langchain && pytest tests/ -v
# Installation check, not a test suite: langchain-mcp-adapters declares an
# uncapped mcp>=1.24 while keycardai-mcp holds mcp>=2.0,<3.0, so the three
# packages have to land on one coherent mcp.
- name: MCP resolution clash
if: matrix.leg == 'mcp-resolution-clash'
run: |
uv venv .venv-leg --python "${{ matrix.python-version }}"
source .venv-leg/bin/activate
uv pip install "./packages/langchain" "./packages/mcp" langchain-mcp-adapters
uv pip list
python - <<'PY'
import importlib.metadata as md
watched = [
"mcp",
"mcp-types",
"langchain-mcp-adapters",
"keycardai-mcp",
"keycardai-langchain",
"keycardai-oauth",
"langchain",
"langchain-core",
"langgraph",
]
resolved = {}
for name in watched:
try:
resolved[name] = md.version(name)
except md.PackageNotFoundError:
continue
print(f"resolved {name}=={resolved[name]}")
mcp_version = resolved["mcp"]
mcp_major = int(mcp_version.split(".")[0])
if mcp_major != 2:
raise SystemExit(
f"resolver backtracked to mcp {mcp_version}; expected a single mcp 2.x. "
f"Resolution was: {resolved}"
)
types_version = resolved.get("mcp-types")
if types_version and types_version.split(".")[0] != str(mcp_major):
raise SystemExit(
f"incoherent mcp install: mcp {mcp_version} with mcp-types {types_version}"
)
import keycardai.langchain # noqa: F401
import keycardai.mcp # noqa: F401
import langchain_mcp_adapters # noqa: F401
import mcp # noqa: F401
print(f"mcp {mcp_version}: keycardai-langchain, keycardai-mcp and langchain-mcp-adapters all import")
PY
release-preview:
runs-on: ubuntu-latest
needs: [validate-commits, lint-and-test]
if: github.event_name == 'pull_request'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install just
run: |
mkdir -p "$HOME/.local/bin"
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh \
| bash -s -- --tag 1.50.0 --to "$HOME/.local/bin"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Install dependencies
run: uv sync --all-extras
- name: Generate release preview
id: release-preview
run: |
# Get version preview information using the Python script
version_preview=$(uv run python scripts/version_preview.py --format github-summary)
echo "preview<<EOF" >> $GITHUB_OUTPUT
echo "$version_preview" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# Check if there are any changes by looking for version information
changes=$(uv run python scripts/version_preview.py --format json)
if [ "$changes" = "[]" ] || [ -z "$changes" ]; then
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "has_changes=true" >> $GITHUB_OUTPUT
fi
- name: Display release preview
if: steps.release-preview.outputs.has_changes == 'true'
run: |
# Use cat with here document to safely handle special characters
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
${{ steps.release-preview.outputs.preview }}
### 📝 Changelog Preview
```
EOF
just preview-changelog >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: No release preview
if: steps.release-preview.outputs.has_changes == 'false'
run: |
# Use cat with here document to safely handle special characters
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
${{ steps.release-preview.outputs.preview }}
EOF
- name: Comment on PR with release preview
if: github.event_name == 'pull_request'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.number }}
run: |
uv run python scripts/pr_comment.py