Skip to content

fix: exclude RequestCredentials.api_token from repr #1147

fix: exclude RequestCredentials.api_token from repr

fix: exclude RequestCredentials.api_token from repr #1147

name: Canvas MCP Enhancement Testing
on:
push:
branches: [ main, development ]
pull_request:
branches: [ main ]
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.11'
- name: Install Ruff
run: python -m pip install ruff
- name: Run Ruff
run: ruff check src/ tests/
- name: Install mypy
# Read the constraint from pyproject instead of repeating it. A literal
# here silently drifts: it said "<2" while pyproject said "<3", so CI
# would have kept type-checking on mypy 1.x forever while contributors
# running `uv sync` got 2.x — the gate asserting a version nobody uses.
run: |
python -m pip install -e .
CONSTRAINT=$(python - <<'PY'
import tomllib
with open("pyproject.toml", "rb") as fh:
groups = tomllib.load(fh)["dependency-groups"]["dev"]
specs = [d for d in groups if isinstance(d, str) and d.startswith("mypy")]
if len(specs) != 1:
raise SystemExit(f"expected exactly one mypy spec in dependency-groups.dev, found {specs}")
print(specs[0])
PY
)
echo "Installing $CONSTRAINT"
python -m pip install "$CONSTRAINT"
- name: Run mypy
run: mypy src/
test-code-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install TypeScript dependencies
run: npm ci
- name: Build and test code API
run: npm run build && npm test
verify-confirmation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install pinned formal-verification tools
run: |
curl --fail --location --retry 3 -o "$RUNNER_TEMP/lean.tar.zst" https://github.com/leanprover/lean4/releases/download/v4.19.0/lean-4.19.0-linux.tar.zst
echo "6fe3ce97a58f44e2b3567d455b994eacec5bfe9ae7774f2a573444480ba813fe $RUNNER_TEMP/lean.tar.zst" | sha256sum --check
tar --no-same-owner --zstd -xf "$RUNNER_TEMP/lean.tar.zst" -C "$RUNNER_TEMP"
echo "$RUNNER_TEMP/lean-4.19.0-linux/bin" >> "$GITHUB_PATH"
curl --fail --location --retry 3 -o "$RUNNER_TEMP/tla2tools.jar" https://github.com/tlaplus/tlaplus/releases/download/v1.7.4/tla2tools.jar
# verify/run.py checks the pinned jar digest before execution.
- name: Prove the repaired machine and reproduce original counterexamples
run: TLA_JAR="$RUNNER_TEMP/tla2tools.jar" python verify/run.py
# Runs the WHOLE suite on every supported interpreter. pyproject declares
# requires-python = ">=3.11" (3.10 dropped ahead of its 2026-10-31 EOL, #315),
# so every version in the matrix is a supported target and a version-specific
# break on the oldest one is invisible on a newer-only runner.
test:
runs-on: ubuntu-latest
env:
# FastMCP 4 temporarily bridges MCP SDK v1 camelCase attribute reads.
# Keep the bridge off in CI so new code must use the v2 snake_case API.
FASTMCP_MCP_CAMELCASE_COMPAT: "false"
strategy:
fail-fast: false
matrix:
python-version: ['3.11', '3.12', '3.13', '3.14']
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history: test_acceptance_replay_real_history replays the
# closing-keyword checker over every real commit message. The default
# shallow checkout has no `main` and no old commits, so the replay would
# skip -- and a validator that only ever sees its own fixtures has not
# earned its place.
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
# pyyaml is needed by the workflow-permission policy tests. They use
# importorskip, so omitting it makes them skip silently in the one job
# branch protection actually requires — passing green while the check
# they encode is never run.
pip install pytest pytest-asyncio pyyaml
- name: Run the test suite
run: pytest tests/ -q
# The same full suite on Windows, where a local stdio server often runs and
# where things Linux never exercises break: an open file cannot be deleted,
# symlinks need a privilege, `python3` may be the Store alias, and the
# default text encoding is the ANSI code page rather than UTF-8.
test-windows:
runs-on: windows-latest
env:
FASTMCP_MCP_CAMELCASE_COMPAT: "false"
# UTF-8 mode for the interpreter and the Pythons it spawns, so stdio and
# files opened without an explicit encoding do not use the ANSI code page.
PYTHONUTF8: "1"
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history, for the same closing-keyword replay as the Linux job.
fetch-depth: 0
- name: Set up Python 3.14
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.14'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e .
python -m pip install pytest pytest-asyncio pyyaml
- name: Run the test suite
run: python -m pytest tests/ -q
# Aggregator. Branch protection requires a check literally named
# "test-enhancements", and a matrix job publishes per-version names
# ("test (3.11)"), which would leave the required check permanently pending
# and block every PR. This gate keeps the required name while making it mean
# "the full suite passed on every supported Python, on Linux and Windows, and
# the code API passed".
test-enhancements:
runs-on: ubuntu-latest
needs: [test, test-windows, test-code-api, verify-confirmation]
if: always()
steps:
- name: Require Python (Linux and Windows), code API, and confirmation proofs to have succeeded
run: |
echo "matrix result: ${{ needs.test.result }}"
echo "windows result: ${{ needs.test-windows.result }}"
if [ "${{ needs.test.result }}" != "success" ] || [ "${{ needs.test-windows.result }}" != "success" ] || [ "${{ needs.test-code-api.result }}" != "success" ] || [ "${{ needs.verify-confirmation.result }}" != "success" ]; then
echo "::error::Python (Linux or Windows), code API, or confirmation verification did not succeed."
exit 1
fi
echo "## Canvas MCP test results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Full suite passed on Ubuntu with Python 3.11, 3.12, 3.13 and 3.14, and on Windows with Python 3.14." >> $GITHUB_STEP_SUMMARY