Create .github/copilot-instructions.md as a minimal GitHub Copilot entry point, trim CLAUDE.md to a minimal pointer file, and move shared safety/output-expectation guidance into docs/agents/workflow.md. Also update the header/implementation-split rule in docs/agents/coding-style.md to allow short one-line bodies and short initializer lists inline in the header.
* Select RHEL8 vcpkg-configuration.json via CMake instead of renaming the tracked file
RHEL8 CI jobs previously ran 'cp vcpkg-configuration-rhel8.json vcpkg-configuration.json'
before configuring, temporarily overwriting the tracked default configuration
in the checkout. The vcpkg toolchain file only defaults VCPKG_MANIFEST_DIR to
CMAKE_SOURCE_DIR when it is not already defined, and reads it while processing
project(), so setting VCPKG_MANIFEST_DIR earlier -- before project() -- lets
vcpkg read a different vcpkg-configuration.json without ever touching the
tracked file.
Add a RESINSIGHT_VCPKG_PROFILE cache variable, implemented in the new
cmake/ResInsightVcpkgProfile.cmake (included from the root CMakeLists.txt
before project(), which is required for VCPKG_MANIFEST_DIR to take effect).
When set (e.g. to 'rhel8'), it copies vcpkg.json and
vcpkg-configuration-<profile>.json into a profile-specific directory under
the build tree and points VCPKG_MANIFEST_DIR there. The copy is regenerated on
every configure, so it can never drift from the root vcpkg.json.
overlay-ports/overlay-triplets entries (e.g. 'ThirdParty/vcpkg-overlay-ports')
are resolved by vcpkg relative to the directory vcpkg-configuration.json lives
in, so repo-relative 'ThirdParty/...' paths are rewritten to absolute paths
right after the copy is generated, keeping them valid from the new location.
Update the RHEL8 workflows and Dockerfile.rhel8 build-warmup stage to pass
-DRESINSIGHT_VCPKG_PROFILE=rhel8 instead of the cp step, and update
vcpkg-readme.md to describe the new mechanism.
* #14733 Use x64-linux-release vcpkg triplet explicitly in RHEL8 CI
The RHEL8 CI workflows and the Docker image's warmup/vcpkg-cache stages
did not set VCPKG_TARGET_TRIPLET/VCPKG_HOST_TRIPLET, so vcpkg fell back
to its plain x64-linux default triplet, which builds both debug and
release variants of every dependency even though the CI build is
Release-only. Set both to x64-linux-release consistently across the
image's vcpkg install, the warmup CMake configure, and the two
consuming workflows so the baked binary cache and the CI configure use
matching ABI hashes and skip the unused debug builds.
grpcio-tools 1.82.0+ (including its 1.82.0 pre-releases) bundles a
protoc that emits protobuf 7.35.x gencode, which no protobuf 6 runtime
can load. Pin grpcio-tools below that (excluding pre-releases via the
'.dev0' trick, since a plain '<1.82' bound already let a 1.82.0rc
release slip through once) and add a CI check that verifies the
generated *_pb2.py files stay within the protobuf floor declared in
pyproject.toml.
Only the load-bearing bounds are kept: protobuf's '>=6.33.5' floor
(must match the emitted gencode) and grpcio-tools' '<1.82.0.dev0'
ceiling. Non-load-bearing bounds (protobuf's '<8', grpcio-tools'
'>=1.81') were dropped since they don't change dependency resolution
or protect against anything the above doesn't already cover.
A full Windows build writes ~550 MB of buildcache entries, so the shared 500 MB limit was exceeded before the build finished. buildcache then evicted entries the same build still needed, and the cache never converged: rebuilding an unchanged tree against a cache written by that very tree hit only 44%, leaving the Windows leg at ~70 minutes while Linux, whose objects are half the size, finished in 83 seconds.
Move the limit into the matrix so Windows gets 1.5 GiB and Linux keeps 500 MB.
CMAKE_SYSTEM holds the host kernel release, which on the ubuntu-latest runner says nothing about the RHEL8 userland inside the container, so the el8 regex never matched. CPACK_SYSTEM_NAME is only set for Windows, so the fallback appended a bare underscore and the release asset ended up as ResInsight-2026.09.0_.tar.gz.
Let the caller state the distribution explicitly and skip the suffix entirely when neither name is known.
vcpkg only reads VCPKG_BUILD_TYPE from the triplet file, so the
-DVCPKG_BUILD_TYPE=release passed to the top-level CMake call never had any
effect and every port was built in both debug and release. On a cold cache
that is roughly half of an 85 minute vcpkg step.
Add release-only overlay triplets for x64-windows and x64-linux and select
them from the workflow matrix. They are separate triplets rather than an
override of the stock ones so local developer builds keep their debug
dependencies. VCPKG_HOST_TRIPLET is set alongside the target triplet,
otherwise the 12 host-tool ports (openssl and protobuf among them) would be
built a second time under the stock triplet.
The triplet is part of the vcpkg cache key since it changes every binary's
ABI hash.
Only save the buildcache from the default branch. GitHub scopes cache writes to the current ref, so a cache saved from a feature branch or PR is invisible to every other branch while still counting against the 10 GB per-repository quota and evicting the shared caches on the default branch.
Disable unity build for all configurations. Unity blobs invalidate on any change to the sources they bundle, which defeats buildcache reuse and fills the cache with objects that are unlikely to be hit again.
ResInsight-tests linked into the build root and copied its full runtime DLL
set there as a POST_BUILD step, the same pattern that made
extract-projectfile-versions race against the generated_classes.py edge. The
set is a superset of the one that failed, covering Qt6Gui, Qt6Widgets and the
rest, and nothing orders it against the code generation edge either. It fires
rarely only because copy_if_different compares content, so windeployqt having
already placed identical DLLs makes it a no-op. On a cold build where the copy
wins that race it genuinely writes.
Give the target its own RUNTIME_OUTPUT_DIRECTORY, and point the companion
PreBuildFileCopyTest target at the same directory so the ODB, OpenVDS and HDF5
runtime files stay next to the executable. That target runs before the link
creates the directory, so create it first.
Update the three workflows that run the test executable by path.
The copilot-setup-steps job ran before every Copilot task and spent up to
an hour on submodule checkout, Qt, vcpkg and a full build, which is wasted
work for documentation and other text-only tasks. Remove it so cloud tasks
start from a plain checkout.
The vcpkg ABI hash depends on more of the runner image than cl.exe: on
Windows every port's ABI includes the PowerShell version. Image
20260728 bumped PowerShell 7.6.3 to 7.6.4, which changed all 102 ABIs
while the cache key stayed fixed. The cache restored but vcpkg rejected
every archive, and the save step skipped because the key already
existed, so the stale entry never refreshed and every run rebuilt all
dependencies (98 min configure step).
The nightly image build has failed since 2026-07-23 with "failed to
solve: not_found" while exporting the BuildKit layer cache, because the
repository's GitHub Actions cache is at the 10 GB limit and entries are
evicted as fast as they are written (0% cache hit rate on restore).
Use a registry cache (ci-rhel8:buildcache in GHCR) instead, which has no
size cap, and exclude the buildcache tag from the daily image cleanup.
Make the cache effective across nightly rebuilds: key the vcpkg stage on
its actual inputs (vcpkg.json, the vcpkg configuration and the vcpkg
tool) with a direct manifest install instead of copying the entire build
context, and exclude .git from the Docker build context since its
internals differ between checkouts of the same commit and invalidated
'COPY . /src' on every run. Nightly builds now reuse the compiled vcpkg
ports from the layer cache and only recompile the ResInsight warmup
stage.
* #1009 macOS: add native Intel (x86_64) build alongside arm64
The macOS workflow only built on the arm64 runner (macos-15), producing
an Apple Silicon-only artifact that could not launch on Intel Macs.
Turn the single build job into a matrix that also builds natively on
GitHub's Intel runner (macos-15-intel), uploading a separate
ResInsight-macOS-x64 artifact next to ResInsight-macOS-arm64. All cache
keys (buildcache tool, buildcache contents, vcpkg) are qualified by
architecture so the two legs cache independently, and fail-fast is
disabled so a broken Intel leg never withholds the arm64 artifact.
The Intel leg uses a 13.3 deployment target: Apple's libc++ only ships
the <format> / std::to_chars(float) runtime symbols from macOS 13.3, and
the code (e.g. custom-surfio) uses std::format on floating-point values,
so a lower target fails to compile. 13.3 stays well below the runner's
macOS 15 SDK, keeping older Intel Macs supported.
release-draft.yml now downloads both macOS artifacts via a glob so each
architecture is attached to the draft release as its own zip.
Add a dedicated clazy-report workflow that configures the build to
generate compile_commands.json and runs clazy-standalone over
ApplicationLibCode and GrpcInterface as a report-only step.
Build clazy 1.15 from source against the installed clang/llvm-19 (the
packaged clazy is built against an older Clang that cannot parse
libstdc++-14's C++23 headers). Analysis runs one process per file
across all cores. The two highest-volume checks (range-loop-detach,
non-pod-global-static) are excluded to surface higher-signal Qt
findings, and ApplicationLibCode/UnitTests is skipped because gtest
headers are absent on this configure-only tree.
Add rhel8-package.yml that builds a RHEL8 install package from a tag
using the prebuilt RHEL8 CI container. It configures with an install
prefix, builds the install target, runs the CPack package target, and
uploads the resulting *.tar.gz as the ResInsight-RHEL8 artifact.
Wire the new workflow into release-draft.yml so the draft release waits
for the RHEL8 package run and attaches the *.tar.gz directly, alongside
the existing zipped platform artifacts.
The previous fix added VCToolsVersion to the Windows vcpkg cache key, but it is still too coarse. vcpkg keys each binary's ABI on a SHA-1 of the actual cl.exe binary content (ThirdParty/vcpkg/scripts/detect_compiler/CMakeLists.txt), not on the VCToolsVersion folder name. GitHub ships rebuilt cl.exe binaries under the same VCToolsVersion across runner image releases, so vcpkg's ABI hash changes while VCToolsVersion stays fixed. The restored binaries are then rejected and vcpkg rebuilds everything. Because the cache key did not change, the action skips saving the freshly built binaries, so the stale entry never refreshes and the rebuild loop persists across runs.
Observed on two dev runs with identical VCToolsVersion (14.44.35207), SDK and vcpkg SHA but different runner images (win22/20260616.203 vs win22/20260622.215): the first restored 102 packages from the binary cache, the second restored 0 and rebuilt all of them.
Hash cl.exe directly so the cache key tracks exactly what vcpkg tracks: a cl.exe change yields a new key, one cold rebuild, then a successful save under the new key, while image bumps that do not touch cl.exe keep restoring from cache.
The vcpkg binary cache was restored on every Windows run, but vcpkg rejected all binaries and rebuilt from source. vcpkg keys each binary by an ABI hash that includes the MSVC toolset version, which was not part of the cache key (only OS, compiler name, vcpkg submodule SHA and the vcpkg-configuration.json hash). When the runner image bumps MSVC, the restored binaries become ABI-incompatible and vcpkg rebuilds everything. Because the cache key stays unchanged, the action skips saving the freshly built binaries, so the stale entry can never refresh and the rebuild loop persists across runs.
Add the MSVC toolset version (VCToolsVersion, exported by the MSVC setup step) to the cache key on Windows. A toolset bump now yields a new key, producing one cold rebuild followed by a successful save under the new key, after which subsequent runs restore from cache.
The run-clang-tidy path regex matched generated moc/qrc files under build/
that are listed in compile_commands.json but not produced when the project is
only configured, not built. Exclude /build/ paths to remove the spurious
clang-diagnostic-error output.
On a tag push, wait for the Windows/Linux build (ResInsightWithCache.yml)
and the macOS build (ResInsightMac.yml) to finish, download their
application artifacts, zip them per platform, and create a draft GitHub
Release with the archives attached for maintainer review.
Replace the third-party celinekurpershoek/link-checker action with a
self-contained bash step that crawls the site sitemap and validates
page status, internal links, external links (with retry) and in-page
anchors against each target page's heading ids.
The script is inlined rather than referenced from a file because the
workflow also runs on gh-pages branch pushes, where the source tree is
not available.
Plain pip has no time-based cutoff, so route the workflow's package
installs through uv and set UV_EXCLUDE_NEWER to refuse releases
published within the last week as supply-chain hardening. Mirror the
policy in the rips pyproject for local uv installs.
* Refactor: add MACOSX_BUNDLE option to qt_add_executable in multiple CMakeLists.txt files
* #14045 macOS: Guard std::stacktrace usage and skip ucontext on Apple platforms
* #14045 macOS: Guard std::ispanstream with std::istringstream fallback
* #14045 macOS: Add vcpkg overlay triplets for osx and exclude grpc on osx
* #14045 macOS: CMake macOS build support and openzgy OpenMP-disable patch
* #14045 CI: Add macOS build workflow
* #14045 macOS: Use feature-test macros to detect <stacktrace> and <spanstream>
* #14045 macOS: Make MAX_STIMPLAN_LAYERS constexpr to fix arm64 link error
* #14045 CI: Ship README-macOS.txt with artifact to document Gatekeeper workaround
* #14045 CI: Pin macOS runner to macos-14 and set deployment target to 14.0
* #14045 CI: Move macOS runner to macos-15 and fix README step on configure failure
vcpkg detects the compiler hash before the CMake toolchain file loads,
so -DCMAKE_C_COMPILER=gcc-14 on the cmake line was too late -- vcpkg
picked up /usr/bin/c++ (gcc-13 on Ubuntu 24.04) and computed an ABI
hash that did not match the gcc-14 entries baked into the image's
/opt/vcpkg-cache-gcc, restoring 0 packages and rebuilding all 102
ports from source. Export CC/CXX in the step env to match the
Dockerfile's vcpkg-builder-gcc stage.
Switches the Copilot Coding Agent's pre-flight job to the prebuilt
ghcr.io/<repo>/ci-ubuntu24 image so the toolchain, Qt, vcpkg cache, and
warm ResInsight buildcache are already provisioned at the start of every
agent session. The setup only fetches source, installs the editable rips
package, and warms an incremental build.
The image's buildcache was baked at /src so source path matching matters
for hit rate. actions/checkout puts source at $GITHUB_WORKSPACE; this
adds a /src -> $GITHUB_WORKSPACE symlink and configures at /src so gcc
command lines reference /src/... and match the baked entries. CMake
records CMAKE_SOURCE_DIR as the string passed to -S without resolving
symlinks, so the indirection is transparent to the build and to Copilot
edits (which still land on the workspace files the symlink points at).
Drops the in-workflow apt/Qt/buildcache restore/vcpkg restore plumbing
that the image now obviates, including the temporary cache-layout
diagnostic block added while debugging the prior restore behavior.
Adds .github/docker/Dockerfile.ubuntu24 -- a multi-stage image bundling gcc-14, clang-19, Qt 6.7.0, the buildcache binary from the canonical GitLab repo, per-compiler vcpkg binary caches, and per-compiler warm ResInsight buildcaches. Published to ghcr.io/<repo>/ci-ubuntu24 by a new nightly build workflow that mirrors the RHEL8 pattern, with a matching daily cleanup workflow that applies the same GHCR retention rules.
Adds .github/workflows/ResInsightWithCacheLinuxContainer.yml -- a parallel companion to the existing Linux legs in ResInsightWithCache.yml, running both compilers in a matrix inside the container with /src as the working directory so buildcache hashes line up with the warmup baked into the image.
The existing ResInsightWithCache.yml Linux legs remain unchanged during the validation phase. copilot-setup-steps.yml will be migrated to the container in a follow-up once the image is proven.
Cache action reports a hit and extracts ~787 MB, but vcpkg then
restores 0 packages from the path it advertises. Same cache key
works on regular GitHub-hosted runners, so the suspicion is a
workspace path mismatch in the Copilot cloud agent's bind-mounted
environment. Add a temporary step to print pwd, GITHUB_WORKSPACE,
the action's output path, and locate any .vcpkg-cache on disk.