Skip to content

Commit 992703d

Browse files
authored
ci: add workflow for building release artifacts (#1779)
1 parent 46e3e02 commit 992703d

5 files changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: pyOCD Release Builds
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
workflow_dispatch:
8+
9+
jobs:
10+
build_artifacts:
11+
name: Build for ${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [windows-latest, ubuntu-latest, macos-latest, ubuntu-24.04-arm]
17+
include:
18+
- os: windows-latest
19+
artifact_name: pyocd-windows
20+
- os: ubuntu-latest
21+
artifact_name: pyocd-linux
22+
- os: macos-latest
23+
artifact_name: pyocd-macos
24+
- os: ubuntu-24.04-arm
25+
artifact_name: pyocd-linux-arm64
26+
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
31+
- name: Setup Python
32+
uses: actions/setup-python@v5
33+
with:
34+
python-version: '3.11'
35+
cache: 'pip'
36+
37+
- name: Install packages
38+
run: pip install . build twine pyinstaller
39+
40+
- name: Build wheel and source distribution
41+
run: python -m build
42+
43+
- name: Check distribution files
44+
run: twine check dist/*
45+
46+
- name: Setup build environment
47+
run: python get_site-packages.py
48+
49+
- name: Verify environment
50+
run: |
51+
echo "Site packages: ${{ env.SITE_PACKAGES }}"
52+
python -c "import sys; print(sys.version)"
53+
54+
- name: Build with PyInstaller
55+
run: pyinstaller pyocd.spec --log-level=ERROR --clean
56+
57+
- name: Test binary
58+
run: |
59+
./dist/pyocd/pyocd --version
60+
./dist/pyocd/pyocd --help
61+
62+
- name: Upload PyInstaller artifacts
63+
uses: actions/upload-artifact@v4
64+
with:
65+
name: ${{ matrix.artifact_name }}
66+
path: dist/pyocd/*
67+
retention-days: 7
68+
69+
- name: Upload distribution artifacts
70+
uses: actions/upload-artifact@v4
71+
if: matrix.os == 'ubuntu-latest'
72+
with:
73+
name: pyocd-distribution
74+
path: |
75+
dist/*.whl
76+
dist/*.tar.gz
77+
retention-days: 7

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ lib
3030
lib64
3131
__pycache__
3232
*.spec
33+
!pyocd.spec
3334

3435
# Installer logs
3536
pip-log.txt

get_site-packages.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# pyOCD debugger
2+
# Copyright (c) 2025 Arm Limited
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import os
18+
import sysconfig
19+
20+
def get_site_packages() -> str:
21+
"""Get the path to the site-packages directory."""
22+
path = sysconfig.get_path('purelib')
23+
if not path:
24+
raise RuntimeError("Could not determine site-packages directory")
25+
return path
26+
27+
def main() -> None:
28+
site_packages = get_site_packages()
29+
# Check if running in GitHub Actions
30+
github_env = os.getenv('GITHUB_ENV')
31+
32+
if github_env:
33+
# If running in GitHub Actions, write to GITHUB_ENV
34+
with open(github_env, "a") as env_file:
35+
env_file.write(f"SITE_PACKAGES={site_packages}\n")
36+
else:
37+
# If not running in GitHub Actions, print the path
38+
print(f"SITE_PACKAGES={site_packages}")
39+
40+
if __name__ == "__main__":
41+
main()

pyocd.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# pyOCD debugger
2+
# Copyright (c) 2025 Arm Limited
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
from pyocd.__main__ import main
18+
19+
if __name__ == '__main__':
20+
main()

pyocd.spec

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# --- Imports ---
2+
import os
3+
import sys
4+
from PyInstaller.utils.hooks import get_package_paths, collect_entry_point, collect_dynamic_libs
5+
6+
# --- Configuration ---
7+
SITE_PACKAGES = os.getenv('SITE_PACKAGES', '')
8+
APP_NAME = 'pyocd'
9+
DEBUG = False
10+
11+
# --- Entry Points ---
12+
datas_probe, hiddenimports_probe = collect_entry_point('pyocd.probe')
13+
datas_rtos, hiddenimports_rtos = collect_entry_point('pyocd.rtos')
14+
15+
# --- Data Files ---
16+
datas = [
17+
(get_package_paths('pyocd')[1], 'pyocd'),
18+
(get_package_paths('pylink')[1], 'pylink'),
19+
('pyocd/debug/sequences/sequences.lark', 'pyocd/debug/sequences'),
20+
('pyocd/debug/svd/svd_data.zip', 'pyocd/debug/svd')
21+
]
22+
datas.append((get_package_paths('cmsis_pack_manager')[1], 'cmsis_pack_manager'))
23+
24+
# --- Analysis Configuration ---
25+
a = Analysis(
26+
['pyocd.py'],
27+
pathex=[],
28+
binaries=collect_dynamic_libs('cmsis_pack_manager') + collect_dynamic_libs('libusb_package'),
29+
datas=datas + datas_probe + datas_rtos,
30+
hiddenimports=hiddenimports_probe + hiddenimports_rtos,
31+
excludes=['tkinter'],
32+
runtime_hooks=[],
33+
cipher=None,
34+
noarchive=False
35+
)
36+
37+
# --- Build Components ---
38+
pyz = PYZ(a.pure, a.zipped_data)
39+
40+
exe = EXE(
41+
pyz,
42+
a.scripts,
43+
[], # Empty list for directory build
44+
exclude_binaries=True,
45+
name=APP_NAME,
46+
debug=DEBUG,
47+
strip=False,
48+
upx=True,
49+
console=True
50+
)
51+
52+
# --- Output Collection ---
53+
coll = COLLECT(
54+
exe,
55+
a.binaries,
56+
a.zipfiles,
57+
a.datas,
58+
strip=False,
59+
upx=True,
60+
name=APP_NAME
61+
)

0 commit comments

Comments
 (0)