feat(installers): Add Installer building workflow (#237)
Release workflow / Build Zip (push) Has been cancelled
Release workflow / deploy-installers (push) Has been cancelled

* New workflows for installer

* versioning

* installers test

* echo version

* echo again

* test21

* set version env

* Extensions manifest

* Add old bl_info

* fixed mistake

* removal of workspace

* Test end to end

* test envar cleanup

* main
This commit is contained in:
Jedd Morgan
2025-04-02 12:33:39 +01:00
committed by GitHub
parent 8df7559e76
commit 0add4fabec
9 changed files with 176 additions and 85 deletions
-12
View File
@@ -1,12 +0,0 @@
name: Update issue Status
on:
issues:
types: [closed]
jobs:
update_issue:
uses: specklesystems/github-actions/.github/workflows/project-add-issue.yml@main
secrets: inherit
with:
issue-id: ${{ github.event.issue.node_id }}
-12
View File
@@ -1,12 +0,0 @@
name: Move new issues into Project
on:
issues:
types: [opened]
jobs:
track_issue:
uses: specklesystems/github-actions/.github/workflows/project-add-issue.yml@main
secrets: inherit
with:
issue-id: ${{ github.event.issue.node_id }}
+31
View File
@@ -0,0 +1,31 @@
name: "PR workflow"
on:
pull_request:
branches:
- "v3-dev"
jobs:
build:
name: Pre-commit Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv and set the python version
uses: astral-sh/setup-uv@v5
with:
python-version: "3.11"
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Install the project
run: uv sync --all-extras --dev
# - uses: actions/cache@v3
# with:
# path: ~/.cache/pre-commit/
# key: ${{ hashFiles('.pre-commit-config.yaml') }}
# - name: Run pre-commit
# run: uv run pre-commit run --all-files
- name: Minimize uv cache
run: uv cache prune --ci
+91
View File
@@ -0,0 +1,91 @@
name: "Release workflow"
on:
push:
branches: ["main", "installer-test/**"]
tags: ["v3.*.*"]
jobs:
build:
name: Build Zip
runs-on: ubuntu-latest
env:
ZIP_NAME: "blender.zip"
SEMVER: null
FILE_VERSION: null
outputs:
semver: ${{ steps.set-version.outputs.semver }}
fileVersion: ${{ steps.set-version.outputs.fileVersion }}
steps:
- uses: actions/checkout@v4
- name: 🐍 Install uv and set the python version
uses: astral-sh/setup-uv@v5
with:
python-version: "3.11"
enable-cache: true
cache-dependency-glob: "uv.lock"
- id: set-version
name: Set version to output
run:
| # Processing the ref manually atm.. likely we'll want to use Adam's fancy logic at some point instead
TAG=${{ github.ref_name }}
if [[ "${{ github.ref }}" != refs/tags/* ]]; then
TAG="3.0.99.${{ github.run_number }}"
fi
SEMVER=$(echo "$TAG" | sed -E 's/\/[a-zA-Z-]+//')
FILE_VERSION=$(echo "$TAG" | sed -E 's/^v([0-9]+)\.([0-9]+)\.([0-9]+)(-[a-zA-Z]+\.([0-9]+))?/\1.\2.\3.\5/' | sed 's/\.$/.0/')
echo "semver=$SEMVER" >> "$GITHUB_OUTPUT"
echo "fileVersion=$FILE_VERSION" >> "$GITHUB_OUTPUT"
echo $SEMVER
echo $FILE_VERSION
- name: ✏ Patch Version
run: python patch_version.py ${{ steps.set-version.outputs.fileVersion }}
- name: 🔄 UV Sync
run: uv sync --all-extras --dev
- name: 📄 Export Package Dependencies
run: ./export_dependencies.sh
- name: 🗃 Zip Package
run: zip -r ${{env.ZIP_NAME}} bpy_speckle
- name: ⬆️ Upload artifacts
uses: actions/upload-artifact@v4
with:
name: output-${{ steps.set-version.outputs.semver }}
path: ${{env.ZIP_NAME}}
if-no-files-found: error
retention-days: 1
compression-level: 0 # no compression
- name: 💾 Minimize uv cache
run: uv cache prune --ci
deploy-installers:
runs-on: ubuntu-latest
needs: build
env:
IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
IS_RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'installer-test/') || github.ref_name == 'main'}}
steps:
- name: 🔫 Trigger Build Installer(s)
uses: ALEEF02/workflow-dispatch@v3.0.0
with:
workflow: Build Blender Installer
repo: specklesystems/connector-installers
token: ${{ secrets.CONNECTORS_GH_TOKEN }}
inputs: '{ "run_id": "${{ github.run_id }}", "semver": "${{ needs.build.outputs.semver }}", "file_version": "${{ needs.build.outputs.fileVersion }}","public_release": ${{ env.IS_TAG_BUILD }}, "store_artifacts": ${{ env.IS_RELEASE_BRANCH }} }'
ref: main
wait-for-completion: true
wait-for-completion-interval: 10s
wait-for-completion-timeout: 10m
display-workflow-run-url: true
display-workflow-run-url-interval: 10s
- uses: geekyeggo/delete-artifact@v5
with:
name: output-*
+12 -1
View File
@@ -12,7 +12,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ruff: noqa
import bpy
from bpy.props import PointerProperty, CollectionProperty, StringProperty, IntProperty, IntVectorProperty
from .connector.ui import icons
import json
@@ -20,6 +19,18 @@ import json
from .installer import ensure_dependencies
ensure_dependencies(f"Blender {bpy.app.version[0]}.{bpy.app.version[1]}")
bl_info = {
"name": "Speckle Blender ",
"author": "Speckle Systems",
"version": (3, 999, 999),
"blender": (4, 2, 0),
"location": "3d viewport toolbar (N), under the Speckle tab.",
"description": "The Speckle Connector using specklepy 3.x!",
"warning": "This add-on is WIP and should be used with caution",
"wiki_url": "https://github.com/specklesystems/speckle-blender",
"category": "Scene",
}
# UI
from .connector.ui.main_panel import SPECKLE_PT_main_panel
+16 -17
View File
@@ -6,7 +6,7 @@ id = "speckle_blender_addon"
version = "3.0.0"
name = "Speckle for Blender BETA"
tagline = "Speckle connector for Blender"
maintainer = "Speckle Systems"
maintainer = "AEC SYSTEMS LTD"
# Supported types: "add-on", "theme"
type = "add-on"
@@ -28,10 +28,9 @@ license = [
"SPDX:Apache-2.0",
]
# Optional: required by some licenses.
# copyright = [
# "2002-2024 Developer Name",
# "1998 Company Name",
# ]
copyright = [
"2022-2025 AEC SYSTEMS LTD",
]
# Optional list of supported platforms. If omitted, the extension will be available in all operating systems.
# platforms = ["windows-x64", "macos-arm64", "linux-x64"]
@@ -50,9 +49,9 @@ license = [
# * clipboard (to read and/or write the system clipboard)
# * camera (to capture photos and videos)
# * microphone (to capture audio)
# permissions = ["network"]
# permissions = ["files", "network", "clipboard"]
#
# If using network, remember to also check `bpy.app.online_access`
# https://docs.blender.org/manual/en/dev/advanced/extensions/addons.html#internet-access
#
@@ -60,16 +59,16 @@ license = [
# Keep this a single short sentence without a period (.) at the end.
# For longer explanations use the documentation or detail page.
#
# [permissions]
# network = "Need to sync motion-capture data to server"
# files = "Import/export FBX from/to disk"
# clipboard = "Copy and paste bone transforms"
[permissions]
network = "Speckle Server comms, and PyPI for dependency management"
files = "Data caching, Account Management, Python dependency management"
clipboard = "Copy and paste URLs and Names (UI)"
# Optional: build settings.
# https://docs.blender.org/manual/en/dev/advanced/extensions/command_line_arguments.html#command-line-args-extension-build
# [build]
# paths_exclude_pattern = [
# "__pycache__/",
# "/.git/",
# "/*.zip",
# ]
[build]
paths_exclude_pattern = [
"__pycache__/",
"/.vscode",
"*.code-workspace",
]
@@ -1,14 +0,0 @@
{
"folders": [
{
"path": ".."
},
{
"name": "speckle_blender_addon",
"path": "."
}
],
"settings": {
"blender.addon.loadDirectory": "auto"
}
}
-20
View File
@@ -1,20 +0,0 @@
import sys
from pathlib import Path
def patch_installer(tag: str):
"""Patches the installer with the correct connector version and specklepy version"""
tag = tag.replace("\n", "")
iss_file = "speckle-sharp-ci-tools/blender.iss"
iss_path = Path(iss_file)
lines = iss_path.read_text().split("\n")
lines.insert(12, f'#define AppVersion "{tag.split("-")[0]}"')
lines.insert(13, f'#define AppInfoVersion "{tag}"')
iss_path.write_text("\n".join(lines))
print(f"Patched installer with connector v{tag}")
if __name__ == "__main__":
tag = sys.argv[1]
patch_installer(tag)
+26 -9
View File
@@ -1,21 +1,36 @@
import re
import sys
def patch_connector(tag):
"""Patches the connector version within the connector init file"""
bpy_file = "bpy_speckle/__init__.py"
tag = tag.split(".")
def patch_addon(simple_version: str):
"""Patches the __init__.py bl_info version within the connector init file"""
FILE_PATH = "bpy_speckle/__init__.py"
version = simple_version.split(".")
with open(bpy_file, "r") as file:
with open(FILE_PATH, "r") as file:
lines = file.readlines()
for (index, line) in enumerate(lines):
if '"version":' in line:
lines[index] = f' "version": ({tag[0]}, {tag[1]}, {tag[2]}),\n'
print(f"Patched connector version number in {bpy_file}")
lines[index] = f' "version": ({version[0]}, {version[1]}, {version[2]}),\n'
with open(FILE_PATH, "w") as file:
file.writelines(lines)
def patch_manifest(simple_version: str):
"""Patches the connector version within the connector init file"""
FILE_PATH = "bpy_speckle/blender_manifest.toml"
version = simple_version.split(".")
with open(FILE_PATH, "r") as file:
lines = file.readlines()
for (index, line) in enumerate(lines):
if line.startswith('version ='):
lines[index] = f'version = "{version[0]}.{version[1]}.{version[2]}",\n'
print(f"Patched connector version number in {FILE_PATH}")
break
with open(bpy_file, "w") as file:
with open(FILE_PATH, "w") as file:
file.writelines(lines)
def main():
@@ -24,7 +39,9 @@ def main():
raise ValueError(f"Invalid tag provided: {tag}")
print(f"Patching version: {tag}")
patch_connector(tag.split("-")[0])
simple_version = tag.split("-")[0]
patch_addon(simple_version)
patch_manifest(simple_version)
if __name__ == "__main__":