Table of Contents

zkbuild

One of Zeugwerk’s CI/CD tools for TwinCAT. Manual PLC builds in the IDE don’t scale and aren’t reproducible. zkbuild lets you compile your PLCs and run unit tests in the cloud -no Jenkins or build servers. zkbuild-action is available for all major Git hosts (GitHub, GitLab, Bitbucket) and calls our CI/CD backend. Push code; get reproducible .library artifacts and test results.

Free tier for public repos (30 builds/month). For private repos or higher volume, contact us.


Why use it

  • Reproducible builds - Same output every time, independent of your machine.
  • Automated testing - Run TcUnit or Framework unit tests in CI; the build fails if tests fail.
  • No manual builds - Avoid “forgot to rebuild” and “works on my machine” issues.
  • Audit trail - Every build is logged and traceable (useful for compliance).
  • Zero DevOps - No Jenkins or build servers to maintain.

Quick start

  1. Register - Register here. Public repos get 30 free builds/month.
  2. Add a workflow - The example below is for GitHub; zkbuild-action also works with GitLab CI and Bitbucket Pipelines. Create .github/workflows/build.yml in your repo (or the equivalent in your Git host):
name: Build/Test
on:
  push:
    branches: [main, 'release/**']
  pull_request_target:
  workflow_dispatch:
jobs:
  Build:
    name: Build/Test
    runs-on: ubuntu-latest
    steps:
      - name: Build
        uses: Zeugwerk/zkbuild-action@1.0.0
        with:
          username: ${{ secrets.ACTIONS_ZGWK_USERNAME }}
          password: ${{ secrets.ACTIONS_ZGWK_PASSWORD }}
      - name: Upload Artifact
        uses: actions/upload-artifact@v4
        with:
          name: artifact
          path: "**/*.library"
      - name: Publish Unittest
        uses: EnricoMi/publish-unit-test-result-action@v1
        with:
          files: archive/test/TcUnit_xUnit_results.xml
  1. Store credentials - Add ACTIONS_ZGWK_USERNAME and ACTIONS_ZGWK_PASSWORD as GitHub Secrets. Do not commit them.
  2. Configure the build - Add a .Zeugwerk/config.json in your repo (see Configuration). You can generate it with Twinpack.

How it works

Your push triggers the action → the action calls Zeugwerk CI/CD → our server builds the solution, runs unit tests, and returns artifacts (e.g. .library files, test results). The action uploads them to the workflow run. No Jenkins or self-hosted runner required.

Configuration

Inputs

Input Required Description
username Yes Zeugwerk account username
password Yes Zeugwerk account password
tcversion No TwinCAT version (default: TC3.1)

Outputs

Artifact Location
.library file(s) archive/<repo>/<tcversion>/<plc>_<version>.library
Test results (JUnit) archive/test/TcUnit_xUnit_results.xml
Build logs GitHub Actions run summary

Basic config (single PLC, no dependencies)

Create .Zeugwerk/config.json in your repo:

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

Use Twinpack to generate this file from your solution.

Unit tests

zkbuild runs unit tests automatically. Two options:

  • Option A (recommended) - In your PLC project, implement function blocks that extend ZCore.IUnittest (Zeugwerk Framework) or Testbench.IUnittest. zkbuild discovers and runs them. Requires the ZCore package or Testbench; do not mix both.
  • Option B - Use a separate test project in a tests/ folder (e.g. with TcUnit). zkbuild builds and runs it.

Pricing

  • Free - 30 builds/month for public repositories.
  • Commercial - Custom pricing for private repos and higher volume. contact us.

Examples

struckig, DeviceInfo, Demo-Twincat-Application-CI, rplc. See the Actions tab in any of these repos for build results.

Troubleshooting

  • Credentials not found - Ensure ACTIONS_ZGWK_USERNAME and ACTIONS_ZGWK_PASSWORD are set in GitHub Secrets.
  • TwinCAT version mismatch - Set tcversion, e.g. tcversion: TC3.1.4024.
  • Tests not running - Ensure FBs implement ZCore.IUnittest or Testbench.IUnittest, or use a separate tests/ project with TcUnit.

Advanced: config with dependencies

You can declare packages (e.g. ZCore) in .Zeugwerk/config.json; the build system resolves, downloads, and installs them. See the zkbuild-action README for the full config.json schema and examples with packages and references.

Advanced: patches

Zeugwerk CI can apply patches before compile:

  • Platform patches - Applied for specific TwinCAT versions.
  • Argument patches - Feature flags (not enabled for the free zkbuild tier; open an issue if you need it for open source).

Patches are configured in .Zeugwerk/config.json under patches (e.g. platform, argument). Supported formats: .patch (Git patch) and .replacement (search-and-replace JSON). See the zkbuild-action README for the exact format.