Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
179 changes: 179 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
name: Build & Package

# Build FindMUS against a pinned libminizinc release (see
# scripts/fetch_minizinc.sh for how that release is chosen) and publish it, so the
# MiniZinc IDE can bundle a build that matches the compiler it ships.
#
# Platforms match libminizinc's, so every published compiler has a matching build.

on:
push:
branches: [develop]
tags: ["*"]
pull_request: {}
workflow_dispatch:
inputs:
minizinc_release:
description: "libminizinc release to build against (blank = tag or edge)."
type: string
default: ""

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
GH_TOKEN: ${{ github.token }}
# Honoured by scripts/fetch_minizinc.sh; blank means "resolve from the ref".
MZN_RELEASE: ${{ github.event.inputs.minizinc_release }}

jobs:
build:
name: build (${{ matrix.platform }})
strategy:
fail-fast: false
matrix:
include:
- { platform: linux, triple: x86_64-linux-gnu, runner: ubuntu-24.04, container: "quay.io/pypa/manylinux_2_28_x86_64", setup: "", generator: "Unix Makefiles", cmakedir: "lib64/cmake" }
- { platform: linux-arm64, triple: aarch64-linux-gnu, runner: ubuntu-24.04-arm, container: "quay.io/pypa/manylinux_2_28_aarch64", setup: "", generator: "Unix Makefiles", cmakedir: "lib64/cmake" }
- { platform: musl, triple: x86_64-linux-musl, runner: ubuntu-24.04, container: "alpine:3.20", setup: "apk add --no-cache bash build-base cmake ninja git zlib-dev", generator: "Ninja", cmakedir: "lib/cmake" }
- { platform: musl-arm64, triple: aarch64-linux-musl, runner: ubuntu-24.04-arm, container: "alpine:3.20", setup: "apk add --no-cache bash build-base cmake ninja git zlib-dev", generator: "Ninja", cmakedir: "lib/cmake" }
- { platform: osx, triple: aarch64-apple-darwin, runner: macos-14, container: "", setup: "", generator: "Ninja", cmakedir: "lib/cmake" }
- { platform: osx-intel, triple: x86_64-apple-darwin, runner: macos-26-intel, container: "", setup: "", generator: "Ninja", cmakedir: "lib/cmake" }
- { platform: win64, triple: x86_64-windows, runner: windows-2022, container: "", setup: "", generator: "Ninja", cmakedir: "CMake" }
- { platform: win64-arm, triple: aarch64-windows, runner: windows-11-arm, container: "", setup: "", generator: "Ninja", cmakedir: "CMake" }
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v7

- name: Fetch libminizinc + Gecode
shell: bash
run: bash scripts/fetch_minizinc.sh ${{ matrix.triple }}

- uses: TheMrMilchmann/setup-msvc-dev@v4.1.0
if: startsWith(matrix.platform, 'win64')
with:
arch: ${{ matrix.platform == 'win64-arm' && 'arm64' || 'x64' }}

# Containers match the compiler's: manylinux_2_28 for the glibc 2.28 floor,
# alpine for musl. `setup` installs what the bare image lacks.
- name: Configure & build
shell: bash
env:
# MSVC reports __cplusplus as 199711L unless asked not to, so Gecode's
# bundled Boost cannot pick a rounding-control implementation on ARM64.
CXXFLAGS: ${{ matrix.platform == 'win64-arm' && '/Zc:__cplusplus' || '' }}
# Matches minizinc-vendor and libminizinc's own per-platform choice;
# ignored (and harmless) on every non-macOS platform.
CMAKE_OSX_ARCHITECTURES: ${{ matrix.platform == 'osx-intel' && 'x86_64' || 'arm64' }}
run: |
set -eux
SETUP='${{ matrix.setup }}'
if [ -n "${{ matrix.container }}" ]; then
docker run --rm -v "$PWD:/work" -w /work \
-e ROOT=/work \
-e CMAKE_GENERATOR="${{ matrix.generator }}" \
-e CMAKEDIR="${{ matrix.cmakedir }}" \
-e CMAKE_OSX_ARCHITECTURES="$CMAKE_OSX_ARCHITECTURES" \
"${{ matrix.container }}" \
sh -c "${SETUP}${SETUP:+ && }bash scripts/ci_build.sh"
else
ROOT="$PWD" \
CMAKE_GENERATOR="${{ matrix.generator }}" \
CMAKEDIR="${{ matrix.cmakedir }}" \
CMAKE_OSX_ARCHITECTURES="$CMAKE_OSX_ARCHITECTURES" \
bash scripts/ci_build.sh
fi

- name: Package
shell: bash
run: tar -czf "findMUS-${{ matrix.triple }}.tar.gz" -C findMUS .

- uses: actions/upload-artifact@v7
with:
name: findMUS-${{ matrix.platform }}
path: findMUS-${{ matrix.triple }}.tar.gz

publish:
name: publish release
needs: build
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/'))
runs-on: ubuntu-24.04
permissions:
contents: write
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
with:
path: artifacts
- name: Publish
shell: bash
run: |
set -eux
mkdir -p upload
cp artifacts/findMUS-*/findMUS-*.tar.gz upload/
if [ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]; then
TAG="${{ github.ref_name }}"
# Only create it if absent; anything else is a real error.
if ! gh release view "$TAG" >/dev/null 2>&1; then
gh release create "$TAG" --title "FindMUS $TAG" --verify-tag \
--notes "Built against the MiniZinc $TAG release."
fi
else
TAG=edge
# Rolling prerelease, updated in place: deleting and recreating it would
# notify every watcher on each develop build.
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -f -a -m "Development build of FindMUS" "$TAG" "$GITHUB_SHA"
git push -f origin "refs/tags/$TAG"
NOTES="Continuously updated build of the latest development version, made against the MiniZinc edge release."
if gh release view "$TAG" >/dev/null 2>&1; then
gh release edit "$TAG" --prerelease --title "FindMUS (edge)" --notes "$NOTES"
else
gh release create "$TAG" --prerelease --title "FindMUS (edge)" --notes "$NOTES"
fi
fi
gh release upload "$TAG" upload/* --clobber

# Next link in the develop chain: libminizinc -> mzn-analyse -> FindMUS ->
# MiniZincIDE. Fires only after this repo's own assets are published, so the
# next one never builds against a half-updated upstream.
# Runs on tags too: this is the last repository the CLI bundles depend on, so by
# the time it has published, every input they need exists at that tag.
notify-downstream:
name: trigger the IDE and the CLI bundles
needs: publish
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/'))
runs-on: ubuntu-24.04
steps:
- uses: actions/create-github-app-token@v3
id: app-token
with:
app-id: ${{ secrets.MINIZINC_BOT_APP_ID }}
private-key: ${{ secrets.MINIZINC_BOT_APP_KEY }}
owner: MiniZinc
repositories: MiniZincIDE, libminizinc
- name: Dispatch
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
# workflow_dispatch, not repository_dispatch: the latter always runs the
# default branch's workflow, so it could not rebuild develop.
#
# Not on tags: a tagged release is cut by hand, one repository at a
# time, so the IDE gets tagged when its turn comes.
if [ "$GITHUB_REF_TYPE" != tag ]; then
gh workflow run ci.yml --repo MiniZinc/MiniZincIDE --ref "$GITHUB_REF_NAME" \
-f minizinc_release=edge
fi

rel=edge
[ "$GITHUB_REF_TYPE" = tag ] && rel="$GITHUB_REF_NAME"
gh workflow run bundle.yml --repo MiniZinc/libminizinc --ref "$GITHUB_REF_NAME" \
-f release="$rel"
64 changes: 0 additions & 64 deletions .gitlab-ci.yml

This file was deleted.

4 changes: 3 additions & 1 deletion mapsolvers/minisat/minisat/utils/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#ifndef Minisat_System_h
#define Minisat_System_h

#if defined(__linux__)
// musl has no fpu_control.h. The only use of it (System.cc) is already guarded
// on the macros this header defines, so skipping it costs nothing there.
#if defined(__linux__) && __has_include(<fpu_control.h>)
#include <fpu_control.h>
#endif

Expand Down
22 changes: 22 additions & 0 deletions scripts/ci_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Configure, build and install findMUS into $ROOT/findMUS, against the
# libminizinc SDK and Gecode already in $ROOT (see fetch_minizinc.sh).
#
# Env: ROOT, CMAKE_GENERATOR, CMAKE_OSX_ARCHITECTURES, CMAKEDIR (where the SDK
# keeps its CMake packages: lib64/cmake on manylinux, lib/cmake on macOS,
# CMake on Windows)
set -eux

: "${ROOT:?ROOT must be set}"
: "${CMAKEDIR:?CMAKEDIR must be set}"

cmake -S "$ROOT" -B "$ROOT/build" -G "${CMAKE_GENERATOR:-Ninja}" \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_SYSTEM_LIBMINIZINC=1 \
-Dlibminizinc_DIR="$ROOT/minizinc/${CMAKEDIR}/libminizinc" \
-DGecode_ROOT="$ROOT/vendor/gecode" \
-DOsiCBC_ROOT="$ROOT/vendor/cbc" \
-DCMAKE_INSTALL_PREFIX="$ROOT/findMUS" \
-DCMAKE_OSX_ARCHITECTURES="${CMAKE_OSX_ARCHITECTURES:-arm64}" \
-DCMAKE_OSX_DEPLOYMENT_TARGET="12.0"
cmake --build "$ROOT/build" --config Release --target install
50 changes: 50 additions & 0 deletions scripts/fetch_minizinc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env bash
# Fetch what findMUS builds against: the libminizinc SDK and Gecode.
#
# Usage: fetch_minizinc.sh <triple>
#
# Release selection: a tagged build uses the libminizinc release with the same
# tag, anything else uses `edge` (republished on every libminizinc develop push).
# Override with MZN_RELEASE.
#
# `minizinc-compiler-only` is the full install tree, headers and CMake package
# included. Gecode and CBC come from that release's vendor.lock: libminizinc's
# exported package does find_dependency on both, so they have to be the versions
# it was built against.
#
# Requires: gh (via $GH_TOKEN), tar.
set -euxo pipefail

TRIPLE="${1:?usage: fetch_minizinc.sh <triple>}"
MZN_REPO="${MZN_REPO:-MiniZinc/libminizinc}"
VENDOR_REPO="${VENDOR_REPO:-MiniZinc/minizinc-vendor}"
here="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$here"

if [ -n "${MZN_RELEASE:-}" ]; then
ref="$MZN_RELEASE"
elif [ "${GITHUB_REF_TYPE:-}" = "tag" ]; then
ref="${GITHUB_REF_NAME}"
else
ref="edge"
fi

mkdir -p minizinc vendor
gh release download "$ref" --repo "$MZN_REPO" \
--pattern "minizinc-compiler-only-${TRIPLE}.tar.gz" --dir . --clobber
tar -xzf "minizinc-compiler-only-${TRIPLE}.tar.gz" -C minizinc
rm -f "minizinc-compiler-only-${TRIPLE}.tar.gz"

gh release download "$ref" --repo "$MZN_REPO" --pattern "vendor.lock" --dir . --clobber

deps=gecode
case "$TRIPLE" in aarch64-windows) ;; *) deps="$deps cbc" ;; esac

for dep in $deps; do
ver="$(grep -E "^${dep}=" vendor.lock | head -1 | cut -d= -f2-)"
[ -n "$ver" ] || { echo "no version pinned for '$dep' in vendor.lock" >&2; exit 1; }
asset="${dep}-${ver}-${TRIPLE}.tar.gz"
gh release download "${dep}-${ver}" --repo "$VENDOR_REPO" --pattern "$asset" --dir . --clobber
tar -xzf "$asset" -C vendor
rm -f "$asset"
done
Loading