diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..d3c43c2
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,11 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "gitversion.tool": {
+ "version": "6.0.2",
+ "commands": ["dotnet-gitversion"],
+ "rollForward": false
+ }
+ }
+}
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..0185959
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,74 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+name: Build Archicad
+
+on:
+ push:
+ branches: ["main", "dev", "release/*", "alan/*"] # Continuous delivery on every long-lived branch
+ tags: ["v3.*"] # Manual delivery on every 3.x tag
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: windows-latest
+ outputs:
+ version: ${{ steps.set-version.outputs.version }}
+ file_version: ${{ steps.set-info-version.outputs.file_version }}
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v2
+
+ - name: ⚒️ Run GitVersion
+ run: ./build.ps1 build-server-version
+
+ - name: Build
+ run: ./build.ps1
+
+ - uses: actions/upload-artifact@v4
+ with:
+ name: output-${{ env.GitVersion_FullSemVer }}
+ path: output/*.zip
+ retention-days: 1
+
+ - id: set-version
+ name: Set version to output
+ run: echo "version=${{ env.GitVersion_FullSemVer }}" >> "$Env:GITHUB_OUTPUT"
+
+ - id: set-info-version
+ name: Set file version to output
+ run: echo "file_version=${{ env.GitVersion_AssemblySemVer}}" >> "$Env:GITHUB_OUTPUT" # version will be retrieved from tag?
+ deploy-installers:
+ runs-on: ubuntu-latest
+ needs: build
+ env:
+ IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
+ IS_RELEASE_BRANCH: true
+ steps:
+ - name: 🔫 Trigger Build Installers
+ uses: ALEEF02/workflow-dispatch@v3.0.0
+ continue-on-error: true
+ with:
+ workflow: build-cpp-installers
+ repo: specklesystems/connector-installers
+ token: ${{ secrets.CONNECTORS_GH_TOKEN }}
+ inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build.outputs.version }}", "file_version": "${{needs.build.outputs.file_version}}", "public_release": ${{ env.IS_TAG_BUILD }}, "store_artifacts": ${{ env.IS_RELEASE_BRANCH }} }'
+ ref: alan/update-archicad-installer
+ 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-*
diff --git a/.gitignore b/.gitignore
index 1ee4221..4d71f7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,8 @@
*.bak
*.log
**/*_svg_source/
+
+**/obj
+**/bin
+**/Thumbs.db
+**/output
\ No newline at end of file
diff --git a/GitVersion.yml b/GitVersion.yml
new file mode 100644
index 0000000..e688060
--- /dev/null
+++ b/GitVersion.yml
@@ -0,0 +1,6 @@
+workflow: GitFlow/v1
+next-version: 3.0.0
+branches:
+ release:
+ prevent-increment:
+ when-current-commit-tagged: true
diff --git a/build.ps1 b/build.ps1
new file mode 100644
index 0000000..e63b7aa
--- /dev/null
+++ b/build.ps1
@@ -0,0 +1,3 @@
+$ErrorActionPreference = "Stop";
+
+dotnet run --project ci-build/build.csproj -- $args
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..f75ab37
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+dotnet run --project Build/Build.csproj -- "$@"
diff --git a/ci-build/Build.csproj b/ci-build/Build.csproj
new file mode 100644
index 0000000..49cf624
--- /dev/null
+++ b/ci-build/Build.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ Debug;Release;Local
+ true
+
+
+
+
+
+
+
+
diff --git a/ci-build/Consts.cs b/ci-build/Consts.cs
new file mode 100644
index 0000000..33cf729
--- /dev/null
+++ b/ci-build/Consts.cs
@@ -0,0 +1,19 @@
+namespace Build;
+
+public static class Consts
+{
+ public static readonly string[] SupportedVersions = new string[] { "27", "28"};
+ public static readonly string[] Solutions = ["build_27/speckle-archicad.sln", "build_28/speckle-archicad.sln"];
+
+ public static readonly InstallerProject[] InstallerManifests =
+ {
+ new("archicad", [new("archicad27", "build/27/INT/Release", "*.apx"), new("archicad28", "build/28/INT/Release", "*.apx")])
+ };
+}
+
+public readonly record struct InstallerProject(string HostAppSlug, IReadOnlyList Projects)
+{
+ public override string ToString() => $"{HostAppSlug}";
+}
+
+public readonly record struct InstallerAsset(string ConnectorVersion, string OutputPath, string GlobPattern = "*");
diff --git a/ci-build/Program.cs b/ci-build/Program.cs
new file mode 100644
index 0000000..98df13c
--- /dev/null
+++ b/ci-build/Program.cs
@@ -0,0 +1,121 @@
+using System.IO.Compression;
+using Build;
+using GlobExpressions;
+using static Bullseye.Targets;
+using static SimpleExec.Command;
+
+const string CLEAN = "clean";
+const string BUILD = "build";
+const string ZIP = "zip";
+const string RESTORE_TOOLS = "restore-tools";
+const string BUILD_SERVER_VERSION = "build-server-version";
+const string RUN_CMAKE = "build-cmake";
+
+Target(
+ CLEAN,
+ ForEach("**/output"),
+ dir =>
+ {
+ IEnumerable GetDirectories(string d)
+ {
+ return Glob.Directories(".", d);
+ }
+
+ void RemoveDirectory(string d)
+ {
+ if (Directory.Exists(d))
+ {
+ Console.WriteLine(d);
+ Directory.Delete(d, true);
+ }
+ }
+
+ foreach (var d in GetDirectories(dir))
+ {
+ RemoveDirectory(d);
+ }
+ }
+);
+
+Target(
+ RESTORE_TOOLS,
+ () =>
+ {
+ Run("dotnet", "tool restore");
+ }
+);
+
+Target(
+ BUILD_SERVER_VERSION,
+ DependsOn(RESTORE_TOOLS),
+ () =>
+ {
+ Run("dotnet", "tool run dotnet-gitversion /output json /output buildserver");
+ }
+);
+
+Target(RUN_CMAKE, Consts.SupportedVersions, s =>
+{
+ Run("cmake", $"-G \"Visual Studio 17 2022\" -T v142 -A \"x64\" -DAC_ADDON_LANGUAGE=\"INT\" -DAC_API_DEVKIT_DIR=\"Libs\\acapi{s}\" -B build\\{s} -DCMAKE_BUILD_TYPE=Release");
+});
+
+Target(
+ BUILD,
+ DependsOn(RUN_CMAKE),
+ Consts.SupportedVersions,
+ s =>
+ {
+ var version = Environment.GetEnvironmentVariable("GitVersion_FullSemVer") ?? "3.0.0-localBuild";
+ var fileVersion = Environment.GetEnvironmentVariable("GitVersion_AssemblySemFileVer") ?? "3.0.0.9999";
+ Console.WriteLine($"Version: {version} & {fileVersion}");
+ Run("msbuild", $"./build/{s}/archicad-speckle.sln /p:Configuration=Release /p:Version={version} /p:FileVersion={fileVersion}");
+ }
+);
+
+Target(
+ ZIP,
+ DependsOn(BUILD),
+ Consts.InstallerManifests,
+ x =>
+ {
+ var outputDir = Path.Combine(".", "output");
+ var slugDir = Path.Combine(outputDir, x.HostAppSlug);
+
+ Directory.CreateDirectory(outputDir);
+ Directory.CreateDirectory(slugDir);
+
+ foreach (var asset in x.Projects)
+ {
+ var fullPath = Path.Combine(".", asset.OutputPath);
+ if (!Directory.Exists(fullPath))
+ {
+ throw new InvalidOperationException("Could not find: " + fullPath);
+ }
+
+ var assetName = asset.ConnectorVersion;
+ var connectorDir = Path.Combine(slugDir, assetName);
+ Directory.CreateDirectory(connectorDir);
+ foreach (var directory in Directory.EnumerateDirectories(fullPath, asset.GlobPattern, SearchOption.AllDirectories))
+ {
+ Directory.CreateDirectory(directory.Replace(fullPath, connectorDir));
+ }
+
+ foreach (var file in Directory.EnumerateFiles(fullPath, asset.GlobPattern, SearchOption.AllDirectories))
+ {
+ Console.WriteLine(file);
+ var destFileName = file.Replace(fullPath, connectorDir);
+ File.Copy(file, destFileName, true);
+ }
+ }
+
+ var outputPath = Path.Combine(outputDir, $"{x.HostAppSlug}.zip");
+ File.Delete(outputPath);
+ Console.WriteLine($"Zipping: '{slugDir}' to '{outputPath}'");
+ ZipFile.CreateFromDirectory(slugDir, outputPath);
+ // Directory.Delete(slugDir, true);
+ }
+);
+
+Target("default", DependsOn(ZIP), () => Console.WriteLine("Done!"));
+
+await RunTargetsAndExitAsync(args).ConfigureAwait(true);