Repository navigation
Publish Release #8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to verify or publish, for example 0.6.0' | |
| required: true | |
| publish_pypi: | |
| description: 'Publish the Python package to PyPI using Trusted Publisher' | |
| required: true | |
| type: boolean | |
| default: false | |
| publish_npm: | |
| description: 'Publish the npm wrapper to npm using Trusted Publishing' | |
| required: true | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: read | |
| jobs: | |
| verify: | |
| name: Verify release package | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| enable-cache: true | |
| - name: Set up Python | |
| run: uv python install 3.11 | |
| - name: Validate version metadata | |
| run: | | |
| python3 - <<'PY' | |
| import json | |
| import sys | |
| import tomllib | |
| from pathlib import Path | |
| expected = "${{ inputs.version }}" | |
| pyproject = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8")) | |
| python_version = pyproject["project"]["version"] | |
| init_version = None | |
| for line in Path("src/magicmd/__init__.py").read_text(encoding="utf-8").splitlines(): | |
| if line.startswith("__version__"): | |
| init_version = line.split("=", 1)[1].strip().strip('"') | |
| break | |
| npm_version = json.loads(Path("npm/magicmd/package.json").read_text(encoding="utf-8"))["version"] | |
| versions = { | |
| "workflow input": expected, | |
| "pyproject.toml": python_version, | |
| "src/magicmd/__init__.py": init_version, | |
| "npm/magicmd/package.json": npm_version, | |
| } | |
| mismatches = {source: version for source, version in versions.items() if version != expected} | |
| if mismatches: | |
| print("Version metadata mismatch:") | |
| for source, version in versions.items(): | |
| print(f"- {source}: {version}") | |
| sys.exit(1) | |
| print(f"Version metadata verified: {expected}") | |
| PY | |
| - name: Install dependencies | |
| run: uv sync --extra dev | |
| - name: Run tests | |
| run: uv run pytest -q | |
| - name: Run ruff | |
| run: uv run ruff check . | |
| - name: Build Python package | |
| run: uv build | |
| - name: Check Python distributions | |
| run: uvx twine check dist/* | |
| - name: Check npm wrapper package | |
| working-directory: npm/magicmd | |
| run: npm pack --dry-run | |
| - name: Upload Python distributions | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: python-dist-${{ inputs.version }} | |
| path: dist/* | |
| if-no-files-found: error | |
| publish-pypi: | |
| name: Publish Python package to PyPI | |
| if: ${{ inputs.publish_pypi }} | |
| needs: verify | |
| runs-on: ubuntu-latest | |
| environment: pypi | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Download Python distributions | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-dist-${{ inputs.version }} | |
| path: dist | |
| - name: Publish Python package to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| publish-npm: | |
| name: Publish npm wrapper to npm | |
| if: ${{ always() && inputs.publish_npm && needs.verify.result == 'success' && (needs.publish-pypi.result == 'success' || needs.publish-pypi.result == 'skipped') }} | |
| needs: | |
| - verify | |
| - publish-pypi | |
| runs-on: ubuntu-latest | |
| environment: npm | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| package-manager-cache: false | |
| - name: Check npm wrapper package | |
| working-directory: npm/magicmd | |
| run: npm pack --dry-run | |
| - name: Publish npm wrapper | |
| working-directory: npm/magicmd | |
| run: npm publish --registry=https://registry.npmjs.org --provenance |