Table of Contents

.Zeugwerk/config.json reference

.Zeugwerk/config.json is the single configuration file used by both zkbuild-action and zkmake. It describes the solution structure, declares package dependencies, maps TwinCAT library references, and optionally configures source patches. The file lives at the root of your repository under .Zeugwerk/config.json.

The easiest way to create and maintain this file is through the Twinpack IDE extension, which generates it from your open solution.


Minimal example

A single library project with no external packages:

{
  "fileversion": 1,
  "solution": "MyProject.sln",
  "projects": [
    {
      "name": "MyProject",
      "plcs": [
        {
          "name": "MyPLC",
          "version": "1.0.0.0",
          "type": "Library"
        }
      ]
    }
  ]
}

Top-level fields

Field Required Description
fileversion Yes Schema version. Always 1.
solution Yes Path to the Visual Studio solution file (.sln), relative to the .Zeugwerk/ folder's parent directory.
projects Yes Array of project objects (see Projects).
modules No Array of subdirectory paths, each containing its own .Zeugwerk/config.json. Used for monorepos or solutions split across multiple folders. Each module is built independently and its libraries are combined in the final artifact set.

Modules

When a solution is split across multiple folders, list the subdirectories under modules. Each listed folder must contain its own .Zeugwerk/config.json.

{
  "fileversion": 1,
  "solution": "MyProject.sln",
  "modules": [
    "modules/AxisControl",
    "modules/SafetyPLC"
  ]
}

The build system processes each module in order, accumulating compiled libraries into a shared cache. Later modules can depend on libraries produced by earlier modules.


Projects

Each entry in projects maps to a Visual Studio project in the solution.

Field Required Description
name Yes Must match the project name in the .sln file exactly.
plcs Yes Array of PLC objects (see PLCs).

PLCs

Each entry in plcs describes one TwinCAT PLC project within the Visual Studio project.

Field Required Description
name Yes PLC name as it appears in the TwinCAT solution tree.
version Yes Version in Major.Minor.Patch.Build format, e.g. 1.2.0.0. Used for the output artifact filename.
type Yes Project type. See PLC types.
title No Human-readable display name. Defaults to name if omitted.
distributor-name No Name of the distributor shown in the TwinCAT library manager.
packages No External packages to install before building. See Packages.
references No TwinCAT system library references. See References.
patches No Source patches to apply before compiling. See Patches.

PLC types

Value Description
Library Standard TwinCAT library. The build produces a .library file.
FrameworkLibrary Same as Library; indicates the PLC is part of the Zeugwerk Framework family.
Application TwinCAT application (runtime project). No .library is produced; the solution is built and can be activated to a target.
UnitTestApplication TwinCAT test application in the same solution (native TcUnit). Built with the release solution and executed in the test phase. See Unit tests — Option C.

Packages

The packages array declares external Twinpack packages that the PLC depends on. The build system downloads, resolves, and installs them automatically before compilation.

{
  "packages": [
    {
      "name": "ZCore",
      "version": "1.2.19.0",
      "repository": "Twinpack",
      "branch": "release/1.2",
      "target": "TC3.1",
      "configuration": "Distribution",
      "distributor-name": "Zeugwerk GmbH"
    }
  ]
}
Field Required Description
name Yes Package name as registered in the Twinpack repository.
version Yes Exact version to install, e.g. 1.2.19.0.
repository Yes Twinpack repository identifier (e.g. Twinpack, bot). Must match a configured source in Twinpack.
branch No Source branch for the package (e.g. release/1.2, main).
target No TwinCAT target platform (e.g. TC3.1). Defaults to the target passed to the build tool.
configuration No Package build configuration (e.g. Distribution, Release, Snapshot).
distributor-name No Distributor name shown in the TwinCAT library manager (e.g. Zeugwerk GmbH).

Full example with packages

{
  "fileversion": 1,
  "solution": "TwinCAT Project1.sln",
  "projects": [
    {
      "name": "TwinCAT Project1",
      "plcs": [
        {
          "name": "MyPLC",
          "version": "1.0.0.0",
          "type": "Library",
          "distributor-name": "My Company",
          "packages": [
            {
              "name": "ZCore",
              "version": "1.2.19.0",
              "repository": "Twinpack",
              "branch": "release/1.2",
              "target": "TC3.1",
              "configuration": "Distribution",
              "distributor-name": "Zeugwerk GmbH"
            },
            {
              "name": "Tc2_MC2",
              "version": "3.3.38.0",
              "repository": "Beckhoff",
              "target": "TC3.1",
              "configuration": "Release",
              "distributor-name": "Beckhoff Automation GmbH"
            }
          ],
          "references": {
            "*": [
              "Tc2_Standard=*",
              "Tc2_System=*",
              "Tc3_Module=*"
            ]
          }
        }
      ]
    }
  ]
}

References

The references field maps TwinCAT target platforms to a list of system library references that must be present in the PLC project. These are Beckhoff system libraries (e.g. Tc2_Standard) that ship with TwinCAT, not Twinpack packages.

{
  "references": {
    "*": [
      "Tc2_Standard=*",
      "Tc2_System=*",
      "Tc2_MC2=*",
      "Tc3_Module=*"
    ]
  }
}

The key "*" applies to all TwinCAT target versions. You can also use a specific version string (e.g. "TC3.1.4024.56") to apply references only when building for that exact version.

Each entry in the array follows the format LibraryName=Version, where * means "any installed version".


Patches

Patches modify the PLC source code before compilation. They are declared under patches at the PLC level and are never committed to the compiled output - they only affect the build.

Two types are supported:

Platform patches

Applied automatically when building for a specific TwinCAT version. Useful for version-specific compatibility fixes.

{
  "patches": {
    "platform": {
      "TC3.1.4024.56": [
        "patches/fix-4024.patch",
        "patches/workaround.replacement"
      ]
    }
  }
}

Argument patches

Applied only when the build tool is explicitly told to apply a named patch (via --patch <identifier> in zkmake, or the patch argument in zkbuild-action). Useful for feature flags, toggling optional behaviour, or build variants.

Note

Argument patches are not available on the free tier of zkbuild-action. Contact us or open an issue if you need them for open source use.

{
  "patches": {
    "argument": {
      "enable-feature-x": [
        "patches/enable-feature-x.replacement"
      ]
    }
  }
}

Activate an argument patch:

:: zkmake (on-premises)
zkmake.exe build --patch enable-feature-x
# zkbuild-action (GitHub)
- name: Build
  uses: Zeugwerk/zkbuild-action@1.0.0
  with:
    username: ${{ secrets.ACTIONS_ZGWK_USERNAME }}
    password: ${{ secrets.ACTIONS_ZGWK_PASSWORD }}
    patch: enable-feature-x

Patch file formats

.patch files - Standard Git patches applied via git apply. Create one with:

git diff > patches/my-change.patch

.replacement files - Search-and-replace over source files. A JSON file with three fields:

Field Description
filter Glob pattern selecting which files to modify (e.g. *.TcPOU, *.TcGVL).
search Regular expression to find. Special regex characters must be escaped.
replace Replacement string. Use $1$N for regex capture groups.
{
  "filter": "*.TcPOU",
  "search": "FEATURE_FLAG := FALSE",
  "replace": "FEATURE_FLAG := TRUE"
}

Complete example

{
  "fileversion": 1,
  "solution": "MyProject.sln",
  "projects": [
    {
      "name": "MyProject",
      "plcs": [
        {
          "name": "MyPLC",
          "version": "2.1.0.0",
          "type": "Library",
          "title": "My PLC Library",
          "distributor-name": "My Company",
          "packages": [
            {
              "name": "ZCore",
              "version": "1.2.19.0",
              "repository": "Twinpack",
              "branch": "release/1.2",
              "target": "TC3.1",
              "configuration": "Distribution",
              "distributor-name": "Zeugwerk GmbH"
            }
          ],
          "references": {
            "*": [
              "Tc2_Standard=*",
              "Tc2_System=*",
              "Tc3_Module=*"
            ]
          },
          "patches": {
            "platform": {
              "TC3.1.4024.56": [
                "patches/compat-4024.patch"
              ]
            },
            "argument": {
              "debug-mode": [
                "patches/enable-debug.replacement"
              ]
            }
          }
        }
      ]
    }
  ]
}