Skip to content

Build Installer

Build Installer #68

Workflow file for this run

name: Build Installer
on:
push:
tags:
- 'v*.*.*'
- 'v*.*.*-staging'
workflow_dispatch:
inputs:
version:
description: 'Version (e.g., 1.0.0 or 1.0.0-staging)'
required: false
default: ''
staging:
description: 'Staging build (no server upload)'
type: boolean
default: false
env:
PYREVIT_VERSION: "5.3.1.25308"
PYREVIT_URL: "https://github.com/pyrevitlabs/pyRevit/releases/download/v5.3.1.25308%2B1659/pyRevit_5.3.1.25308_signed.exe"
permissions:
contents: write
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get version
id: version
shell: pwsh
run: |
if ("${{ github.event.inputs.version }}" -ne "") {
$version = "${{ github.event.inputs.version }}"
} elseif ($env:GITHUB_REF -match "refs/tags/v(.+)") {
$version = $matches[1]
} else {
$version = "0.0.1-dev"
}
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
# Determine if this is a staging build
$isStaging = $false
if ("${{ github.event.inputs.staging }}" -eq "true") {
$isStaging = $true
} elseif ($version -match "-staging$") {
$isStaging = $true
}
echo "IS_STAGING=$isStaging" >> $env:GITHUB_OUTPUT
Write-Host "Version: $version, Staging: $isStaging"
- name: Prepare build directory
shell: pwsh
run: |
New-Item -ItemType Directory -Path "build" -Force
Copy-Item -Path "pyrevit.extension" -Destination "build\CPSK.extension" -Recurse
Copy-Item -Path "installer\scripts\*" -Destination "build\" -Force
# Copy requirements.txt, version.yaml and config.py to root (not extension!)
Copy-Item -Path "requirements.txt" -Destination "build\" -Force
Copy-Item -Path "version.yaml" -Destination "build\" -Force
Copy-Item -Path "config.py" -Destination "build\" -Force
- name: Remove dev tools from build
shell: pwsh
run: |
$libDir = "build\CPSK.extension\lib"
# Remove dev tools not needed in production
$devTools = @("pyrevit_checker.py")
foreach ($tool in $devTools) {
$path = Join-Path $libDir $tool
if (Test-Path $path) {
Remove-Item $path -Force
Write-Host "Removed: $tool (dev tool)"
}
}
Write-Host "Files in lib:"
Get-ChildItem $libDir | ForEach-Object { Write-Host " $($_.Name)" }
- name: Set DEBUG=False in config.py
shell: pwsh
run: |
$configFile = "build\config.py"
$content = Get-Content $configFile -Raw -Encoding UTF8
$content = $content -replace 'DEBUG\s*=\s*True', 'DEBUG = False'
[System.IO.File]::WriteAllText($configFile, $content, [System.Text.UTF8Encoding]::new($false))
Write-Host "Set DEBUG = False in config.py"
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Minify Python code
shell: pwsh
run: |
Write-Host "Installing python-minifier..."
pip install python-minifier
$libDir = "build\CPSK.extension\lib"
Write-Host "=== Minifying Python files in $libDir ==="
# Encoding declaration required for IronPython with non-ASCII characters
$encodingDecl = "# -*- coding: utf-8 -*-`n"
# Files to minify (lib modules)
Get-ChildItem "$libDir\*.py" | ForEach-Object {
if ($_.Name -ne "__init__.py") {
$originalSize = $_.Length
Write-Host "Minifying: $($_.Name) ($originalSize bytes)"
# Minify with Python 2 compatible settings (no transforms that could break IronPython)
$tempFile = "$($_.FullName).min"
python -m python_minifier $_.FullName --remove-literal-statements --no-remove-annotations --no-hoist-literals --no-rename-locals --no-convert-posargs-to-args -o $tempFile
if (Test-Path $tempFile) {
# Add encoding declaration back (minifier removes comments)
$content = Get-Content $tempFile -Raw -Encoding UTF8
$content = $encodingDecl + $content
[System.IO.File]::WriteAllText($_.FullName, $content, [System.Text.UTF8Encoding]::new($false))
Remove-Item $tempFile -Force
$newSize = (Get-Item $_.FullName).Length
$reduction = [math]::Round((1 - $newSize / $originalSize) * 100)
Write-Host " [OK] $originalSize -> $newSize bytes (-$reduction%)"
} else {
Write-Host " [WARN] Minification failed, keeping original"
}
}
}
Write-Host "=== Minification complete ==="
- name: Install Inno Setup
shell: pwsh
run: |
choco install innosetup -y
- name: Build Installer
shell: pwsh
run: |
$version = "${{ steps.version.outputs.VERSION }}"
$pyrevitVersion = "${{ env.PYREVIT_VERSION }}"
$pyrevitUrl = "${{ env.PYREVIT_URL }}"
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" `
/DMyAppVersion="$version" `
/DPyRevitVersion="$pyrevitVersion" `
/DPyRevitUrl="$pyrevitUrl" `
/O"." `
"installer\setup.iss"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: CPSK-Tools-Installer
path: "CPSK_Tools_*.exe"
retention-days: 30
- name: Generate release notes
if: startsWith(github.ref, 'refs/tags/')
id: release_notes
shell: pwsh
run: |
# Get commits since last tag
$lastTag = git describe --tags --abbrev=0 HEAD^ 2>$null
if ($lastTag) {
$commits = git log --pretty=format:"- %s" "$lastTag..HEAD" --no-merges | Where-Object { $_ -notmatch "Release v" }
$authors = git log --pretty=format:"%an" "$lastTag..HEAD" --no-merges | Sort-Object -Unique | Where-Object { $_ -ne "github-actions[bot]" }
} else {
$commits = git log --pretty=format:"- %s" -10 --no-merges | Where-Object { $_ -notmatch "Release v" }
$authors = git log --pretty=format:"%an" -10 --no-merges | Sort-Object -Unique | Where-Object { $_ -ne "github-actions[bot]" }
}
$version = "${{ steps.version.outputs.VERSION }}"
# Release notes for server (markdown)
$serverNotes = "## CPSK Tools v$version`n`n"
$serverNotes += "### Изменения`n"
if ($commits) {
$serverNotes += ($commits -join "`n")
} else {
$serverNotes += "- Обновление версии"
}
if ($authors) {
$serverNotes += "`n`n### Авторы`n"
$serverNotes += ($authors | ForEach-Object { "- $_" }) -join "`n"
}
$serverNotes += "`n`n### Требования`n- Windows 10/11`n- Autodesk Revit 2021-2025"
$serverNotes | Out-File -FilePath "release_notes.txt" -Encoding UTF8
# Release notes for GitHub (with install instructions)
$githubNotes = "## CPSK Tools for Revit v$version`n`n"
$githubNotes += "### Установка`n"
$githubNotes += "1. Скачайте ``CPSK_Tools_v$version.exe```n"
$githubNotes += "2. Запустите установщик`n"
$githubNotes += "3. Перезапустите Revit`n`n"
$githubNotes += "### Изменения`n"
if ($commits) {
$githubNotes += ($commits -join "`n")
} else {
$githubNotes += "- Обновление версии"
}
if ($authors) {
$githubNotes += "`n`n### Авторы`n"
$githubNotes += ($authors | ForEach-Object { "- $_" }) -join "`n"
}
$githubNotes += "`n`n### Требования`n- Windows 10/11`n- Autodesk Revit 2021-2025"
$githubNotes | Out-File -FilePath "github_release_notes.txt" -Encoding UTF8
Write-Host "Release notes generated"
- name: Create Release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
name: "CPSK Tools v${{ steps.version.outputs.VERSION }}"
body_path: github_release_notes.txt
files: "CPSK_Tools_*.exe"
draft: false
prerelease: ${{ steps.version.outputs.IS_STAGING == 'True' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to release server
if: startsWith(github.ref, 'refs/tags/') && steps.version.outputs.IS_STAGING != 'True'
shell: pwsh
run: |
$version = "${{ steps.version.outputs.VERSION }}"
$token = "${{ secrets.RELEASE_API_TOKEN }}"
if (-not $token) {
Write-Host "WARNING: RELEASE_API_TOKEN secret not set, skipping upload"
exit 0
}
$exeFile = Get-ChildItem -Path "." -Filter "CPSK_Tools_*.exe" | Select-Object -First 1
if (-not $exeFile) {
Write-Host "ERROR: No exe file found"
exit 1
}
# Read release notes from file
$releaseNotes = Get-Content -Path "release_notes.txt" -Raw -Encoding UTF8
Write-Host "Uploading $($exeFile.Name) to release server..."
$headers = @{
"Authorization" = "Bearer $token"
}
$form = @{
version = $version
exe_file = Get-Item $exeFile.FullName
release_notes = $releaseNotes
git_tag = "v$version"
git_commit = "${{ github.sha }}"
github_release_url = "https://github.com/${{ github.repository }}/releases/tag/v$version"
min_revit_version = "2021"
max_revit_version = "2025"
}
try {
$response = Invoke-RestMethod -Uri "https://rocket-tools.ru/api/rocketrevit/releases/upload/" `
-Method POST `
-Headers $headers `
-Form $form
Write-Host "Upload successful!"
Write-Host "Response: $($response | ConvertTo-Json)"
} catch {
Write-Host "ERROR: Upload failed: $_"
Write-Host "Response: $($_.ErrorDetails.Message)"
# Don't fail the build if upload fails - GitHub release is already created
Write-Host "WARNING: Server upload failed, but GitHub release was created successfully"
}