diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 00000000000..624088f2a04 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,31 @@ +# release CI for FreeBSD +compute_engine_instance: + image_project: freebsd-org-cloud-dev + image: family/freebsd-13-2 + platform: freebsd + disk: 100 # Gb + +build_task: + timeout_in: 120m + only_if: $CIRRUS_TAG != '' + env: + ADD_CABAL_ARGS: "--enable-split-sections" + ARCH: 64 + ARTIFACT: "x86_64-portbld-freebsd" + CIRRUS_CLONE_SUBMODULES: true + DISTRO: na + GHC_VERSION: 9.2.8 + GITHUB_WORKSPACE: ${CIRRUS_WORKING_DIR} + RUNNER_OS: FreeBSD + TARBALL_EXT: tar.xz + TZ: Asia/Singapore + install_script: + - sed -i.bak -e 's/quarterly/latest/' /etc/pkg/FreeBSD.conf + - pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake llvm14 patchelf tree gmp libiconv + script: + - tzsetup Etc/GMT + - adjkerntz -a + - bash .github/scripts/build.sh + binaries_artifacts: + path: "out/*" + diff --git a/.github/scripts/brew.sh b/.github/scripts/brew.sh new file mode 100644 index 00000000000..e05ffb7421c --- /dev/null +++ b/.github/scripts/brew.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +set -eux + +# shellcheck disable=SC1091 +. .github/scripts/env.sh + +if [ -e "$HOME/.brew" ] ; then + ( + cd "$HOME/.brew" + git fetch --depth 1 + git reset --hard origin/master + ) +else + git clone --depth=1 https://github.com/Homebrew/brew "$HOME/.brew" +fi +export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH" + +mkdir -p "$CI_PROJECT_DIR/.brew_cache" +export HOMEBREW_CACHE="$CI_PROJECT_DIR/.brew_cache" +mkdir -p "$CI_PROJECT_DIR/.brew_logs" +export HOMEBREW_LOGS="$CI_PROJECT_DIR/.brew_logs" +mkdir -p /private/tmp/.brew_tmp +export HOMEBREW_TEMP=/private/tmp/.brew_tmp + +#brew update +brew install ${1+"$@"} + diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh new file mode 100644 index 00000000000..556e1af472c --- /dev/null +++ b/.github/scripts/build.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +set -eux + +# shellcheck disable=SC1091 +. .github/scripts/env.sh +# shellcheck disable=SC1091 +. .github/scripts/common.sh + +uname -a +uname -p +uname +pwd +env + +# ensure ghcup +install_ghcup + +# build +ghcup install ghc "${GHC_VERSION}" +ghcup set ghc "${GHC_VERSION}" +sed -i.bak -e '/DELETE MARKER FOR CI/,/END DELETE/d' cabal.project # see comment in cabal.project +ecabal update +ecabal user-config diff +ecabal user-config init -f +"ghc-${GHC_VERSION}" --info +"ghc" --info + +# https://github.com/haskell/cabal/issues/7313#issuecomment-811851884 +if [ "$(getconf LONG_BIT)" == "32" ] || [ "${DISTRO}" == "CentOS" ] ; then + echo 'constraints: lukko -ofd-locking' >> cabal.release.project.local +fi + +# shellcheck disable=SC2206 +args=( + -w "ghc-$GHC_VERSION" + --disable-profiling + --enable-executable-stripping + --project-file=cabal.release.project + ${ADD_CABAL_ARGS} +) + +run cabal v2-build "${args[@]}" cabal-install + +mkdir -p "$CI_PROJECT_DIR/out" +# shellcheck disable=SC2154 +cp "$(cabal list-bin "${args[@]}" cabal-install:exe:cabal)" "$CI_PROJECT_DIR/out/cabal$ext" +cp dist-newstyle/cache/plan.json "$CI_PROJECT_DIR/out/plan.json" +cd "$CI_PROJECT_DIR/out/" + +# create tarball/zip +TARBALL_PREFIX="cabal-install-$("$CI_PROJECT_DIR/out/cabal" --numeric-version)" +case "${TARBALL_EXT}" in + zip) + zip "${TARBALL_PREFIX}-${ARTIFACT}.${TARBALL_EXT}" "cabal${ext}" plan.json + ;; + tar.xz) + tar caf "${TARBALL_PREFIX}-${ARTIFACT}.${TARBALL_EXT}" "cabal${ext}" plan.json + ;; + *) + fail "Unknown TARBALL_EXT: ${TARBALL_EXT}" + ;; +esac + +rm cabal plan.json + diff --git a/.github/scripts/common.sh b/.github/scripts/common.sh new file mode 100644 index 00000000000..071b23af914 --- /dev/null +++ b/.github/scripts/common.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +# shellcheck disable=SC1091 +. .github/scripts/env.sh + +# Colors +RED="0;31" +LT_BROWN="1;33" +LT_BLUE="1;34" + +ecabal() { + cabal "$@" +} + +nonfatal() { + "$@" || "$* failed" +} + +sha_sum() { + if [ "${RUNNER_OS}" = "FreeBSD" ] ; then + sha256 "$@" + else + sha256sum "$@" + fi +} + +git_describe() { + git config --global --get-all safe.directory | grep '^\*$' || git config --global --add safe.directory "*" + git describe --always +} + +install_ghcup() { + # find "$GHCUP_INSTALL_BASE_PREFIX" + mkdir -p "$GHCUP_BIN" + mkdir -p "$GHCUP_BIN"/../cache + + if [ "${RUNNER_OS}" = "FreeBSD" ] ; then + curl -o ghcup https://downloads.haskell.org/~ghcup/x86_64-portbld-freebsd-ghcup + chmod +x ghcup + mv ghcup "$HOME/.local/bin/ghcup" + else + curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_MINIMAL=1 sh + source "$(dirname "${GHCUP_BIN}")/env" + ghcup install cabal --set "${BOOTSTRAP_HASKELL_CABAL_VERSION}" + fi +} + +strip_binary() { + ( + set -e + local binary=$1 + case "$(uname -s)" in + "Darwin"|"darwin") + ;; + MSYS_*|MINGW*) + ;; + *) + strip -s "${binary}" + ;; + esac + ) +} + +# GitLab Pipelines log section delimiters +# https://gitlab.com/gitlab-org/gitlab-foss/issues/14664 +start_section() { + name="$1" + echo -e "section_start:$(date +%s):$name\015\033[0K" +} + +end_section() { + name="$1" + echo -e "section_end:$(date +%s):$name\015\033[0K" +} + +echo_color() { + local color="$1" + local msg="$2" + echo -e "\033[${color}m${msg}\033[0m" +} + +error() { echo_color "${RED}" "$1"; } +warn() { echo_color "${LT_BROWN}" "$1"; } +info() { echo_color "${LT_BLUE}" "$1"; } + +fail() { error "error: $1"; exit 1; } + +run() { + info "Running $*..." + "$@" || ( error "$* failed"; return 1; ) +} + +emake() { + if command -v gmake >/dev/null 2>&1 ; then + gmake "$@" + else + make "$@" + fi +} + +mktempdir() { + case "$(uname -s)" in + "Darwin"|"darwin") + mktemp -d -t cabal_ci.XXXXXXX + ;; + *) + mktemp -d + ;; + esac +} diff --git a/.github/scripts/env.sh b/.github/scripts/env.sh new file mode 100644 index 00000000000..79acb00b474 --- /dev/null +++ b/.github/scripts/env.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +mkdir -p "$HOME"/.local/bin + +if [ "${RUNNER_OS}" = "Windows" ] ; then + ext=".exe" +else + # shellcheck disable=SC2034 + ext='' +fi + +export PATH="$HOME/.local/bin:$PATH" + +export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 +export BOOTSTRAP_HASKELL_CABAL_VERSION="${CABAL_VER:-3.12.1.0}" +export BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG=no +export BOOTSTRAP_HASKELL_INSTALL_NO_STACK=yes +export BOOTSTRAP_HASKELL_ADJUST_BASHRC=1 + +if [ "${RUNNER_OS}" = "freebsd" ] ; then + export RUNNER_OS=FreeBSD +fi + +if [ "${RUNNER_OS}" = "Windows" ] ; then + # on windows use pwd to get unix style path + CI_PROJECT_DIR="$(pwd)" + export CI_PROJECT_DIR + export GHCUP_INSTALL_BASE_PREFIX="/c" + export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin" + export PATH="$GHCUP_BIN:$PATH" + export CABAL_DIR="C:\\Users\\runneradmin\\AppData\\Roaming\\cabal" +else + export CI_PROJECT_DIR="${GITHUB_WORKSPACE}" + export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR" + export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin" + export PATH="$GHCUP_BIN:$PATH" + export CABAL_DIR="$CI_PROJECT_DIR/cabal" + export CABAL_CACHE="$CI_PROJECT_DIR/cabal-cache" +fi + +export DEBIAN_FRONTEND=noninteractive +export TZ=Asia/Singapore diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000000..7912335726a --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,423 @@ +name: Build and release + +on: + push: + tags: + - 'cabal-install-*' + +jobs: + build-linux: + name: Build linux binaries + runs-on: ubuntu-latest + env: + TARBALL_EXT: tar.xz + ARCH: 64 + DEBIAN_FRONTEND: noninteractive + TZ: Asia/Singapore + GHC_VERSION: 9.8.4 + strategy: + fail-fast: false + matrix: + platform: [ { image: "debian:10" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" + , DISTRO: "Debian" + , ARTIFACT: "x86_64-linux-deb10" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "debian:11" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" + , DISTRO: "Debian" + , ARTIFACT: "x86_64-linux-deb11" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "debian:12" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" + , DISTRO: "Debian" + , ARTIFACT: "x86_64-linux-deb12" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "ubuntu:20.04" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" + , DISTRO: "Ubuntu" + , ARTIFACT: "x86_64-linux-ubuntu20.04" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "ubuntu:22.04" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" + , DISTRO: "Ubuntu" + , ARTIFACT: "x86_64-linux-ubuntu22.04" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "ubuntu:24.04" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses6 libtinfo6 patchelf" + , DISTRO: "Ubuntu" + , ARTIFACT: "x86_64-linux-ubuntu24.04" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "linuxmintd/mint20.3-amd64" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" + , DISTRO: "Mint" + , ARTIFACT: "x86_64-linux-mint20" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "linuxmintd/mint21.3-amd64" + , installCmd: "apt-get update && apt-get install -y" + , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" + , DISTRO: "Mint" + , ARTIFACT: "x86_64-linux-mint21" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "fedora:33" + , installCmd: "dnf install -y" + , toolRequirements: "autoconf automake binutils bzip2 coreutils curl elfutils-devel elfutils-libs findutils gcc gcc-c++ git gmp gmp-devel jq lbzip2 make ncurses ncurses-compat-libs ncurses-devel openssh-clients patch perl pxz python3 sqlite sudo wget which xz zlib-devel patchelf" + , DISTRO: "Fedora" + , ARTIFACT: "x86_64-linux-fedora33" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "fedora:37" + , installCmd: "dnf install -y" + , toolRequirements: "autoconf automake binutils bzip2 coreutils curl elfutils-devel elfutils-libs findutils gcc gcc-c++ git gmp gmp-devel jq lbzip2 make ncurses ncurses-compat-libs ncurses-devel openssh-clients patch perl pxz python3 sqlite sudo wget which xz zlib-devel patchelf" + , DISTRO: "Fedora" + , ARTIFACT: "x86_64-linux-fedora37" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "rockylinux:8" + , installCmd: "yum -y install epel-release && yum install -y --allowerasing" + , toolRequirements: "autoconf automake binutils bzip2 coreutils curl elfutils-devel elfutils-libs findutils gcc gcc-c++ git gmp gmp-devel jq lbzip2 make ncurses ncurses-compat-libs ncurses-devel openssh-clients patch perl pxz python3 sqlite sudo wget which xz zlib-devel patchelf" + , DISTRO: "Unknown" + , ARTIFACT: "x86_64-linux-rocky8" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "rockylinux:9" + , installCmd: "yum -y install epel-release && yum install -y --allowerasing" + , toolRequirements: "autoconf automake binutils bzip2 coreutils curl elfutils-devel elfutils-libs findutils gcc gcc-c++ git gmp gmp-devel jq lbzip2 make ncurses ncurses-compat-libs ncurses-devel openssh-clients patch perl pxz python3 sqlite sudo wget which xz zlib-devel patchelf" + , DISTRO: "Unknown" + , ARTIFACT: "x86_64-linux-rocky9" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "alpine:latest" + , installCmd: "apk update && apk add" + , toolRequirements: "binutils-gold curl gcc g++ gmp-dev libc-dev libffi-dev make musl-dev ncurses-dev perl tar xz autoconf automake bzip2 coreutils elfutils-dev findutils git jq bzip2-dev patch python3 sqlite sudo wget which zlib-dev patchelf zlib zlib-dev zlib-static" + , DISTRO: "Unknown" + , ARTIFACT: "x86_64-linux-unknown" + , ADD_CABAL_ARGS: "--enable-split-sections --enable-executable-static" + }, + { image: "alpine:3.12" + , installCmd: "apk update && apk add" + , toolRequirements: "binutils-gold curl gcc g++ gmp-dev libc-dev libffi-dev make musl-dev ncurses-dev perl tar xz autoconf automake bzip2 coreutils elfutils-dev findutils git jq bzip2-dev patch python3 sqlite sudo wget which zlib-dev patchelf zlib zlib-dev zlib-static" + , DISTRO: "Unknown" + , ARTIFACT: "x86_64-linux-alpine312" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "alpine:3.19" + , installCmd: "apk update && apk add" + , toolRequirements: "binutils-gold curl gcc g++ gmp-dev libc-dev libffi-dev make musl-dev ncurses-dev perl tar xz autoconf automake bzip2 coreutils elfutils-dev findutils git jq bzip2-dev patch python3 sqlite sudo wget which zlib-dev patchelf zlib zlib-dev zlib-static" + , DISTRO: "Unknown" + , ARTIFACT: "x86_64-linux-alpine319" + , ADD_CABAL_ARGS: "--enable-split-sections" + }, + { image: "ghcr.io/void-linux/void-glibc:latest" + , installCmd: "xbps-install -Sy" + , toolRequirements: "ncurses-libtinfo-libs autoconf automake binutils bzip2 coreutils curl elfutils-devel elfutils findutils gcc gmp gmp-devel jq lbzip2 make ncurses ncurses-devel openssh patch perl python3 sqlite sudo wget which xz tar zlib-devel patchelf" + , DISTRO: "Unknown" + , ARTIFACT: "x86_64-linux-void-glibc" + , ADD_CABAL_ARGS: "--enable-split-sections" + } + ] + container: + image: ${{ matrix.platform.image }} + steps: + - name: Install requirements + shell: sh + run: | + ${{ matrix.platform.installCmd }} curl bash git ${{ matrix.platform.toolRequirements }} + + - uses: actions/checkout@v4 + + - name: Run build + run: | + bash .github/scripts/build.sh + + env: + ARTIFACT: ${{ matrix.platform.ARTIFACT }} + DISTRO: ${{ matrix.platform.DISTRO }} + ADD_CABAL_ARGS: ${{ matrix.platform.ADD_CABAL_ARGS }} + + - if: always() + name: Upload artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + retention-days: 2 + name: artifacts-${{ matrix.platform.ARTIFACT }} + path: | + ./out/* + + build-linux-32bit: + name: Build linux binaries (32bit) + runs-on: ubuntu-latest + env: + TARBALL_EXT: tar.xz + ARCH: 32 + TZ: Asia/Singapore + GHC_VERSION: 9.8.4 + DISTRO: "Unknown" + ARTIFACT: "i386-linux-unknown" + ADD_CABAL_ARGS: "--enable-split-sections --enable-executable-static" + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: 'true' + + - name: Run build (32 bit linux) + uses: docker://hasufell/i386-alpine-haskell:3.20 + with: + args: sh -c "apk update && apk add bash binutils-gold curl gcc g++ gmp-dev libc-dev libffi-dev make musl-dev ncurses-dev perl tar xz autoconf automake bzip2 coreutils elfutils-dev findutils git jq bzip2-dev patch python3 sqlite sudo wget which zlib-dev patchelf zlib zlib-dev zlib-static && bash .github/scripts/build.sh" + + - if: always() + name: Upload artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + retention-days: 2 + name: artifacts-32bit + path: | + ./out/* + + build-arm: + name: Build ARM binary + runs-on: ${{ matrix.os }} + env: + TARBALL_EXT: tar.xz + ADD_CABAL_ARGS: "" + DEBIAN_FRONTEND: noninteractive + TZ: Asia/Singapore + ARCH: ARM64 + DISTRO: Debian + strategy: + fail-fast: false + matrix: + include: + - os: [self-hosted, Linux, ARM64, maerwald] + ARCH: ARM + ARTIFACT: "armv7-linux-deb10" + GHC_VERSION: 9.2.8 + - os: [self-hosted, Linux, ARM64, maerwald] + ARCH: ARM64 + ARTIFACT: "aarch64-linux-deb10" + GHC_VERSION: 9.8.4 + steps: + - name: git config + run: | + git config --global --get-all safe.directory | grep '^\*$' || git config --global --add safe.directory "*" + shell: bash + + - name: Checkout code + uses: actions/checkout@v4 + + - if: matrix.ARCH == 'ARM' + uses: docker://hasufell/arm32v7-debian-haskell:10 + name: Run build (armv7 linux) + with: + args: bash .github/scripts/build.sh + env: + ARTIFACT: ${{ matrix.ARTIFACT }} + GHC_VERSION: ${{ matrix.GHC_VERSION }} + + - if: matrix.ARCH == 'ARM64' + uses: docker://hasufell/arm64v8-debian-haskell:10 + name: Run build (aarch64 linux) + with: + args: bash .github/scripts/build.sh + env: + ARTIFACT: ${{ matrix.ARTIFACT }} + GHC_VERSION: ${{ matrix.GHC_VERSION }} + + - if: always() + name: Upload artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + retention-days: 2 + name: artifacts-${{ matrix.ARTIFACT }} + path: | + ./out/* + + build-mac-x86_64: + name: Build binary (Mac x86_64) + runs-on: macOS-13 + env: + MACOSX_DEPLOYMENT_TARGET: 10.13 + ADD_CABAL_ARGS: "" + ARTIFACT: "x86_64-apple-darwin" + ARCH: 64 + TARBALL_EXT: tar.xz + DISTRO: na + GHC_VERSION: 9.8.4 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run build + run: | + brew install coreutils tree + bash .github/scripts/build.sh + + - if: always() + name: Upload artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + retention-days: 2 + name: artifacts-mac-x86_64 + path: | + ./out/* + + build-mac-aarch64: + name: Build binary (Mac aarch64) + runs-on: [self-hosted, macOS, ARM64] + env: + MACOSX_DEPLOYMENT_TARGET: 10.13 + ADD_CABAL_ARGS: "" + ARTIFACT: "aarch64-apple-darwin" + ARCH: ARM64 + TARBALL_EXT: tar.xz + DISTRO: na + HOMEBREW_CHANGE_ARCH_TO_ARM: 1 + GHC_VERSION: 9.8.4 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run build + run: | + bash .github/scripts/brew.sh git coreutils autoconf automake tree + export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH" + export LD=ld + bash .github/scripts/build.sh + + - if: always() + name: Upload artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + retention-days: 2 + name: artifacts-mac-aarch64 + path: | + ./out/* + + build-win: + name: Build binary (Win) + runs-on: windows-latest + env: + ADD_CABAL_ARGS: "" + ARTIFACT: "x86_64-mingw64" + ARCH: 64 + TARBALL_EXT: "zip" + DISTRO: na + GHC_VERSION: 9.8.4 + steps: + - name: install windows deps + shell: pwsh + run: | + C:\msys64\usr\bin\bash -lc "pacman --disable-download-timeout --noconfirm -Syuu" + C:\msys64\usr\bin\bash -lc "pacman --disable-download-timeout --noconfirm -Syuu" + C:\msys64\usr\bin\bash -lc "pacman --disable-download-timeout --noconfirm -S make mingw-w64-x86_64-clang curl autoconf mingw-w64-x86_64-pkgconf ca-certificates base-devel gettext autoconf make libtool automake python p7zip patch unzip zip git" + taskkill /F /FI "MODULES eq msys-2.0.dll" + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run build (windows) + run: | + $env:CHERE_INVOKING = 1 + $env:MSYS2_PATH_TYPE = "inherit" + $ErrorActionPreference = "Stop" + C:\msys64\usr\bin\bash -lc "bash .github/scripts/build.sh" + shell: pwsh + + - if: always() + name: Upload artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + retention-days: 2 + name: artifacts-win + path: | + ./out/* + + build-freebsd-x86_64: + name: Build FreeBSD x86_64 + runs-on: [self-hosted, FreeBSD, X64] + env: + ADD_CABAL_ARGS: "" + ARTIFACT: "x86_64-portbld-freebsd" + ARCH: 64 + TARBALL_EXT: tar.xz + DISTRO: na + GHC_VERSION: 9.8.4 + RUNNER_OS: FreeBSD + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run build + run: | + sudo sed -i.bak -e 's/quarterly/latest/' /etc/pkg/FreeBSD.conf + sudo pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake llvm14 libiconv + sudo tzsetup Etc/GMT + sudo adjkerntz -a + bash .github/scripts/build.sh + + - if: always() + name: Upload artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + retention-days: 2 + name: artifacts-freebsd + path: | + ./out/* + + release: + name: release + needs: ["build-linux", "build-linux-32bit", "build-arm", "build-mac-x86_64", "build-mac-aarch64", "build-win", "build-freebsd-x86_64"] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + merge-multiple: true + path: ./out + + - name: Install requirements + run: | + sudo apt-get update && sudo apt-get install -y tar xz-utils + shell: bash + + - name: build sdists + run: | + cabal sdist -o out all + shell: bash + + - name: Release + uses: softprops/action-gh-release@v1 + with: + draft: true + files: | + ./out/* + diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index c346838f93a..73b2d417dd7 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,10 +1,5 @@ name: Validate -# See: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#concurrency. -concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - # Note: This workflow file contains the required job "Validate post job". We are using path filtering # here to ignore PRs which only change documentation. This can cause a problem, see the workflow file # "validate.skip.yml" for a description of the problem and the solution provided in that file. @@ -24,9 +19,6 @@ on: release: types: - created - workflow_call: - - # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions workflow_dispatch: inputs: allow-newer: @@ -67,34 +59,7 @@ jobs: # If you remove something from here, then add it to the old-ghcs job. # Also a removed GHC from here means that we are actually dropping # support, so the PR *must* have a changelog entry. - ghc: - [ - "9.10.1", - "9.8.2", - "9.6.4", - "9.4.8", - "9.2.8", - "9.0.2", - "8.10.7", - "8.8.4", - ] - exclude: - # Throws fatal "cabal-tests.exe: fd:8: hGetLine: end of file" exception - # even with --io-manager=native - - sys: - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } - ghc: "9.0.2" - # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356 - - sys: - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } - ghc: "8.10.7" - # lot of segfaults caused by ghc bugs - - sys: - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } - ghc: "8.8.4" - defaults: - run: - shell: ${{ matrix.sys.shell }} + ghc: ["9.2.8"] steps: - name: Work around XDG directories existence (haskell-actions/setup#62) if: runner.os == 'macOS' @@ -231,65 +196,6 @@ jobs: if: matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS run: sh validate.sh $FLAGS -s solver-benchmarks-run - validate-old-ghcs: - name: Validate old ghcs ${{ matrix.extra-ghc }} - runs-on: ubuntu-22.04 - needs: validate - - strategy: - matrix: - extra-ghc: - ["8.4.4", "8.2.2", "8.0.2"] - ## GHC 7.10.3 does not install on ubuntu-22.04 with ghcup. - ## Older GHCs are not supported by ghcup in the first place. - fail-fast: false - - steps: - - uses: actions/checkout@v4 - - - name: Install prerequisites for old GHCs - run: | - sudo apt-get update - sudo apt-get install libncurses5 libtinfo5 - - - name: Install extra compiler - run: ghcup install ghc ${{ matrix.extra-ghc }} - - - name: GHCup logs - if: always() - run: cat /usr/local/.ghcup/logs/* - - - name: Install primary compiler - uses: haskell-actions/setup@v2 - id: setup-haskell - with: - ghc-version: ${{ env.GHC_FOR_RELEASE }} - cabal-version: latest - - - name: GHC versions - run: | - ghc --version - "ghc-${{ matrix.extra-ghc }}" --version - - # As we are reusing the cached build dir from the previous step - # the generated artifacts are available here, - # including the cabal executable and the test suite - - uses: actions/cache@v4 - with: - path: | - ${{ steps.setup-haskell.outputs.cabal-store }} - dist-* - key: ${{ runner.os }}-${{ env.GHC_FOR_RELEASE }}-${{ github.sha }} - restore-keys: ${{ runner.os }}-${{ env.GHC_FOR_RELEASE }}- - - - name: Validate build - run: sh validate.sh ${{ env.COMMON_FLAGS }} -s build - - - name: "Validate lib-suite-extras --extra-hc ghc-${{ matrix.extra-ghc }}" - env: - EXTRA_GHC: ghc-${{ matrix.extra-ghc }} - run: sh validate.sh ${{ env.COMMON_FLAGS }} --lib-only -s lib-suite-extras --extra-hc "${{ env.EXTRA_GHC }}" - build-alpine: name: Build statically linked using alpine runs-on: ubuntu-latest @@ -305,13 +211,6 @@ jobs: - uses: actions/checkout@v4 - # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions - - name: Manually supplied constraints/allow-newer - if: github.event_name == 'workflow_dispatch' - run: | - echo "allow-newer: ${ALLOWNEWER}" >> cabal.validate.project - echo "constraints: ${CONSTRAINTS}" >> cabal.validate.project - - uses: haskell-actions/setup@v2 id: setup-haskell with: @@ -400,57 +299,3 @@ jobs: - name: Build using cabal HEAD run: sh validate.sh ${{ env.COMMON_FLAGS }} --with-cabal ./cabal-head/cabal -s build - prerelease-head: - name: Create a GitHub prerelease with the binary artifacts - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/master' - - # IMPORTANT! Any job added to the workflow should be added here too - needs: [validate, validate-old-ghcs, build-alpine, dogfooding] - - steps: - - uses: actions/download-artifact@v4 - with: - name: cabal-Windows-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-Linux-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-Linux-static-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-macOS-x86_64 - - - name: Create GitHub prerelease - uses: marvinpinto/action-automatic-releases@v1.2.1 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - automatic_release_tag: cabal-head - prerelease: true - title: cabal-head - files: | - cabal-head-Windows-x86_64.tar.gz - cabal-head-Linux-x86_64.tar.gz - cabal-head-Linux-static-x86_64.tar.gz - cabal-head-macOS-x86_64.tar.gz - - # We use this job as a summary of the workflow - # It will fail if any of the previous jobs does - # This way we can use it exclusively in branch protection rules - # and abstract away the concrete jobs of the workflow, including their names - validate-post-job: - if: always() - name: Validate post job - runs-on: ubuntu-latest - # IMPORTANT! Any job added to the workflow should be added here too - needs: [validate, validate-old-ghcs, build-alpine, dogfooding] - - steps: - - run: | - echo "jobs info: ${{ toJSON(needs) }}" - - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') - run: exit 1 diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index dbdba88bbc1..a7cbac19849 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -106,7 +106,7 @@ library , containers >=0.5.6.2 && <0.8 , edit-distance ^>= 0.2.2 , directory >= 1.3.7.0 && < 1.4 - , filepath ^>=1.4.0.0 || ^>=1.5.0.0 + , filepath >= 1.3.0.1 && < 1.6 , mtl >=2.0 && <2.4 , network-uri >= 2.6.0.2 && < 2.7 , pretty ^>=1.1 diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index 731cd374821..110788e74e9 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -69,7 +69,7 @@ library , cryptohash-sha256 ^>= 0.11.101.0 , directory ^>= 1.2.0.1 || ^>= 1.3.0.0 , exceptions ^>= 0.10.0 - , filepath ^>= 1.3.0.1 || ^>= 1.4.0.0 || ^>= 1.5.0.0 + , filepath >= 1.3.0.1 && < 1.6 , network-wait ^>= 0.1.2.0 || ^>= 0.2.0.0 , optparse-applicative ^>= 0.14.3.0 || ^>=0.15.1.0 || ^>=0.16.0.0 || ^>= 0.17.0.0 || ^>= 0.18.1.0 , process ^>= 1.2.1.0 || ^>= 1.4.2.0 || ^>= 1.6.1.0 diff --git a/cabal.release.project b/cabal.release.project index 676e9f68587..f3dcf54e63b 100644 --- a/cabal.release.project +++ b/cabal.release.project @@ -2,4 +2,21 @@ import: project-cabal/pkgs/cabal.config import: project-cabal/pkgs/install.config import: project-cabal/pkgs/tests.config -index-state: hackage.haskell.org 2024-09-05T17:19:45Z +constraints: + hashable -arch-native, + tar >= 0.6.2.0, + bzlib-conduit >= 0.3.0.3, + bz2 >= 1.0.1.1, + bzlib >= 0.5.2.0, + directory >= 1.3.8.3, + filepath == 1.4.101.0 || == 1.4.300.1 || >= 1.5.2.0 + +-- https://github.com/haskell/ghcup-hs/issues/1107 +-- https://github.com/haskell/unix/pull/318 +if arch(arm) || arch(i386) + constraints: unix >= 2.8.6.0 + +package zlib + flags: -pkg-config +bundled-c-zlib + +index-state: hackage.haskell.org 2024-12-21T16:10:10Z diff --git a/cabal.validate.project b/cabal.validate.project index 52c78411107..c77a43a65b6 100644 --- a/cabal.validate.project +++ b/cabal.validate.project @@ -7,3 +7,16 @@ tests: True write-ghc-environment-files: never program-options ghc-options: -Werror + +constraints: + hashable -arch-native, + tar >= 0.6.2.0, + bzlib-conduit >= 0.3.0.3, + bz2 >= 1.0.1.1, + bzlib >= 0.5.2.0, + directory >= 1.3.8.3, + filepath == 1.4.101.0 || == 1.4.300.1 || >= 1.5.2.0 + +package zlib + flags: -pkg-config +bundled-c-zlib + diff --git a/scripts/release/create-yaml-snippet.sh b/scripts/release/create-yaml-snippet.sh new file mode 100755 index 00000000000..f1bc37466b4 --- /dev/null +++ b/scripts/release/create-yaml-snippet.sh @@ -0,0 +1,115 @@ +#!/bin/bash + +set -eu +set -o pipefail + +RELEASE=$1 +VERSION=${RELEASE#cabal-install-v} + +cd "gh-release-artifacts/cabal-${VERSION}" +BASE_URL=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal/$VERSION + +cat < /dev/stdout + $VERSION: + viTags: + - Latest + viChangeLog: https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-$VERSION.md + viArch: + A_64: + Linux_Debian: + '(>= 10 && < 11)': &cabal-${VERSION//./}-64-deb10 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-deb10.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-deb10.tar.xz" | awk '{ print $1 }') + '(>= 11 && < 12)': &cabal-${VERSION//./}-64-deb11 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-deb11.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-deb11.tar.xz" | awk '{ print $1 }') + '(>= 12 && < 13)': &cabal-${VERSION//./}-64-deb12 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-deb12.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-deb12.tar.xz" | awk '{ print $1 }') + unknown_versioning: *cabal-${VERSION//./}-64-deb12 + Linux_Ubuntu: + '( >= 20 && < 22 )': &cabal-${VERSION//./}-64-ubuntu20 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-ubuntu20.04.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-ubuntu20.04.tar.xz" | awk '{ print $1 }') + '( >= 22 && < 24 )': &cabal-${VERSION//./}-64-ubuntu22 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-ubuntu22.04.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-ubuntu22.04.tar.xz" | awk '{ print $1 }') + '( >= 24 && < 25 )': &cabal-${VERSION//./}-64-ubuntu24 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-ubuntu24.04.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-ubuntu24.04.tar.xz" | awk '{ print $1 }') + unknown_versioning: *cabal-${VERSION//./}-64-ubuntu24 + Linux_Mint: + '(>= 20 && < 21)': &cabal-${VERSION//./}-64-mint20 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-mint20.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-mint20.tar.xz" | awk '{ print $1 }') + '>= 21': &cabal-${VERSION//./}-64-mint21 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-mint21.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-mint21.tar.xz" | awk '{ print $1 }') + unknown_versioning: *cabal-${VERSION//./}-64-mint21 + Linux_Fedora: + '(>= 33 && < 37)': &cabal-${VERSION//./}-64-fedora33 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-fedora33.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-fedora33.tar.xz" | awk '{ print $1 }') + '>= 37': &cabal-${VERSION//./}-64-fedora37 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-fedora37.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-fedora37.tar.xz" | awk '{ print $1 }') + unknown_versioning: *cabal-${VERSION//./}-64-fedora37 + Linux_Rocky: + '( >= 8 && < 9 )': &cabal-${VERSION//./}-64-rocky8 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-rocky8.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-rocky8.tar.xz" | awk '{ print $1 }') + '( >= 9 )': &cabal-${VERSION//./}-64-rocky9 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-rocky9.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-rocky9.tar.xz" | awk '{ print $1 }') + unknown_versioning: *cabal-${VERSION//./}-64-rocky9 + Linux_RedHat: + unknown_versioning: *cabal-${VERSION//./}-64-rocky8 + Linux_UnknownLinux: + unknown_versioning: &cabal-${VERSION//./}-64-unknown + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-unknown.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-unknown.tar.xz" | awk '{ print $1 }') + Linux_Alpine: + '( >= 3.12 && < 3.19 )': &cabal-${VERSION//./}-64-alpine312 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-alpine312.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-alpine312.tar.xz" | awk '{ print $1 }') + '( >= 3.19 )': &cabal-${VERSION//./}-64-alpine319 + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-linux-alpine319.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-linux-alpine319.tar.xz" | awk '{ print $1 }') + unknown_versioning: *cabal-${VERSION//./}-64-alpine319 + Linux_Void: + unknown_versioning: *cabal-${VERSION//./}-64-unknown + Darwin: + unknown_versioning: + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-apple-darwin.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-apple-darwin.tar.xz" | awk '{ print $1 }') + Windows: + unknown_versioning: + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-mingw64.zip + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-mingw64.zip" | awk '{ print $1 }') + FreeBSD: + unknown_versioning: + dlUri: ${BASE_URL}/cabal-install-$VERSION-x86_64-portbld-freebsd.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-x86_64-portbld-freebsd.tar.xz" | awk '{ print $1 }') + A_32: + Linux_UnknownLinux: + unknown_versioning: &cabal-${VERSION//./}-32-unknown + dlUri: ${BASE_URL}/cabal-install-$VERSION-i386-linux-unknown.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-i386-linux-unknown.tar.xz" | awk '{ print $1 }') + Linux_Alpine: + unknown_versioning: *cabal-${VERSION//./}-32-unknown + A_ARM64: + Linux_UnknownLinux: + unknown_versioning: + dlUri: ${BASE_URL}/cabal-install-$VERSION-aarch64-linux-deb10.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-aarch64-linux-deb10.tar.xz" | awk '{ print $1 }') + Darwin: + unknown_versioning: + dlUri: ${BASE_URL}/cabal-install-$VERSION-aarch64-apple-darwin.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-aarch64-apple-darwin.tar.xz" | awk '{ print $1 }') + A_ARM: + Linux_UnknownLinux: + unknown_versioning: + dlUri: ${BASE_URL}/cabal-install-$VERSION-armv7-linux-deb10.tar.xz + dlHash: $(sha256sum "cabal-install-$VERSION-armv7-linux-deb10.tar.xz" | awk '{ print $1 }') +EOF + diff --git a/scripts/release/download-gh-artifacts.sh b/scripts/release/download-gh-artifacts.sh new file mode 100755 index 00000000000..38c57169187 --- /dev/null +++ b/scripts/release/download-gh-artifacts.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -eu +set -o pipefail + +RELEASE=$1 +VERSION=${RELEASE#cabal-install-v} +SIGNER=$2 + +echo "RELEASE: $RELEASE" +echo "SIGNER: $SIGNER" + +for com in gh gpg curl sha256sum ; do + command -V ${com} >/dev/null 2>&1 +done + +[ ! -e "gh-release-artifacts/cabal-${VERSION}" ] + +mkdir -p "gh-release-artifacts/cabal-${VERSION}" + +git archive --format=tar.gz -o "gh-release-artifacts/cabal-${VERSION}/cabal-${VERSION}-src.tar.gz" --prefix="cabal-${VERSION}/" HEAD + +cd "gh-release-artifacts/cabal-${VERSION}" + +# github +gh release download "$RELEASE" + +sha256sum ./* > SHA256SUMS +gpg --detach-sign -u "${SIGNER}" SHA256SUMS + +gh release upload "$RELEASE" "cabal-${VERSION}-src.tar.gz" SHA256SUMS SHA256SUMS.sig +