Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
groups:
python-deps:
patterns:
- "*"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "ci"
groups:
actions:
patterns:
- "*"
18 changes: 15 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,26 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: pip install -e ".[dev]" || pip install -e .
# Install with the [async] extra so test_async_native.py can exercise
# the full AsyncColonyClient stack via httpx.MockTransport.
run: pip install -e ".[dev,async]" pytest-cov

- name: Install test deps
run: pip install pytest
- name: Run tests with coverage
if: matrix.python-version == '3.12'
run: pytest tests/ --ignore=tests/test_integration.py --cov=langchain_colony --cov-report=xml --cov-report=term-missing -v

- name: Run tests
if: matrix.python-version != '3.12'
run: pytest tests/ --ignore=tests/test_integration.py -v

- name: Upload coverage to Codecov
if: matrix.python-version == '3.12'
uses: codecov/codecov-action@v6
with:
files: coverage.xml
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}

lint:
runs-on: ubuntu-latest
steps:
Expand Down
122 changes: 122 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Release

# Publishes to PyPI via OIDC trusted publishing whenever a `v*` tag is pushed.
# No API tokens are stored anywhere — PyPI mints a short-lived token from
# the GitHub Actions OIDC identity at publish time.
#
# To cut a release:
# 1. Bump the version in pyproject.toml
# (langchain_colony.__version__ is derived at import time from
# importlib.metadata.version("langchain-colony"), so pyproject.toml
# is the single source of truth)
# 2. Move the "## Unreleased" section in CHANGELOG.md under a new
# "## X.Y.Z (YYYY-MM-DD)" heading
# 3. Merge to main
# 4. git tag vX.Y.Z && git push origin vX.Y.Z
#
# This workflow will then: run the test suite, build wheel + sdist,
# publish to PyPI via OIDC, and create a GitHub Release with the
# CHANGELOG section as the release notes.

on:
push:
tags:
- "v*"

jobs:
test:
name: Test before release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install -e ".[dev,async]"
- run: ruff check src/ tests/
- run: ruff format --check src/ tests/
- run: pytest tests/ --ignore=tests/test_integration.py

build:
name: Build distributions
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install build
- run: python -m build
- name: Verify version matches tag
# langchain-colony's version lives in pyproject.toml only —
# __version__ is auto-derived via importlib.metadata at import time.
run: |
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
echo "::error::Tag v$TAG_VERSION does not match pyproject.toml version $PKG_VERSION"
exit 1
fi
echo "Tag and pyproject.toml agree on version $PKG_VERSION"
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

publish:
name: Publish to PyPI
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/langchain-colony
permissions:
id-token: write # required for OIDC trusted publishing
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Publish to PyPI via OIDC
uses: pypa/gh-action-pypi-publish@release/v1

github-release:
name: Create GitHub Release
needs: publish
runs-on: ubuntu-latest
permissions:
contents: write # required for gh release create
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Extract changelog section for this version
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
# Print everything under "## VERSION (...)" up to (but not
# including) the next "## " heading. Strips the heading line itself.
# langchain-colony uses "## X.Y.Z (YYYY-MM-DD)" format with parens.
awk -v ver="$VERSION" '
/^## / {
if (in_section) exit
if ($0 ~ "^## " ver "( |$|\\()") { in_section = 1; next }
next
}
in_section { print }
' CHANGELOG.md > release_notes.md
if [ ! -s release_notes.md ]; then
echo "::warning::No CHANGELOG entry found for $VERSION — release notes will be empty"
fi
echo "--- release_notes.md ---"
cat release_notes.md
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${GITHUB_REF_NAME}" \
--title "${GITHUB_REF_NAME}" \
--notes-file release_notes.md \
dist/*
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

### Infrastructure

- **OIDC release automation** — releases now ship via PyPI Trusted Publishing on tag push. `git tag vX.Y.Z && git push origin vX.Y.Z` triggers `.github/workflows/release.yml`, which runs the test suite, builds wheel + sdist, publishes to PyPI via short-lived OIDC tokens (no API token stored anywhere), and creates a GitHub Release with the changelog entry as release notes. The workflow refuses to publish if the tag version doesn't match `pyproject.toml` (the single source of truth — `langchain_colony.__version__` is auto-derived from package metadata at import time).
- **Dependabot** — `.github/dependabot.yml` watches `pip` and `github-actions` weekly, **grouped** into single PRs per ecosystem to minimise noise.
- **Coverage on CI** — `pytest-cov` now runs on the 3.12 job with Codecov upload via `codecov-action@v6`. Previously CI only ran tests with no coverage signal. CI also now installs the `[async]` extra so `test_async_native.py` exercises the full `AsyncColonyClient` stack on every run.

### Added — new tools (SDK 1.4.0 + 1.5.0 surface)

- **`ColonyFollowUser`**, **`ColonyUnfollowUser`** — manage your social graph on The Colony.
Expand Down
Loading