-
Notifications
You must be signed in to change notification settings - Fork 8
231 lines (205 loc) · 9.8 KB
/
Copy pathrelease.yml
File metadata and controls
231 lines (205 loc) · 9.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
name: Release and Publish
# Trigger on pushes to tags matching v* (e.g., v1.0, v0.2.1, v1.2.3-rc1)
on:
push:
tags:
- 'v*' # Matches v, vX, vX.Y, vX.Y.Z and pre-release variants
workflow_dispatch: # Allows manual triggering
jobs:
# Combined job for macOS, Windows, and Linux (manylinux) builds using cibuildwheel
build_wheels:
# Job name includes the platform from the matrix for clarity in the UI
name: Build Wheels (${{ matrix.platform }})
# Strategy defines the different platform configurations to run
strategy:
matrix:
# Use 'include' to define specific combinations for each platform
include:
- platform: macos # cibuildwheel platform identifier
os: macos-latest # GitHub Actions runner OS
- platform: windows # cibuildwheel platform identifier
os: windows-latest # GitHub Actions runner OS
- platform: linux # cibuildwheel platform identifier (builds manylinux)
os: ubuntu-latest # GitHub Actions runner OS (runs Docker)
fail-fast: false # Don't cancel all jobs if one platform fails
# Runner OS is determined by the matrix strategy
runs-on: ${{ matrix.os }}
steps:
# Step 1: Checkout main repository ONLY using default GITHUB_TOKEN
# Submodules handled manually later for consistent SSH key usage
- name: Check out main repository
uses: actions/checkout@v4
with:
submodules: false
# Step 2: Set up SSH access for private submodule (Bash version)
- name: Set up SSH access for private submodule (Bash)
shell: bash
run: |
mkdir -p ~/.ssh
# Decode if Base64 encoded, otherwise echo directly. Assuming direct key content for now.
echo "${{ secrets.SUBMODULE_DEPLOY_KEY }}" | tr -d '\r' > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan github.com >> ~/.ssh/known_hosts
echo "SSH key setup complete."
# Add a verification step: Try to load the key fingerprint
echo "Verifying key load..."
ssh-keygen -l -f ~/.ssh/id_ed25519 || (echo "ERROR: Failed to load key fingerprint. Key format in secret is likely invalid." && exit 1)
echo "Key loaded successfully by ssh-keygen."
# Step 3: Configure Git to use SSH instead of HTTPS for GitHub
# Using bash shell (available on all runners via Git Bash on Windows)
- name: Configure Git to use SSH for github.com
run: git config --global url."git@github.com:".insteadOf "https://github.com/"
shell: bash
# Step 4: Initialize and update submodules manually using SSH
# Using bash shell
- name: Initialize submodules
run: |
git submodule sync --recursive
git submodule update --init --recursive
shell: bash
# Source code including the private submodule is now fully checked out
# Step 5: Set up Python (just need one version to run cibuildwheel itself)
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Step 6: Install cibuildwheel
- name: Install cibuildwheel
run: python -m pip install --upgrade pip cibuildwheel
# Step 7: Build wheels using cibuildwheel
# Configuration (Python versions, archs, env vars) should be read from pyproject.toml
# The specific platform (linux, macos, windows) is passed from the matrix include definition
- name: Build wheels for ${{ matrix.platform }}
# env:
# CIBW_BEFORE_BUILD: "pip install numpy --force-reinstall --no-cache-dir" # maybe not needed
run: cibuildwheel --platform ${{ matrix.platform }}
# IMPORTANT: Make sure your pyproject.toml has the [tool.cibuildwheel] section
# configured correctly for all platforms, including Python versions ('build=' key),
# architectures ('archs=' key), and any necessary environment variables
# (using [tool.cibuildwheel.environment] or platform-specific sections like
# [tool.cibuildwheel.linux.environment], etc. for CMAKE_CXX_STANDARD etc.).
# Step 8: Upload wheels artifact
# cibuildwheel output is in './wheelhouse' by default
- name: Upload wheels (${{ matrix.platform }})
uses: actions/upload-artifact@v4
with:
# Name the artifact based on the platform from the matrix
# This artifact will contain wheels for all Python versions built for this platform
name: wheels-${{ matrix.platform }}
path: ./wheelhouse
# --- Job to Publish to TestPyPI ---
publish-testpypi:
name: Publish to TestPyPI
needs: build_wheels # Run after wheels are built
runs-on: ubuntu-latest
# Define environment linked to TestPyPI trusted publishing config
environment:
name: test-pypi # MUST match the environment name configured in TestPyPI trusted publishing
url: https://test.pypi.org/p/bitepy # Link to your project on TestPyPI (replace 'bite' if needed)
permissions:
id-token: write # Allow workflow to get OIDC ID token for PyPI
contents: read # Allow checkout if needed (though not strictly required by pypi-publish)
# Condition: Only run on pre-release tags (containing a hyphen, e.g., v1.0.0-rc1) or manual workflow dispatch
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, '-'))
steps:
- name: Download all wheel artifacts
uses: actions/download-artifact@v4
with:
# Download all artifacts matching the pattern into 'dist' directory
pattern: wheels-*
path: dist
merge-multiple: true # Combine contents if artifacts have same name (shouldn't happen here)
- name: List downloaded wheels
run: ls -R dist/
- name: Publish package to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
# No API token needed - uses OIDC via id-token permission and environment
with:
# repository_url defaults to PyPI, explicitly set for TestPyPI
repository_url: https://test.pypi.org/legacy/
# skip_existing: true # Optional: uncomment to prevent errors if version already exists
#--- Job to Publish to PyPI (Optional - Uncomment and configure carefully) ---
publish-pypi:
name: Publish to PyPI
needs: build_wheels # Run after wheels are built
runs-on: ubuntu-latest
# Define environment linked to PyPI trusted publishing config
environment:
name: pypi # MUST match the environment name configured in PyPI trusted publishing
url: https://pypi.org/p/bitepy # Link to your project on PyPI (replace 'bite' if needed)
permissions:
id-token: write # Allow workflow to get OIDC ID token for PyPI
contents: read
# Condition: Only run on tags that DO NOT contain a hyphen (e.g., v1.0.0, not v1.0.0-rc1)
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-')
steps:
- name: Download all wheel artifacts
uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist
merge-multiple: true
- name: List downloaded wheels
run: ls -R dist/
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
# repository_url defaults to PyPI, no need to set it here
# --- Job to Create GitHub Release ---
create-github-release:
name: Create GitHub Release
needs: build_wheels # Run after wheels are built
runs-on: ubuntu-latest
permissions:
contents: write # Need write access to create release and upload assets
steps:
# STEP 1: Checkout the repository code FIRST
- name: Checkout repository
uses: actions/checkout@v4 # Or latest version
with:
# Fetch all history so --generate-notes can determine changes
# since the last release.
fetch-depth: 0
# STEP 2: Download artifacts (can happen after checkout)
- name: Download all wheel artifacts
uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist
merge-multiple: true
- name: List downloaded wheels
run: ls -R dist/
- name: Check if release already exists
id: check_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
run: |
echo "Checking if release already exists for tag ${TAG_NAME}"
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
echo "Release ${TAG_NAME} already exists, skipping creation"
echo "release_exists=true" >> $GITHUB_OUTPUT
else
echo "Release ${TAG_NAME} does not exist, will create"
echo "release_exists=false" >> $GITHUB_OUTPUT
fi
- name: Create GitHub Release and Upload Assets
if: steps.check_release.outputs.release_exists == 'false'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Ensure this workflow is triggered by a tag push, otherwise
# github.ref_name might be 'main' or a branch name.
TAG_NAME: ${{ github.ref_name }}
run: |
echo "Creating release for tag ${TAG_NAME}"
# Set --prerelease flag if tag name contains a hyphen (e.g., -rc, -alpha, -beta)
PRE_RELEASE_FLAG=""
if [[ "$TAG_NAME" == *"-"* ]]; then
PRE_RELEASE_FLAG="--prerelease"
echo "Marking as pre-release."
fi
# Create release using GitHub CLI, auto-generate notes, upload all wheels
gh release create "$TAG_NAME" \
--title "Release ${TAG_NAME}" \
--generate-notes \
$PRE_RELEASE_FLAG \
dist/*.whl # Upload all downloaded wheels