name: Publish Python packages to PyPI on: workflow_dispatch: inputs: version: description: Release version required: true type: string release: types: [published] permissions: contents: read jobs: build: runs-on: ubuntu-latest env: RELEASE_VERSION: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.version }} steps: - uses: actions/checkout@v6 - name: Set up Node uses: actions/setup-node@v4 with: node-version: '22.13' cache: npm cache-dependency-path: website/package-lock.json - name: Set up Python uses: actions/setup-python@v6 with: python-version: '3.11' - name: Install build dependencies run: | python -m pip install --upgrade pip python -m pip install build packaging twine - name: Validate release version run: python scripts/bump_version.py --check --expected-version "${RELEASE_VERSION}" - name: Build Studio static workspace working-directory: website run: | npm ci npm run build:static - name: Prepare and build distributions run: | python scripts/package_studio.py mkdir -p dist/reme dist/studio python -m build --outdir dist/reme python -m build packages/reme_ai_studio --outdir dist/studio python -m twine check dist/reme/* dist/studio/* - name: Verify distributions and isolated installation run: | REME_WHEEL="$(pwd)/$(ls dist/reme/reme_ai-[0-9]*.whl)" STUDIO_WHEEL="$(pwd)/$(ls dist/studio/reme_ai_studio-*.whl)" STUDIO_SDIST="$(pwd)/$(ls dist/studio/reme_ai_studio-*.tar.gz)" python -m zipfile -l "${REME_WHEEL}" | (! grep 'reme/web/') python -m zipfile -l "${STUDIO_WHEEL}" | grep 'reme_ai_studio/static/index.html' python -m zipfile -l "${STUDIO_WHEEL}" | grep 'dist-info/licenses/LICENSE' python -m tarfile -l "${STUDIO_SDIST}" | grep '/LICENSE' python -m venv "${RUNNER_TEMP}/reme-release-smoke" "${RUNNER_TEMP}/reme-release-smoke/bin/python" -m pip install \ --find-links "$(pwd)/dist/studio" "${REME_WHEEL}[core]" cd "${RUNNER_TEMP}" "${RUNNER_TEMP}/reme-release-smoke/bin/python" -c \ "import reme; from reme_ai_studio import static_dir; assert (static_dir() / 'index.html').is_file()" "${RUNNER_TEMP}/reme-release-smoke/bin/python" -c \ "from reme.utils import resolve_web_static_dir; assert (resolve_web_static_dir() / 'index.html').is_file()" - name: Upload ReMe Studio distributions uses: actions/upload-artifact@v4 with: name: reme-studio-distributions path: dist/studio/ - name: Upload ReMe distributions uses: actions/upload-artifact@v4 with: name: reme-distributions path: dist/reme/ publish-studio: needs: build runs-on: ubuntu-latest steps: - name: Download ReMe Studio distributions uses: actions/download-artifact@v4 with: name: reme-studio-distributions path: dist/studio - name: Publish ReMe Studio uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} packages-dir: dist/studio skip-existing: true publish-reme: needs: publish-studio runs-on: ubuntu-latest steps: - name: Download ReMe distributions uses: actions/download-artifact@v4 with: name: reme-distributions path: dist/reme - name: Publish ReMe uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} packages-dir: dist/reme skip-existing: true