1+ # .github/workflows/cd.yml
12name : TreeMapper CD
23
34permissions :
4- contents : write
5+ contents : write # Нужно для создания релиза, коммита, тега и merge
56
67on :
78 workflow_dispatch :
89 inputs :
910 version :
10- description : ' Version to release'
11+ description : ' Version to release (e.g., 1.0.0) '
1112 required : true
1213 publish_to_pypi :
1314 description : ' Publish to PyPI'
@@ -19,191 +20,197 @@ on:
1920 - ' false'
2021
2122jobs :
22- create-release :
23- name : Create GitHub Release
23+ # --- 1. Подготовка: Установка версии, коммит, пуш, создание релиза/тега ---
24+ prepare-release :
25+ name : Prepare Commit and Create GitHub Release/Tag # Название изменено для ясности
2426 runs-on : ubuntu-latest
27+ outputs :
28+ version : ${{ steps.set_outputs.outputs.version }}
29+ tag_name : ${{ steps.set_outputs.outputs.tag_name }}
30+ commit_sha : ${{ steps.commit_push.outputs.commit_sha }} # Выводим SHA
31+ upload_url : ${{ steps.create_release.outputs.upload_url }}
32+ release_id : ${{ steps.create_release.outputs.id }}
2533 steps :
2634 - name : Checkout Code
27- uses : actions/checkout@v3
35+ uses : actions/checkout@v4
2836
2937 - name : Set up Python
30- uses : actions/setup-python@v4
38+ uses : actions/setup-python@v5
3139 with :
3240 python-version : ' 3.11'
3341
34- - name : Install Dependencies
35- run : |
36- python -m pip install --upgrade pip
37- pip install -r requirements.txt
38- pip install -e .
39-
40- - name : Set version (Unix)
41- if : matrix.os != 'windows-latest'
42+ - name : Set version in version.py
4243 run : |
43- python -c "import re; content = open('src/treemapper/version.py', 'r').read(); open('src/treemapper/version.py', 'w').write(re.sub('__version__ = \".*\"', '__version__ = \"${{ github.event.inputs.version }}\"', content))"
44-
45- - name : Set version (Windows)
46- if : matrix.os == 'windows-latest'
47- shell : pwsh
44+ VERSION="${{ github.event.inputs.version }}"
45+ echo "Setting version to $VERSION"
46+ sed -i -E "s/__version__ = \".*\"/__version__ = \"$VERSION\"/" src/treemapper/version.py
47+ echo "version.py content after change:"
48+ cat src/treemapper/version.py
49+
50+ # ---> ИЗМЕНЕНИЕ: Коммит и PUSH только коммита, получение SHA <---
51+ - name : Commit and Push version bump
52+ id : commit_push # Добавляем id шагу
4853 run : |
49- $content = Get-Content src/treemapper/version.py -Raw
50- $newContent = $content -replace '__version__ = ".*"', '__version__ = "${{ github.event.inputs.version }}"'
51- Set-Content src/treemapper/version.py -Value $newContent
52-
53- - name : Create Release
54+ git config user.name github-actions[bot]
55+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
56+ git add src/treemapper/version.py
57+ # Коммитим только если есть изменения
58+ if ! git diff --staged --quiet; then
59+ git commit -m "Release version ${{ github.event.inputs.version }}"
60+ else
61+ echo "No changes to commit."
62+ fi
63+ # Получаем SHA последнего коммита (либо нового, либо существующего)
64+ COMMIT_SHA=$(git rev-parse HEAD)
65+ echo "Commit SHA: $COMMIT_SHA"
66+ echo "commit_sha=$COMMIT_SHA" >> $GITHUB_OUTPUT
67+ # Отправляем коммит в ту ветку, на которой запущен workflow
68+ git push origin HEAD
69+
70+ # ---> ИЗМЕНЕНИЕ: Создание релиза И ТЕГА через action, используя SHA <---
71+ - name : Create GitHub Release and Tag
5472 id : create_release
5573 uses : actions/create-release@v1
5674 env :
5775 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
5876 with :
59- tag_name : v${{ github.event.inputs.version }}
77+ tag_name : v${{ github.event.inputs.version }} # Action создаст этот тег
6078 release_name : Release ${{ github.event.inputs.version }}
79+ commitish : ${{ steps.commit_push.outputs.commit_sha }} # <--- Используем SHA коммита
6180 draft : false
6281 prerelease : false
6382
64- outputs :
65- upload_url : ${{ steps.create_release.outputs.upload_url }}
66- version : ${{ github.event.inputs.version }}
67- release_id : ${{ steps.create_release.outputs.id }}
83+ - name : Set outputs for subsequent jobs
84+ id : set_outputs
85+ run : |
86+ echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
87+ echo "tag_name=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
88+ # SHA коммита уже установлен шагом commit_push
6889
90+ # --- 2. Сборка и загрузка ассетов для разных ОС (без изменений) ---
6991 build-and-upload :
7092 name : Build and Upload Assets
71- needs : create-release
72- runs-on : ${{ matrix.os }}
93+ needs : prepare-release
7394 strategy :
95+ fail-fast : false
7496 matrix :
7597 include :
76- - os : ubuntu-20.04
98+ - os : ubuntu-latest
7799 asset_name : linux
100+ python-version : ' 3.11'
78101 - os : macos-latest
79102 asset_name : macos
103+ python-version : ' 3.11'
80104 - os : windows-latest
81105 asset_name : windows
106+ python-version : ' 3.11'
107+ runs-on : ${{ matrix.os }}
82108 steps :
83- - name : Checkout Code
84- uses : actions/checkout@v3
109+ - name : Checkout Code at release tag
110+ uses : actions/checkout@v4
111+ with :
112+ ref : ${{ needs.prepare-release.outputs.tag_name }} # Скачиваем код по тегу (который создаст action)
85113
86114 - name : Set up Python
87- uses : actions/setup-python@v4
115+ uses : actions/setup-python@v5
88116 with :
89- python-version : ' 3.11 '
117+ python-version : ${{ matrix.python-version }}
90118
91119 - name : Cache pip Dependencies
92- uses : actions/cache@v3
120+ uses : actions/cache@v4
121+ id : cache-pip
93122 with :
94123 path : ~/.cache/pip
95- key : ${{ runner.os }}-pip-${{ hashFiles('**/setup.cfg') }}
124+ key : ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/setup.cfg') }}
96125 restore-keys : |
126+ ${{ runner.os }}-pip-${{ matrix.python-version }}-
97127 ${{ runner.os }}-pip-
98128
99- - name : Install Dependencies
129+ - name : Install Dependencies (including PyInstaller)
100130 run : |
101131 python -m pip install --upgrade pip
102- pip install -r requirements.txt
103- pip install -e .
104-
105- - name : Set version (Unix)
106- if : matrix.os != 'windows-latest'
107- run : |
108- python -c "import re; content = open('src/treemapper/version.py', 'r').read(); open('src/treemapper/version.py', 'w').write(re.sub('__version__ = \".*\"', '__version__ = \"${{ github.event.inputs.version }}\"', content))"
109-
110- - name : Set version (Windows)
111- if : matrix.os == 'windows-latest'
112- shell : pwsh
113- run : |
114- $content = Get-Content src/treemapper/version.py -Raw
115- $newContent = $content -replace '__version__ = ".*"', '__version__ = "${{ github.event.inputs.version }}"'
116- Set-Content src/treemapper/version.py -Value $newContent
132+ pip install .[dev]
117133
118134 - name : Build with PyInstaller
119135 run : |
120- python -m PyInstaller --clean -y --dist ./dist/${{ matrix.asset_name }} --workpath /tmp treemapper.spec
136+ python -m PyInstaller --clean -y --dist ./dist/${{ matrix.asset_name }} treemapper.spec
121137
122138 - name : Determine architecture
123139 id : arch
124140 shell : bash
125141 run : |
126- if [ "${{ matrix.os }}" = "macos-latest" ]; then
127- echo "ARCH=$(uname -m)" >> $GITHUB_OUTPUT
128- elif [ "${{ matrix.os }}" = "ubuntu-20.04" ]; then
129- echo "ARCH=$(uname -m)" >> $GITHUB_OUTPUT
130- else
131- echo "ARCH=x86_64" >> $GITHUB_OUTPUT
142+ ARCH=$(uname -m)
143+ if [[ "${{ runner.os }}" == "Windows" ]]; then
144+ if [[ "${{ runner.arch }}" == "X64" ]]; then ARCH="x86_64"; \
145+ elif [[ "${{ runner.arch }}" == "ARM64" ]]; then ARCH="arm64"; \
146+ else ARCH="unknown"; fi
147+ elif [[ "${{ runner.os }}" == "macOS" ]] && [[ "$ARCH" == "arm64" ]]; then
148+ echo "Detected ARM on macOS"
132149 fi
150+ echo "Determined ARCH: $ARCH"
151+ echo "arch=$ARCH" >> $GITHUB_OUTPUT
152+
133153
134154 - name : Upload Release Asset
135155 uses : actions/upload-release-asset@v1
136156 env :
137157 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
138158 with :
139- upload_url : ${{ needs.create -release.outputs.upload_url }}
140- asset_path : ./dist/${{ matrix.asset_name }}/treemapper${{ matrix.os == 'windows-latest' && '.exe' || '' }}
141- asset_name : treemapper-${{ matrix.asset_name }}-${{ steps.arch.outputs.ARCH }}-v${{ needs.create -release.outputs.version }}${{ matrix.os == 'windows-latest' && '.exe' || '' }}
159+ upload_url : ${{ needs.prepare -release.outputs.upload_url }}
160+ asset_path : ./dist/${{ matrix.asset_name }}/treemapper/ ${{ matrix.os == 'windows-latest' && 'treemapper .exe' || 'treemapper ' }}
161+ asset_name : treemapper-${{ matrix.asset_name }}-${{ steps.arch.outputs.arch }}-v${{ needs.prepare -release.outputs.version }}${{ matrix.os == 'windows-latest' && '.exe' || '' }}
142162 asset_content_type : application/octet-stream
143163
164+ # --- 3. Публикация на PyPI (без изменений) ---
144165 publish-to-pypi :
145166 name : Publish to PyPI
146- needs : [ create -release, build-and-upload ]
167+ needs : [prepare -release, build-and-upload]
147168 if : github.event.inputs.publish_to_pypi == 'true'
148169 runs-on : ubuntu-latest
170+ environment :
171+ name : pypi
172+ url : https://pypi.org/p/treemapper
173+ permissions :
174+ id-token : write
149175 steps :
150- - name : Checkout Code
151- uses : actions/checkout@v3
176+ - name : Checkout Code at release tag
177+ uses : actions/checkout@v4
178+ with :
179+ ref : ${{ needs.prepare-release.outputs.tag_name }}
152180
153181 - name : Set up Python
154- uses : actions/setup-python@v4
182+ uses : actions/setup-python@v5
155183 with :
156184 python-version : ' 3.11'
157185
158- - name : Cache pip Dependencies
159- uses : actions/cache@v3
160- with :
161- path : ~/.cache/pip
162- key : ${{ runner.os }}-pip-${{ hashFiles('**/setup.cfg') }}
163- restore-keys : |
164- ${{ runner.os }}-pip-
165-
166- - name : Install Dependencies
186+ - name : Install build tools
167187 run : |
168188 python -m pip install --upgrade pip
169- pip install -r requirements.txt
170-
171- - name : Set version (Unix)
172- if : matrix.os != 'windows-latest'
173- run : |
174- python -c "import re; content = open('src/treemapper/version.py', 'r').read(); open('src/treemapper/version.py', 'w').write(re.sub('__version__ = \".*\"', '__version__ = \"${{ github.event.inputs.version }}\"', content))"
189+ pip install build
175190
176- - name : Set version (Windows)
177- if : matrix.os == 'windows-latest'
178- shell : pwsh
179- run : |
180- $content = Get-Content src/treemapper/version.py -Raw
181- $newContent = $content -replace '__version__ = ".*"', '__version__ = "${{ github.event.inputs.version }}"'
182- Set-Content src/treemapper/version.py -Value $newContent
183-
184- - name : Build and Publish to PyPI
185- env :
186- TWINE_USERNAME : __token__
187- TWINE_PASSWORD : ${{ secrets.PYPI_TOKEN }}
188- run : |
189- python -m build
190- python -m twine upload dist/* --verbose
191+ - name : Build sdist and wheel
192+ run : python -m build
191193
194+ - name : Publish package distributions to PyPI
195+ uses : pypa/gh-action-pypi-publish@release/v1
192196
197+ # --- 4. Обновление ветки main (без изменений) ---
193198 update-main-branch :
194- name : Update main branch
195- needs : [ publish-to-pypi ]
199+ name : Update main branch (Merge Tag)
200+ needs : [prepare-release, build-and-upload ]
196201 runs-on : ubuntu-latest
202+ # if: always() # Раскомментируйте, если нужно мержить всегда
197203 steps :
198204 - name : Checkout main branch
199- uses : actions/checkout@v3
205+ uses : actions/checkout@v4
200206 with :
201207 ref : main
202208 fetch-depth : 0
203209
204210 - name : Merge tag into main
205211 run : |
206- git config user.name github-actions
207- git config user.email [email protected] 208- git merge ${{ github.ref }} --no-ff -m "Merge tag ${{ github.ref_name }} into main"
209- git push origin main
212+ git config user.name github-actions[bot]
213+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
214+ echo "Attempting to merge tag ${{ needs.prepare-release.outputs.tag_name }} into main"
215+ git merge ${{ needs.prepare-release.outputs.tag_name }} --no-ff -m "Merge tag ${{ needs.prepare-release.outputs.tag_name }} into main"
216+ git push origin main
0 commit comments