Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
b53df58
Make the bundle's stagings available by FetchLayer, prebuilt or from …
alexadereyko Oct 24, 2026
86bd0f2
Build every layer from sources in one tree: post-fetch includes for B…
alexadereyko Oct 26, 2026
5ab7227
Include the axis table where variants are parsed, for fill-store
alexadereyko Oct 28, 2026
6ac79aa
Pin the core with the C binding, test-utils and the native modules
alexadereyko Oct 28, 2026
43d32c6
Pack the installer with each module as a choice of its own
alexadereyko Oct 29, 2026
25d96ea
Smoke-check an installed bundle: the modules load, the C binding is c…
alexadereyko Oct 29, 2026
bc84664
Pin the core whose C binding installs all its headers; name the macOS…
alexadereyko Oct 29, 2026
4c684ff
Load the modules through the C binding too
alexadereyko Oct 29, 2026
1692d8f
Pack the installer as NSIS too: the core's look, modules as choices, …
alexadereyko Oct 30, 2026
73b439c
Move the installers' files to packaging/, by generator
alexadereyko Oct 30, 2026
861bd0f
Rename PackingProject.cmake to CPackOptions.cmake: what cpack reads
alexadereyko Oct 30, 2026
890226b
Assemble the bundle in CI: pull its stagings from the registry as art…
alexadereyko Nov 2, 2026
d2fb300
Assemble the bundle for Linux ARM too
alexadereyko Nov 2, 2026
0224927
Show how download-artifact lays out the stagings it downloads
alexadereyko Nov 2, 2026
fa22ce8
Assemble the installers in CI: each platform built by reusable.yml fr…
alexadereyko Nov 2, 2026
e3359a3
Install the stagings' system libraries for the DEB's dependencies
alexadereyko Nov 2, 2026
d218e1a
Install the NSIS installer without PATH for the smoke check; time an …
alexadereyko Nov 2, 2026
5e617ac
Add to PATH by the EnVar plugin: the template's AddToPath waits on a …
alexadereyko Nov 3, 2026
58dbdfa
Take the layers' revisions as inputs of the assembly, and the staging…
alexadereyko Nov 3, 2026
b295339
Pack the Linux DEBs from the manylinux stagings, as the wheels are built
alexadereyko Nov 3, 2026
86f0442
Pack the Linux DEBs from the Ubuntu stagings again: the manylinux one…
alexadereyko Nov 3, 2026
aff9574
Keep the layers' revisions in bundle.json, one ref per layer, read by…
alexadereyko Nov 3, 2026
02d557e
Configure with the commits the assembly resolved, not bundle.json's r…
alexadereyko Nov 3, 2026
c27b123
Fill the configure's cache variables under their new name
alexadereyko Nov 3, 2026
e89ab15
Split the assembly: resolve.yml lays the stagings into the run, assem…
alexadereyko Nov 5, 2026
2e2e85a
Take the stagings staged in another run from its artifacts instead of…
alexadereyko Nov 5, 2026
441ffcf
Take no stagings from other runs: no caller needs it yet
alexadereyko Nov 5, 2026
871b504
Stage a staging missing in the registry here, by its layer's stage.ym…
alexadereyko Nov 5, 2026
fd33d36
Test: OpcUaModules at a commit the registry lacks, staged here
alexadereyko Nov 5, 2026
065737b
Take OpcUaModules at bundle.json's commit again
alexadereyko Nov 5, 2026
7ad3748
Look for each staging in the channel its commit lies in, not in dev a…
alexadereyko Nov 5, 2026
bf00ad0
Test: OpcUaModules at a commit the registry lacks, staged here
alexadereyko Nov 5, 2026
001676c
Take OpcUaModules at bundle.json's commit again
alexadereyko Nov 5, 2026
7cbfb4d
Test: OpcUaModules at a commit the registry lacks, staged here
alexadereyko Nov 5, 2026
320ff98
Take OpcUaModules at bundle.json's commit again
alexadereyko Nov 5, 2026
6c94094
Name every staging in the run as its stage does, stage a missing core…
alexadereyko Nov 6, 2026
e85778c
Stage MQTT, LT and ASAM here too when the registry lacks them
alexadereyko Nov 6, 2026
0f64981
Build the layers staged here for the bundle's platforms only
alexadereyko Nov 7, 2026
64e690b
Test: OpcUaModules and MQTTStreamingModule at commits the registry la…
alexadereyko Nov 7, 2026
66213ab
Take OpcUaModules and MQTTStreamingModule at bundle.json's commits again
alexadereyko Nov 7, 2026
eb91d90
Test: openDAQ at a commit the registry lacks, every layer staged here
alexadereyko Nov 7, 2026
024c145
Take openDAQ at bundle.json's commit again
alexadereyko Nov 7, 2026
e6e0e32
Test: openDAQ at an empty commit on 1a82fa8 the registry lacks, every…
alexadereyko Nov 7, 2026
ee71a44
Take openDAQ at bundle.json's commit again
alexadereyko Nov 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions .github/workflows/assemble.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: Assemble the bundle

# The bundle's installers assembled from stagings, without compiling. The stagings are artifacts of this run, laid
# in by resolve.yml, <staging>-staging-<job>. reusable.yml builds each platform as the stagings were built:
# the stagings unpacked each into its own folder, given to the bundle as FETCHLAYER_PREFIX_<STAGING> (configure preset
# bundle-prefixes), the commits as BUNDLE_REVISION_<LAYER>, the installer packed (package preset installer). Each
# installer is then installed as a user would and smoke-checked by tests/installed.

on:
workflow_call:
inputs:
revisions:
description: "The commit of each staging's layer: a JSON object, staging → full sha (resolve.yml's)"
type: string
platforms:
description: "The platforms: a JSON list of {job, triplet, generator, runner, modules} (resolve.yml's)"
type: string

permissions:
contents: read

jobs:
plan:
name: Plan the build
runs-on: ubuntu-latest
outputs:
jobs: ${{ steps.plan.outputs.jobs }}
packages: ${{ steps.plan.outputs.packages }}
cmake-presets: ${{ steps.plan.outputs.cmake-presets }}
cpack-presets: ${{ steps.plan.outputs.cpack-presets }}
checks: ${{ steps.plan.outputs.checks }}
steps:
- name: Plan
id: plan
shell: python3 {0}
env:
REVISIONS: ${{ inputs.revisions }}
PLATFORMS: ${{ inputs.platforms }}
run: |
import json, os

# a staging → its layer, named as its repository (BUNDLE_REVISION_<LAYER>)
REPOSITORIES = {"opendaq": "openDAQ", "opcua-modules": "OpcUaModules", "mqtt-module": "MQTTStreamingModule",
"lt-streaming-modules": "LTStreamingModulesModern", "asam-cmp-modules": "ASAM-CMP-Modules"}
revision = json.loads(os.environ["REVISIONS"])
platforms = json.loads(os.environ["PLATFORMS"])

packages, cmake_presets, cpack_presets, checks = [], [], [], []
for p in platforms:
job = p["job"]
# the commits resolved there, so configure takes the same ones and resolves no ref again
artifacts = []
cache_variables = {f"BUNDLE_REVISION_{REPOSITORIES[staging].upper()}": sha for staging, sha in revision.items()}
for staging in revision:
artifacts.append({"name": f"{staging}-staging-{job}", "dir": f"stagings/{staging}"})
# the core's tarball carries its install prefix, opt/opendaq, except on Windows
inside = "/opt/opendaq" if staging == "opendaq" and not job.startswith("windows-") else ""
cache_variables[f"FETCHLAYER_PREFIX_{staging.upper()}"] = "${sourceDir}/stagings/" + staging + inside
packages.append({"match-jobs": [job], "artifacts": artifacts})
cmake_presets.append({"match-jobs": [job], "configure-preset": "bundle-prefixes", "cache-variables": cache_variables})
cpack_presets.append({"match-jobs": [job], "installers": [{"name": "bundle", "package": p["generator"], "package-preset": "installer"}]})
checks.append({"job": job, "runner": p["runner"], "generator": p["generator"], "modules": p["modules"]})

# DEB names the libraries the stagings need in its Depends (dpkg-shlibdeps), so they must be there: ASAM's
# libpcap, ref_fb's renderer's X11, GL, udev and freetype, LT's OpenSSL; NSIS packs
packages += [{"match-jobs": ["ubuntu-*"], "apt-install": ["dpkg-dev", "file", "libpcap0.8", "libx11-6",
"libxrandr2", "libxcursor1", "libxi6", "libgl1", "libudev1", "libfreetype6", "libssl3"]},
{"match-jobs": ["windows-*"], "choco-install": ["nsis"]}]

outputs = {"jobs": [p["job"] for p in platforms], "packages": packages,
"cmake-presets": cmake_presets, "cpack-presets": cpack_presets, "checks": checks}
print(json.dumps(outputs, indent=2))
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
for key, value in outputs.items():
f.write(f"{key}={json.dumps(value)}\n")

build:
name: Build
needs: plan
uses: openDAQ/openDAQ-CI/.github/workflows/reusable.yml@bundle/extract-each-artifact-into-its-dir
with:
include-jobs: ${{ needs.plan.outputs.jobs }}
packages: ${{ needs.plan.outputs.packages }}
cmake-presets: ${{ needs.plan.outputs.cmake-presets }}
cpack-presets: ${{ needs.plan.outputs.cpack-presets }}

# installed as a user would, everything selected, and smoke-checked
check:
name: Check ${{ matrix.check.job }}
needs: [plan, build]
runs-on: ${{ matrix.check.runner }}
strategy:
fail-fast: false
matrix:
check: ${{ fromJSON(needs.plan.outputs.checks) }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
with:
repository: ${{ job.workflow_repository }}
ref: ${{ job.workflow_sha }}

- uses: actions/download-artifact@v4
with:
name: package-${{ matrix.check.job }}
path: installer

- name: Install
id: install
timeout-minutes: 10
run: |
find installer -type f
case "${{ matrix.check.generator }}" in
DEB) sudo apt-get update -qq
sudo apt-get install -y -qq "$(find "$PWD/installer" -name '*.deb' | head -1)"
echo "prefix=/opt/opendaq" >> "$GITHUB_OUTPUT" ;;
productbuild) sudo installer -pkg "$(find installer -name '*.pkg' | head -1)" -target /
echo "prefix=/opt/opendaq" >> "$GITHUB_OUTPUT" ;;
NSIS) exe=$(cygpath -w "$(find installer -name '*.exe' | head -1)")
pwsh -Command 'Write-Host "PATH: $($env:Path.Length) characters (the template reads 1024)"'
pwsh -Command "Start-Process -Wait -FilePath '$exe' -ArgumentList '/S','/PATH=AllUsers','/D=C:\opendaq'"
echo "prefix=C:/opendaq" >> "$GITHUB_OUTPUT" ;;
esac

- name: Smoke check
run: |
cmake -S tests/installed -B build/installed \
-DOPENDAQ_PREFIX=${{ steps.install.outputs.prefix }} -DEXPECT_MODULES=${{ matrix.check.modules }}
cmake --build build/installed --config Release
ctest --test-dir build/installed -C Release --output-on-failure

# the installer added its bin to the machine's PATH, and the uninstaller removes it
- name: PATH
if: matrix.check.generator == 'NSIS'
timeout-minutes: 5
shell: pwsh
run: |
$bin = 'C:\opendaq\bin'
$has = { ([Environment]::GetEnvironmentVariable('Path', 'Machine') -split ';') -contains $bin }
Write-Host "after install, machine PATH has ${bin}: $(& $has)"
if (-not (& $has)) { exit 1 }
Start-Process -Wait -FilePath 'C:\opendaq\Uninstall.exe' -ArgumentList '/S','_?=C:\opendaq'
Write-Host "after uninstall, machine PATH has ${bin}: $(& $has)"
if (& $has) { exit 1 }
78 changes: 78 additions & 0 deletions .github/workflows/bundle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Bundle

# The bundle's installers: resolve.yml lays the stagings of the bundle's commits into this run, assemble.yml builds
# the installers from them. A layer's revision can be given as an input (a commit, or a branch or tag taken at its
# head now), in place of bundle.json's. Called by the bundle's own triggers and by a layer's CI.

on:
workflow_dispatch:
inputs:
opendaq:
description: "openDAQ: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
opcua-modules:
description: "OpcUaModules: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
mqtt-module:
description: "MQTTStreamingModule: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
lt-streaming-modules:
description: "LTStreamingModulesModern: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
asam-cmp-modules:
description: "ASAM-CMP-Modules: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
workflow_call:
inputs:
opendaq:
description: "openDAQ: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
opcua-modules:
description: "OpcUaModules: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
mqtt-module:
description: "MQTTStreamingModule: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
lt-streaming-modules:
description: "LTStreamingModulesModern: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
asam-cmp-modules:
description: "ASAM-CMP-Modules: a commit, branch or tag (empty: bundle.json's)"
type: string
default: ""
pull_request:

permissions:
contents: read
packages: read

jobs:
resolve:
name: Resolve
permissions:
contents: read
packages: write # a missing staging's stage.yml asks for it; nothing is pushed from here
uses: ./.github/workflows/resolve.yml
with:
opendaq: ${{ inputs.opendaq }}
opcua-modules: ${{ inputs.opcua-modules }}
mqtt-module: ${{ inputs.mqtt-module }}
lt-streaming-modules: ${{ inputs.lt-streaming-modules }}
asam-cmp-modules: ${{ inputs.asam-cmp-modules }}

assemble:
name: Assemble
needs: resolve
uses: ./.github/workflows/assemble.yml
with:
revisions: ${{ needs.resolve.outputs.revisions }}
platforms: ${{ needs.resolve.outputs.platforms }}
Loading
Loading