treemapper CD #20
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
| # .github/workflows/cd.yml | |
| name: TreeMapper CD | |
| permissions: | |
| contents: write # Нужно для создания релиза и коммита/тега/merge | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to release (e.g., 1.0.0)' | |
| required: true | |
| publish_to_pypi: | |
| description: 'Publish to PyPI' | |
| required: true | |
| default: 'false' | |
| type: choice | |
| options: | |
| - 'true' | |
| - 'false' | |
| jobs: | |
| # --- 1. Подготовка: Установка версии и создание тега/релиза --- | |
| prepare-release: | |
| name: Prepare and Create GitHub Release | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.set_outputs.outputs.version }} | |
| tag_name: ${{ steps.set_outputs.outputs.tag_name }} | |
| upload_url: ${{ steps.create_release.outputs.upload_url }} | |
| release_id: ${{ steps.create_release.outputs.id }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 # Используем v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 # Используем v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Set version in version.py | |
| run: | | |
| VERSION="${{ github.event.inputs.version }}" | |
| echo "Setting version to $VERSION" | |
| sed -i -E "s/__version__ = \".*\"/__version__ = \"$VERSION\"/" src/treemapper/version.py | |
| echo "version.py content after change:" | |
| cat src/treemapper/version.py | |
| # --- Коммит, тег И PUSH ИХ ВМЕСТЕ --- | |
| - name: Commit, Tag, and Push version bump | |
| run: | | |
| git config user.name github-actions[bot] # Используем стандартного бота | |
| git config user.email 41898282+github-actions[bot]@users.noreply.github.com | |
| git add src/treemapper/version.py | |
| # Коммитим только если есть изменения | |
| git diff --staged --quiet || git commit -m "Release version ${{ github.event.inputs.version }}" | |
| git tag v${{ github.event.inputs.version }} | |
| # ---> ИЗМЕНЕНИЕ: Отправляем и коммит (HEAD текущей ветки) и тег вместе <--- | |
| git push origin HEAD v${{ github.event.inputs.version }} | |
| # --- Создание релиза GitHub --- | |
| - name: Create GitHub Release | |
| id: create_release | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: v${{ github.event.inputs.version }} | |
| release_name: Release ${{ github.event.inputs.version }} | |
| # Commitish теперь не обязателен, т.к. tag_name уже должен существовать удаленно | |
| # Но можно оставить для ясности, т.к. тег уже запушен | |
| commitish: v${{ github.event.inputs.version }} | |
| draft: false | |
| prerelease: false | |
| - name: Set outputs for subsequent jobs | |
| id: set_outputs | |
| run: | | |
| echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT | |
| echo "tag_name=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT | |
| # --- 2. Сборка и загрузка ассетов для разных ОС --- | |
| build-and-upload: | |
| name: Build and Upload Assets | |
| needs: prepare-release | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| asset_name: linux | |
| python-version: '3.11' | |
| - os: macos-latest | |
| asset_name: macos | |
| python-version: '3.11' | |
| - os: windows-latest | |
| asset_name: windows | |
| python-version: '3.11' | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout Code at release tag | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.prepare-release.outputs.tag_name }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip Dependencies | |
| uses: actions/cache@v4 | |
| id: cache-pip | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.cfg') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-${{ matrix.python-version }}- | |
| ${{ runner.os }}-pip- | |
| - name: Install Dependencies (including PyInstaller) | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Build with PyInstaller | |
| run: | | |
| python -m PyInstaller --clean -y --dist ./dist/${{ matrix.asset_name }} treemapper.spec | |
| - name: Determine architecture | |
| id: arch | |
| shell: bash | |
| run: | | |
| ARCH=$(uname -m) | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| if [[ "${{ runner.arch }}" == "X64" ]]; then ARCH="x86_64"; \ | |
| elif [[ "${{ runner.arch }}" == "ARM64" ]]; then ARCH="arm64"; \ | |
| else ARCH="unknown"; fi | |
| elif [[ "${{ runner.os }}" == "macOS" ]] && [[ "$ARCH" == "arm64" ]]; then | |
| echo "Detected ARM on macOS" | |
| fi | |
| echo "Determined ARCH: $ARCH" | |
| echo "arch=$ARCH" >> $GITHUB_OUTPUT | |
| - name: Upload Release Asset | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.prepare-release.outputs.upload_url }} | |
| # Путь к ассету (PyInstaller создает папку с именем скрипта внутри dist) | |
| asset_path: ./dist/${{ matrix.asset_name }}/treemapper/${{ matrix.os == 'windows-latest' && 'treemapper.exe' || 'treemapper' }} | |
| asset_name: treemapper-${{ matrix.asset_name }}-${{ steps.arch.outputs.arch }}-v${{ needs.prepare-release.outputs.version }}${{ matrix.os == 'windows-latest' && '.exe' || '' }} | |
| asset_content_type: application/octet-stream | |
| # --- 3. Публикация на PyPI (опционально) --- | |
| publish-to-pypi: | |
| name: Publish to PyPI | |
| needs: [prepare-release, build-and-upload] | |
| if: github.event.inputs.publish_to_pypi == 'true' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/treemapper | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Checkout Code at release tag | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.prepare-release.outputs.tag_name }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install build tools | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build | |
| - name: Build sdist and wheel | |
| run: python -m build | |
| - name: Publish package distributions to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| # --- 4. Обновление ветки main (опционально) --- | |
| update-main-branch: | |
| name: Update main branch (Merge Tag) | |
| # Запускается ПОСЛЕ успешной сборки ассетов | |
| needs: [prepare-release, build-and-upload] | |
| runs-on: ubuntu-latest | |
| # if: always() # Раскомментируйте, если нужно мержить даже при падении build-and-upload | |
| steps: | |
| - name: Checkout main branch | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: main | |
| fetch-depth: 0 # Нужна полная история для merge | |
| - name: Merge tag into main | |
| run: | | |
| git config user.name github-actions[bot] | |
| git config user.email 41898282+github-actions[bot]@users.noreply.github.com | |
| echo "Attempting to merge tag ${{ needs.prepare-release.outputs.tag_name }} into main" | |
| # Используем --no-ff для явного коммита слияния | |
| git merge ${{ needs.prepare-release.outputs.tag_name }} --no-ff -m "Merge tag ${{ needs.prepare-release.outputs.tag_name }} into main" | |
| git push origin main |