Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langchain ai Langchain PyPI Trusted Publishing Production

From Leeroopedia

Template:Metadata

Overview

Concrete tool for publishing validated LangChain packages to production PyPI and creating a GitHub Release, provided by the publish and mark-release jobs in _release.yml.

Description

The production publishing stage consists of two sequential jobs:

Job 1: publish (lines 534-578)

Uploads the distribution artifacts to production PyPI using the pypa/gh-action-pypi-publish action with OIDC trusted publishing. Key characteristics:

  • Requires id-token: write permission for OIDC authentication.
  • Uses the default PyPI repository URL (production https://upload.pypi.org/legacy/).
  • Does not set skip-existing (unlike Test PyPI), so re-uploading the same version will fail -- this is intentional to prevent accidental overwrites.
  • Attestations are disabled as a temporary workaround.
  • Only runs if all preceding jobs succeeded or were skipped (!cancelled() && !failure()).

Job 2: mark-release (lines 580-620)

Creates a GitHub Release using the ncipollo/release-action:

  • Tags the release as <pkg-name>==<version> (e.g., langchain-core==1.2.11).
  • Attaches the distribution artifacts (dist/*) to the release.
  • Sets the release body to the auto-generated release notes from the release-notes job.
  • Pins the release to the exact commit SHA that triggered the workflow.
  • Marks the release as "latest" only if the package is langchain-core.

Usage

These jobs run automatically at the end of the release pipeline. The publish job depends on all validation jobs passing. The mark-release job depends on publish succeeding.

Code Reference

Source Location: .github/workflows/_release.yml (lines 534-620)

Publish Job:

publish:
  needs:
    - build
    - release-notes
    - test-pypi-publish
    - pre-release-checks
    - test-dependents
    - test-prior-published-packages-against-new-core
  if: ${{ !cancelled() && !failure() }}
  runs-on: ubuntu-latest
  permissions:
    id-token: write

  defaults:
    run:
      working-directory: ${{ inputs.working-directory }}

  steps:
    - uses: actions/checkout@v6

    - name: Set up Python + uv
      uses: "./.github/actions/uv_setup"
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - uses: actions/download-artifact@v7
      with:
        name: dist
        path: ${{ inputs.working-directory }}/dist/

    - name: Publish package distributions to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        packages-dir: ${{ inputs.working-directory }}/dist/
        verbose: true
        print-hash: true
        attestations: false

Mark Release Job:

mark-release:
  needs:
    - build
    - release-notes
    - test-pypi-publish
    - pre-release-checks
    - publish
  runs-on: ubuntu-latest
  permissions:
    contents: write

  steps:
    - uses: actions/checkout@v6

    - name: Set up Python + uv
      uses: "./.github/actions/uv_setup"
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - uses: actions/download-artifact@v7
      with:
        name: dist
        path: ${{ inputs.working-directory }}/dist/

    - name: Create Tag
      uses: ncipollo/release-action@v1
      with:
        artifacts: "dist/*"
        token: ${{ secrets.GITHUB_TOKEN }}
        generateReleaseNotes: false
        tag: ${{ needs.build.outputs.pkg-name }}==${{ needs.build.outputs.version }}
        body: ${{ needs.release-notes.outputs.release-body }}
        commit: ${{ github.sha }}
        makeLatest: ${{ needs.build.outputs.pkg-name == 'langchain-core' }}

Invocation: Automatic, as the final jobs in the release pipeline.

I/O Contract

Direction Name Type Description
Input dist/*.whl File Built wheel artifact
Input dist/*.tar.gz File Built source distribution
Input OIDC token Token Short-lived identity token for PyPI authentication
Input pkg-name string Package name from build job (e.g., langchain-core)
Input version string Version from build job (e.g., 1.2.11)
Input release-body string Auto-generated release notes
Input github.sha string Commit SHA that triggered the workflow
Input GITHUB_TOKEN Secret Token for creating the GitHub Release
Output PyPI package Published package Available at https://pypi.org/project/<pkg-name>/<version>/
Output GitHub Release Release Tagged as <pkg-name>==<version> with artifacts and release notes

Usage Examples

Example 1: Verifying the published package

# After publish completes:
pip install langchain-core==1.2.11
python -c "import langchain_core; print(langchain_core.__version__)"

Example 2: Viewing the GitHub Release

# The release is available at:
# https://github.com/langchain-ai/langchain/releases/tag/langchain-core==1.2.11

# Or via gh CLI:
gh release view "langchain-core==1.2.11" --repo langchain-ai/langchain

Example 3: Tag format examples

langchain-core==1.2.11
langchain-openai==1.1.9
langchain-anthropic==0.3.12
langchain==0.3.25
langchain-text-splitters==0.3.8

Example 4: The makeLatest flag behavior

# Only langchain-core releases are marked as "Latest" on GitHub Releases:
makeLatest: ${{ needs.build.outputs.pkg-name == 'langchain-core' }}

# For langchain-core==1.2.11 -> makeLatest = true
# For langchain-openai==1.1.9  -> makeLatest = false

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment